diff --git a/.eslintignore b/.eslintignore
index d525538fd8..1122886a22 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -37,6 +37,10 @@ packages/core/src/lib/markdown-it/plugins/*
# --- packages/core end ---
+# --- packages/cli ---
+packages/cli/dist/**/*.js
+# --- packages/cli end ---
+
!.eslintrc.js
# --- packages/vue-components ---
@@ -48,4 +52,4 @@ packages/vue-components/src/utils/utils.js
# --- packages/vue-components end ---
-dangerfile.js
\ No newline at end of file
+dangerfile.js
diff --git a/.gitignore b/.gitignore
index 354522f152..8d1f6fa8cc 100644
--- a/.gitignore
+++ b/.gitignore
@@ -107,6 +107,12 @@ packages/core/index.js
packages/core/src/lib/progress/*.js
# --- packages/core end ---
+# Manual type definitions need to be included
+!packages/cli/src/lib/live-server/index.d.ts
+
# Nx for Lerna
.nx/cache
-.nx/workspace-data
\ No newline at end of file
+.nx/workspace-data
+
+# Build folder
+dist/
diff --git a/docs/devGuide/development/settingUp.md b/docs/devGuide/development/settingUp.md
index 9f3dbd08bf..f01ae3074e 100644
--- a/docs/devGuide/development/settingUp.md
+++ b/docs/devGuide/development/settingUp.md
@@ -41,12 +41,12 @@ We recommend the **WebStorm IDE** or **VS Code** for working with MarkBind code.
1. **Fork and clone** the MarkBind repo.
-1. **Bind your cloned version of MarkBind to your console** by navigating to the cloned `packages/cli` folder and running `npm link`
-
1. **Install dependencies** by running
- `npm run setup`
+ `npm run setup`
in the **root folder** of your cloned repo.
+1. **Bind your cloned version of MarkBind to your console** by navigating to the cloned `packages/cli` folder and running `npm link`
+
1. **Congratulations!** Now you are ready to start modifying MarkBind code.
diff --git a/docs/devGuide/development/workflow.md b/docs/devGuide/development/workflow.md
index c1bdc895a1..121cc783f2 100644
--- a/docs/devGuide/development/workflow.md
+++ b/docs/devGuide/development/workflow.md
@@ -39,6 +39,7 @@ The sections below has more information about various stages of submitting a PR.
**1. Using the docs as a development environment**, with:
* the lazy reload`-o`lazy reload`-o` option to speed up page building
* the `-d` developer option. (see [below](#editing-frontend-features))
+ * the project-bundled `tsx` as a [TypeScript runner](https://nodejs.org/en/learn/typescript/run)
{.mb-3}
diff --git a/docs/images/debugger/WebStorm_1.png b/docs/images/debugger/WebStorm_1.png
index e08aadaef3..c8f7526900 100644
Binary files a/docs/images/debugger/WebStorm_1.png and b/docs/images/debugger/WebStorm_1.png differ
diff --git a/package-lock.json b/package-lock.json
index 9f5433e4cb..a5c2eca0de 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,6 +24,7 @@
"stylelint": "^16.2.1",
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^36.0.0",
+ "tsx": "^4.21.0",
"typescript": "^5.3.3",
"walk-sync": "^2.0.2"
}
@@ -2103,6 +2104,448 @@
"tslib": "^2.4.0"
}
},
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
+ "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
+ "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
+ "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
+ "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
+ "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
+ "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
+ "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
+ "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
+ "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
+ "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
+ "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
+ "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
+ "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
+ "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
+ "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
+ "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
+ "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
+ "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
+ "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
+ "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
+ "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
+ "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
"node_modules/@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -7221,12 +7664,16 @@
}
},
"node_modules/binaryextensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz",
- "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==",
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-6.11.0.tgz",
+ "integrity": "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==",
"dev": true,
+ "license": "Artistic-2.0",
+ "dependencies": {
+ "editions": "^6.21.0"
+ },
"engines": {
- "node": ">=0.8"
+ "node": ">=4"
},
"funding": {
"url": "https://bevry.me/fund"
@@ -10177,10 +10624,11 @@
}
},
"node_modules/diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz",
+ "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==",
"dev": true,
+ "license": "BSD-3-Clause",
"engines": {
"node": ">=0.3.1"
}
@@ -10326,6 +10774,23 @@
"safe-buffer": "^5.0.1"
}
},
+ "node_modules/editions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/editions/-/editions-6.22.0.tgz",
+ "integrity": "sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==",
+ "dev": true,
+ "license": "Artistic-2.0",
+ "dependencies": {
+ "version-range": "^4.15.0"
+ },
+ "engines": {
+ "ecmascript": ">= es5",
+ "node": ">=4"
+ },
+ "funding": {
+ "url": "https://bevry.me/fund"
+ }
+ },
"node_modules/editorconfig": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
@@ -10424,6 +10889,17 @@
"node": ">= 0.8"
}
},
+ "node_modules/encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
"node_modules/end-of-stream": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
@@ -10649,6 +11125,48 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/esbuild": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.3",
+ "@esbuild/android-arm": "0.27.3",
+ "@esbuild/android-arm64": "0.27.3",
+ "@esbuild/android-x64": "0.27.3",
+ "@esbuild/darwin-arm64": "0.27.3",
+ "@esbuild/darwin-x64": "0.27.3",
+ "@esbuild/freebsd-arm64": "0.27.3",
+ "@esbuild/freebsd-x64": "0.27.3",
+ "@esbuild/linux-arm": "0.27.3",
+ "@esbuild/linux-arm64": "0.27.3",
+ "@esbuild/linux-ia32": "0.27.3",
+ "@esbuild/linux-loong64": "0.27.3",
+ "@esbuild/linux-mips64el": "0.27.3",
+ "@esbuild/linux-ppc64": "0.27.3",
+ "@esbuild/linux-riscv64": "0.27.3",
+ "@esbuild/linux-s390x": "0.27.3",
+ "@esbuild/linux-x64": "0.27.3",
+ "@esbuild/netbsd-arm64": "0.27.3",
+ "@esbuild/netbsd-x64": "0.27.3",
+ "@esbuild/openbsd-arm64": "0.27.3",
+ "@esbuild/openbsd-x64": "0.27.3",
+ "@esbuild/openharmony-arm64": "0.27.3",
+ "@esbuild/sunos-x64": "0.27.3",
+ "@esbuild/win32-arm64": "0.27.3",
+ "@esbuild/win32-ia32": "0.27.3",
+ "@esbuild/win32-x64": "0.27.3"
+ }
+ },
"node_modules/escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -11558,11 +12076,27 @@
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
},
"node_modules/figlet": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.2.tgz",
- "integrity": "sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ==",
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.10.0.tgz",
+ "integrity": "sha512-aktIwEZZ6Gp9AWdMXW4YCi0J2Ahuxo67fNJRUIWD81w8pQ0t9TS8FFpbl27ChlTLF06VkwjDesZSzEVzN75rzA==",
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^14.0.0"
+ },
+ "bin": {
+ "figlet": "bin/index.js"
+ },
"engines": {
- "node": ">= 0.4.0"
+ "node": ">= 17.0.0"
+ }
+ },
+ "node_modules/figlet/node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
}
},
"node_modules/figures": {
@@ -11975,10 +12509,11 @@
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"node_modules/fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"hasInstallScript": true,
+ "license": "MIT",
"optional": true,
"os": [
"darwin"
@@ -12235,6 +12770,19 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/get-tsconfig": {
+ "version": "4.13.5",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.5.tgz",
+ "integrity": "sha512-v4/4xAEpBRp6SvCkWhnGCaLkJf9IwWzrsygJPxD/+p2/xPE3C5m2fA9FD0Ry9tG+Rqqq3gBzHSl6y1/T9V/tMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
"node_modules/get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -13811,16 +14359,18 @@
}
},
"node_modules/istextorbinary": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-3.3.0.tgz",
- "integrity": "sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ==",
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-9.5.0.tgz",
+ "integrity": "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==",
"dev": true,
+ "license": "Artistic-2.0",
"dependencies": {
- "binaryextensions": "^2.2.0",
- "textextensions": "^3.2.0"
+ "binaryextensions": "^6.11.0",
+ "editions": "^6.21.0",
+ "textextensions": "^6.11.0"
},
"engines": {
- "node": ">=8"
+ "node": ">=4"
},
"funding": {
"url": "https://bevry.me/fund"
@@ -19658,6 +20208,16 @@
"node": ">=4"
}
},
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
"node_modules/resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -21799,12 +22359,16 @@
"dev": true
},
"node_modules/textextensions": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-3.3.0.tgz",
- "integrity": "sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw==",
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-6.11.0.tgz",
+ "integrity": "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==",
"dev": true,
+ "license": "Artistic-2.0",
+ "dependencies": {
+ "editions": "^6.21.0"
+ },
"engines": {
- "node": ">=8"
+ "node": ">=4"
},
"funding": {
"url": "https://bevry.me/fund"
@@ -22217,6 +22781,26 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
"dev": true
},
+ "node_modules/tsx": {
+ "version": "4.21.0",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
+ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.27.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
"node_modules/tuf-js": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz",
@@ -22620,6 +23204,19 @@
"node": ">= 0.8"
}
},
+ "node_modules/version-range": {
+ "version": "4.15.0",
+ "resolved": "https://registry.npmjs.org/version-range/-/version-range-4.15.0.tgz",
+ "integrity": "sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==",
+ "dev": true,
+ "license": "Artistic-2.0",
+ "engines": {
+ "node": ">=4"
+ },
+ "funding": {
+ "url": "https://bevry.me/fund"
+ }
+ },
"node_modules/vue": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.3.11.tgz",
@@ -23643,7 +24240,7 @@
"chokidar": "^3.3.0",
"colors": "1.4.0",
"commander": "^8.1.0",
- "figlet": "^1.2.4",
+ "figlet": "^1.9.4",
"find-up": "^4.1.0",
"fs-extra": "^9.0.1",
"live-server": "1.2.1",
@@ -23653,13 +24250,14 @@
"winston-daily-rotate-file": "^3.10.0"
},
"bin": {
- "markbind": "index.js"
+ "markbind": "dist/index.js"
},
"devDependencies": {
+ "@types/lodash": "^4.14.181",
"@types/url-parse": "^1.4.8",
- "diff": "^4.0.1",
+ "diff": "^8.0.3",
"ignore": "^5.1.4",
- "istextorbinary": "^3.3.0",
+ "istextorbinary": "^9.5.0",
"jest": "^29.7.0",
"memfs": "^4.56.2",
"walk-sync": "^2.0.2"
@@ -29635,6 +30233,188 @@
"tslib": "^2.4.0"
}
},
+ "@esbuild/aix-ppc64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz",
+ "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/android-arm": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz",
+ "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/android-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz",
+ "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/android-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz",
+ "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/darwin-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz",
+ "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/darwin-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz",
+ "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/freebsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/freebsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz",
+ "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-arm": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz",
+ "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz",
+ "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-ia32": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz",
+ "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-loong64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz",
+ "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-mips64el": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz",
+ "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-ppc64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz",
+ "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-riscv64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz",
+ "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-s390x": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz",
+ "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/linux-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz",
+ "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/netbsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/netbsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz",
+ "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/openbsd-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz",
+ "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/openbsd-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz",
+ "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/openharmony-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz",
+ "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/sunos-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz",
+ "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/win32-arm64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz",
+ "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/win32-ia32": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz",
+ "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==",
+ "dev": true,
+ "optional": true
+ },
+ "@esbuild/win32-x64": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz",
+ "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==",
+ "dev": true,
+ "optional": true
+ },
"@eslint-community/eslint-utils": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
@@ -35385,10 +36165,13 @@
"integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA=="
},
"binaryextensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.3.0.tgz",
- "integrity": "sha512-nAihlQsYGyc5Bwq6+EsubvANYGExeJKHDO3RjnvwU042fawQTQfM3Kxn7IHUXQOz4bzfwsGYYHGSvXyW4zOGLg==",
- "dev": true
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-6.11.0.tgz",
+ "integrity": "sha512-sXnYK/Ij80TO3lcqZVV2YgfKN5QjUWIRk/XSm2J/4bd/lPko3lvk0O4ZppH6m+6hB2/GTu+ptNwVFe1xh+QLQw==",
+ "dev": true,
+ "requires": {
+ "editions": "^6.21.0"
+ }
},
"bindings": {
"version": "1.5.0",
@@ -37514,9 +38297,9 @@
"dev": true
},
"diff": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
- "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.3.tgz",
+ "integrity": "sha512-qejHi7bcSD4hQAZE0tNAawRK1ZtafHDmMTMkrrIGgSLl7hTnQHmKCeB45xAcbfTqK2zowkM3j3bHt/4b/ARbYQ==",
"dev": true
},
"diff-sequences": {
@@ -37628,6 +38411,15 @@
"safe-buffer": "^5.0.1"
}
},
+ "editions": {
+ "version": "6.22.0",
+ "resolved": "https://registry.npmjs.org/editions/-/editions-6.22.0.tgz",
+ "integrity": "sha512-UgGlf8IW75je7HZjNDpJdCv4cGJWIi6yumFdZ0R7A8/CIhQiWUjyGLCxdHpd8bmyD1gnkfUNK0oeOXqUS2cpfQ==",
+ "dev": true,
+ "requires": {
+ "version-range": "^4.15.0"
+ }
+ },
"editorconfig": {
"version": "0.15.3",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.3.tgz",
@@ -37707,6 +38499,16 @@
"resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
"integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w=="
},
+ "encoding": {
+ "version": "0.1.13",
+ "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
+ "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "iconv-lite": "^0.6.2"
+ }
+ },
"end-of-stream": {
"version": "1.4.5",
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz",
@@ -37882,6 +38684,40 @@
"is-symbol": "^1.0.2"
}
},
+ "esbuild": {
+ "version": "0.27.3",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz",
+ "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==",
+ "dev": true,
+ "requires": {
+ "@esbuild/aix-ppc64": "0.27.3",
+ "@esbuild/android-arm": "0.27.3",
+ "@esbuild/android-arm64": "0.27.3",
+ "@esbuild/android-x64": "0.27.3",
+ "@esbuild/darwin-arm64": "0.27.3",
+ "@esbuild/darwin-x64": "0.27.3",
+ "@esbuild/freebsd-arm64": "0.27.3",
+ "@esbuild/freebsd-x64": "0.27.3",
+ "@esbuild/linux-arm": "0.27.3",
+ "@esbuild/linux-arm64": "0.27.3",
+ "@esbuild/linux-ia32": "0.27.3",
+ "@esbuild/linux-loong64": "0.27.3",
+ "@esbuild/linux-mips64el": "0.27.3",
+ "@esbuild/linux-ppc64": "0.27.3",
+ "@esbuild/linux-riscv64": "0.27.3",
+ "@esbuild/linux-s390x": "0.27.3",
+ "@esbuild/linux-x64": "0.27.3",
+ "@esbuild/netbsd-arm64": "0.27.3",
+ "@esbuild/netbsd-x64": "0.27.3",
+ "@esbuild/openbsd-arm64": "0.27.3",
+ "@esbuild/openbsd-x64": "0.27.3",
+ "@esbuild/openharmony-arm64": "0.27.3",
+ "@esbuild/sunos-x64": "0.27.3",
+ "@esbuild/win32-arm64": "0.27.3",
+ "@esbuild/win32-ia32": "0.27.3",
+ "@esbuild/win32-x64": "0.27.3"
+ }
+ },
"escalade": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
@@ -38580,9 +39416,19 @@
"integrity": "sha512-lUGBnIamTAwk4znq5BcqsDaxSmZ9nDVJaij6NvRt/Tg4R69gERA+otPKbS86ROw9nxVMw2/mp1fnaiWqbs6Sdg=="
},
"figlet": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.5.2.tgz",
- "integrity": "sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ=="
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/figlet/-/figlet-1.10.0.tgz",
+ "integrity": "sha512-aktIwEZZ6Gp9AWdMXW4YCi0J2Ahuxo67fNJRUIWD81w8pQ0t9TS8FFpbl27ChlTLF06VkwjDesZSzEVzN75rzA==",
+ "requires": {
+ "commander": "^14.0.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="
+ }
+ }
},
"figures": {
"version": "3.2.0",
@@ -38889,9 +39735,9 @@
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
},
"fsevents": {
- "version": "2.3.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
- "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
"optional": true
},
"function-bind": {
@@ -39070,6 +39916,15 @@
"get-intrinsic": "^1.1.1"
}
},
+ "get-tsconfig": {
+ "version": "4.13.5",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.5.tgz",
+ "integrity": "sha512-v4/4xAEpBRp6SvCkWhnGCaLkJf9IwWzrsygJPxD/+p2/xPE3C5m2fA9FD0Ry9tG+Rqqq3gBzHSl6y1/T9V/tMQ==",
+ "dev": true,
+ "requires": {
+ "resolve-pkg-maps": "^1.0.0"
+ }
+ },
"get-value": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -40184,13 +41039,14 @@
}
},
"istextorbinary": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-3.3.0.tgz",
- "integrity": "sha512-Tvq1W6NAcZeJ8op+Hq7tdZ434rqnMx4CCZ7H0ff83uEloDvVbqAwaMTZcafKGJT0VHkYzuXUiCY4hlXQg6WfoQ==",
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-9.5.0.tgz",
+ "integrity": "sha512-5mbUj3SiZXCuRf9fT3ibzbSSEWiy63gFfksmGfdOzujPjW3k+z8WvIBxcJHBoQNlaZaiyB25deviif2+osLmLw==",
"dev": true,
"requires": {
- "binaryextensions": "^2.2.0",
- "textextensions": "^3.2.0"
+ "binaryextensions": "^6.11.0",
+ "editions": "^6.21.0",
+ "textextensions": "^6.11.0"
}
},
"jackspeak": {
@@ -41523,18 +42379,19 @@
"requires": {
"@markbind/core": "6.2.0",
"@markbind/core-web": "6.2.0",
+ "@types/lodash": "^4.14.181",
"@types/url-parse": "^1.4.8",
"chalk": "^3.0.0",
"cheerio": "^0.22.0",
"chokidar": "^3.3.0",
"colors": "1.4.0",
"commander": "^8.1.0",
- "diff": "^4.0.1",
- "figlet": "^1.2.4",
+ "diff": "^8.0.3",
+ "figlet": "^1.9.4",
"find-up": "^4.1.0",
"fs-extra": "^9.0.1",
"ignore": "^5.1.4",
- "istextorbinary": "^3.3.0",
+ "istextorbinary": "^9.5.0",
"jest": "^29.7.0",
"live-server": "1.2.1",
"lodash": "^4.17.15",
@@ -45587,6 +46444,12 @@
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"dev": true
},
+ "resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true
+ },
"resolve-url": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
@@ -47165,10 +48028,13 @@
"dev": true
},
"textextensions": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-3.3.0.tgz",
- "integrity": "sha512-mk82dS8eRABNbeVJrEiN5/UMSCliINAuz8mkUwH4SwslkNP//gbEzlWNS5au0z5Dpx40SQxzqZevZkn+WYJ9Dw==",
- "dev": true
+ "version": "6.11.0",
+ "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-6.11.0.tgz",
+ "integrity": "sha512-tXJwSr9355kFJI3lbCkPpUH5cP8/M0GGy2xLO34aZCjMXBaK3SoPnZwr/oWmo1FdCnELcs4npdCIOFtq9W3ruQ==",
+ "dev": true,
+ "requires": {
+ "editions": "^6.21.0"
+ }
},
"thingies": {
"version": "2.5.0",
@@ -47468,6 +48334,17 @@
}
}
},
+ "tsx": {
+ "version": "4.21.0",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
+ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
+ "dev": true,
+ "requires": {
+ "esbuild": "~0.27.0",
+ "fsevents": "~2.3.3",
+ "get-tsconfig": "^4.7.5"
+ }
+ },
"tuf-js": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-2.2.1.tgz",
@@ -47747,6 +48624,12 @@
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
"integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="
},
+ "version-range": {
+ "version": "4.15.0",
+ "resolved": "https://registry.npmjs.org/version-range/-/version-range-4.15.0.tgz",
+ "integrity": "sha512-Ck0EJbAGxHwprkzFO966t4/5QkRuzh+/I1RxhLgUKKwEn+Cd8NwM60mE3AqBZg5gYODoXW0EFsQvbZjRlvdqbg==",
+ "dev": true
+ },
"vue": {
"version": "3.3.11",
"resolved": "https://registry.npmjs.org/vue/-/vue-3.3.11.tgz",
diff --git a/package.json b/package.json
index 19c51c4e26..c2fa1f34b7 100644
--- a/package.json
+++ b/package.json
@@ -5,22 +5,22 @@
"packages/*"
],
"scripts": {
- "prebuild:backend": "npm run clean",
- "build:backend": "tsc --noEmitOnError",
"build:web": "cd packages/core-web && npm run build",
- "build:dg": "cd docs && ../packages/cli/index.js build -s dg-site.json",
- "build:ug": "cd docs && ../packages/cli/index.js build -s ug-site.json",
- "build:docs": "cd docs && node ../packages/cli/index.js build --baseUrl",
- "deploy:dg": "cd docs && ../packages/cli/index.js deploy -s dg-site.json --ci",
- "deploy:ug": "cd docs && ../packages/cli/index.js deploy -s ug-site.json --ci",
- "deploy:netlify": "npm run setup && npm run build:web && cd docs && node ../packages/cli/index.js build --baseUrl",
- "clean": "node ./scripts/clean.js",
+ "prebuild:backend": "npm run clean",
+ "build:backend": "tsc --build",
+ "build:dg": "cd docs && node ../packages/cli/dist/index.js build -s dg-site.json",
+ "build:ug": "cd docs && node ../packages/cli/dist/index.js build -s ug-site.json",
+ "build:docs": "cd docs && node ../packages/cli/dist/index.js build --baseUrl",
+ "deploy:dg": "cd docs && node ../packages/cli/dist/index.js deploy -s dg-site.json --ci",
+ "deploy:ug": "cd docs && node ../packages/cli/dist/index.js deploy -s ug-site.json --ci",
+ "deploy:netlify": "npm run setup && npm run build:web && cd docs && node ../packages/cli/dist/index.js build --baseUrl",
+ "clean": "tsc --build --clean && node ./scripts/clean.js",
"csslint": "stylelint **/*.css **/*.vue",
"csslintfix": "stylelint **/*.css **/*.vue --fix",
- "dev": "tsc --watch",
+ "dev": "tsc --build --watch",
"lint": "eslint . --ext .js,.ts,.vue && npm run csslint",
"lintfix": "eslint . --ext .js,.ts,.vue --fix && npm run csslintfix",
- "setup": "npm ci && npm run clean && lerna run prepare",
+ "setup": "npm ci && npm run build:backend",
"test": "npm run lint && lerna run test --stream",
"updatetest": "lerna run updatetest --stream"
},
@@ -41,6 +41,7 @@
"stylelint-config-recommended-vue": "^1.5.0",
"stylelint-config-standard": "^36.0.0",
"typescript": "^5.3.3",
- "walk-sync": "^2.0.2"
+ "walk-sync": "^2.0.2",
+ "tsx": "^4.21.0"
}
}
diff --git a/packages/cli/index.js b/packages/cli/index.ts
similarity index 90%
rename from packages/cli/index.js
rename to packages/cli/index.ts
index 12b3f6bcb3..244a172d3f 100755
--- a/packages/cli/index.js
+++ b/packages/cli/index.ts
@@ -1,15 +1,13 @@
#!/usr/bin/env node
// Entry file for MarkBind project
-const program = require('commander');
-
-const logger = require('./src/util/logger');
-const { build } = require('./src/cmd/build');
-const { deploy } = require('./src/cmd/deploy');
-const { init } = require('./src/cmd/init');
-const { serve } = require('./src/cmd/serve');
-
-const CLI_VERSION = require('./package.json').version;
+import { program } from 'commander';
+import * as logger from './src/util/logger';
+import { build } from './src/cmd/build';
+import { deploy } from './src/cmd/deploy';
+import { init } from './src/cmd/init';
+import { serve } from './src/cmd/serve';
+import { version as CLI_VERSION } from './package.json';
process.title = 'MarkBind';
process.stdout.write(
@@ -19,6 +17,7 @@ process.stdout.write(
function printHeader() {
logger.logo();
logger.log(` v${CLI_VERSION}`);
+ return '';
}
program
diff --git a/packages/cli/package.json b/packages/cli/package.json
index e9246f10d1..ff06211231 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -12,17 +12,21 @@
],
"homepage": "https://markbind.org",
"license": "MIT",
- "main": "index.js",
+ "main": "dist/index.js",
+ "types": "dist/index.d.ts",
"bin": {
- "markbind": "./index.js"
+ "markbind": "./dist/index.js"
},
+ "files": ["dist/", "README.md"],
"repository": {
"type": "git",
"url": "https://github.com/MarkBind/markbind.git"
},
"scripts": {
- "test": "jest --colors && cd test/functional && node test.js",
- "updatetest": "cd test/functional && node updatetest.js"
+ "test": "jest --colors && cd test/functional && node ../../dist/test/functional/test.js",
+ "updatetest": "cd test/functional && node updatetest.js",
+ "build": "tsc",
+ "dev": "tsc --watch"
},
"dependencies": {
"@markbind/core": "6.2.0",
@@ -32,7 +36,7 @@
"chokidar": "^3.3.0",
"colors": "1.4.0",
"commander": "^8.1.0",
- "figlet": "^1.2.4",
+ "figlet": "^1.9.4",
"find-up": "^4.1.0",
"fs-extra": "^9.0.1",
"live-server": "1.2.1",
@@ -42,10 +46,11 @@
"winston-daily-rotate-file": "^3.10.0"
},
"devDependencies": {
+ "@types/lodash": "^4.14.181",
"@types/url-parse": "^1.4.8",
- "diff": "^4.0.1",
+ "diff": "^8.0.3",
"ignore": "^5.1.4",
- "istextorbinary": "^3.3.0",
+ "istextorbinary": "^9.5.0",
"jest": "^29.7.0",
"memfs": "^4.56.2",
"walk-sync": "^2.0.2"
diff --git a/packages/cli/src/cmd/build.js b/packages/cli/src/cmd/build.js
deleted file mode 100755
index 438f9f7c8f..0000000000
--- a/packages/cli/src/cmd/build.js
+++ /dev/null
@@ -1,45 +0,0 @@
-const path = require('path');
-
-const { Site } = require('@markbind/core');
-
-const cliUtil = require('../util/cliUtil');
-const logger = require('../util/logger');
-
-const _ = {};
-_.isBoolean = require('lodash/isBoolean');
-
-function build(userSpecifiedRoot, output, options) {
- // if --baseUrl contains no arguments (options.baseUrl === true) then set baseUrl to empty string
- const baseUrl = _.isBoolean(options.baseUrl) ? '' : options.baseUrl;
-
- let rootFolder;
- try {
- rootFolder = cliUtil.findRootFolder(userSpecifiedRoot, options.siteConfig);
- } catch (error) {
- logger.error(error.message);
- logger.error('This directory does not appear to contain a valid MarkBind site. '
- + 'Check that you are running the command in the correct directory!\n'
- + '\n'
- + 'To create a new MarkBind site, run:\n'
- + ' markbind init');
- cliUtil.cleanupFailedMarkbindBuild(userSpecifiedRoot);
- process.exitCode = 1;
- process.exit();
- }
-
- const defaultOutputRoot = path.join(rootFolder, '_site');
- const outputFolder = output ? path.resolve(process.cwd(), output) : defaultOutputRoot;
- new Site(rootFolder, outputFolder, undefined, undefined, options.siteConfig)
- .generate(baseUrl)
- .then(() => {
- logger.info('Build success!');
- })
- .catch((error) => {
- logger.error(error.message);
- process.exitCode = 1;
- });
-}
-
-module.exports = {
- build,
-};
diff --git a/packages/cli/src/cmd/build.ts b/packages/cli/src/cmd/build.ts
new file mode 100755
index 0000000000..eb499b2ed6
--- /dev/null
+++ b/packages/cli/src/cmd/build.ts
@@ -0,0 +1,50 @@
+import path from 'path';
+import { Site } from '@markbind/core';
+import isBoolean from 'lodash/isBoolean';
+import isError from 'lodash/isError';
+import * as cliUtil from '../util/cliUtil';
+import * as logger from '../util/logger';
+
+const _ = {
+ isBoolean,
+ isError,
+};
+
+function build(userSpecifiedRoot: string, output: string, options: any) {
+ // if --baseUrl contains no arguments (options.baseUrl === true) then set baseUrl to empty string
+ const baseUrl = _.isBoolean(options.baseUrl) ? '' : options.baseUrl;
+
+ let rootFolder;
+ try {
+ rootFolder = cliUtil.findRootFolder(userSpecifiedRoot, options.siteConfig);
+ } catch (error) {
+ if (_.isError(error)) {
+ logger.error(error.message);
+ logger.error('This directory does not appear to contain a valid MarkBind site. '
+ + 'Check that you are running the command in the correct directory!\n'
+ + '\n'
+ + 'To create a new MarkBind site, run:\n'
+ + ' markbind init');
+ } else {
+ logger.error(`Unknown error occurred: ${error}`);
+ }
+ cliUtil.cleanupFailedMarkbindBuild();
+ process.exitCode = 1;
+ process.exit();
+ }
+
+ const defaultOutputRoot = path.join(rootFolder, '_site');
+ const outputFolder = output ? path.resolve(process.cwd(), output) : defaultOutputRoot;
+ new Site(rootFolder, outputFolder, '', undefined, options.siteConfig,
+ false, false, () => {})
+ .generate(baseUrl)
+ .then(() => {
+ logger.info('Build success!');
+ })
+ .catch((error) => {
+ logger.error(error.message);
+ process.exitCode = 1;
+ });
+}
+
+export { build };
diff --git a/packages/cli/src/cmd/deploy.js b/packages/cli/src/cmd/deploy.ts
similarity index 55%
rename from packages/cli/src/cmd/deploy.js
rename to packages/cli/src/cmd/deploy.ts
index 317ff21ff4..dde6b13554 100755
--- a/packages/cli/src/cmd/deploy.js
+++ b/packages/cli/src/cmd/deploy.ts
@@ -1,21 +1,28 @@
-const path = require('path');
+import path from 'path';
+import { Site } from '@markbind/core';
+import isError from 'lodash/isError';
+import * as cliUtil from '../util/cliUtil';
+import * as logger from '../util/logger';
-const { Site } = require('@markbind/core');
-
-const cliUtil = require('../util/cliUtil');
-const logger = require('../util/logger');
+const _ = {
+ isError,
+};
-function deploy(userSpecifiedRoot, options) {
+function deploy(userSpecifiedRoot: string, options: any) {
let rootFolder;
try {
rootFolder = cliUtil.findRootFolder(userSpecifiedRoot, options.siteConfig);
} catch (error) {
- logger.error(error.message);
- logger.error('This directory does not appear to contain a valid MarkBind site. '
- + 'Check that you are running the command in the correct directory!\n'
- + '\n'
- + 'To create a new MarkBind site, run:\n'
- + ' markbind init');
+ if (_.isError(error)) {
+ logger.error(error.message);
+ logger.error('This directory does not appear to contain a valid MarkBind site. '
+ + 'Check that you are running the command in the correct directory!\n'
+ + '\n'
+ + 'To create a new MarkBind site, run:\n'
+ + ' markbind init');
+ } else {
+ logger.error(`Unknown error occurred: ${error}`);
+ }
process.exitCode = 1;
process.exit();
}
@@ -23,9 +30,10 @@ function deploy(userSpecifiedRoot, options) {
// Choose to build or not build depending on --no-build flag
// We cannot chain generate and deploy while calling generate conditionally, so we split with if-else
- const site = new Site(rootFolder, outputFolder, undefined, undefined, options.siteConfig);
+ const site = new Site(rootFolder, outputFolder, '', undefined, options.siteConfig,
+ false, false, () => {});
if (options.build) {
- site.generate()
+ site.generate(undefined)
.then(() => {
logger.info('Build success!');
site.deploy(options.ci)
@@ -49,6 +57,4 @@ function deploy(userSpecifiedRoot, options) {
}
}
-module.exports = {
- deploy,
-};
+export { deploy };
diff --git a/packages/cli/src/cmd/init.js b/packages/cli/src/cmd/init.ts
similarity index 50%
rename from packages/cli/src/cmd/init.js
rename to packages/cli/src/cmd/init.ts
index 9b68980ede..3aaa3fb96c 100755
--- a/packages/cli/src/cmd/init.js
+++ b/packages/cli/src/cmd/init.ts
@@ -1,11 +1,16 @@
-const fs = require('fs-extra');
-const path = require('path');
+import fs from 'fs-extra';
+import path from 'path';
+import isError from 'lodash/isError';
-const { Template } = require('@markbind/core');
+import { Template } from '@markbind/core';
-const logger = require('../util/logger');
+import * as logger from '../util/logger';
-async function init(root, options) {
+const _ = {
+ isError,
+};
+
+async function init(root: string, options: any) {
const rootFolder = path.resolve(root || process.cwd());
if (options.convert) {
@@ -21,7 +26,11 @@ async function init(root, options) {
await template.init();
logger.info('Initialization success.');
} catch (error) {
- logger.error(`Failed to initialize site with given template with error: ${error.message}`);
+ if (_.isError(error)) {
+ logger.error(`Failed to initialize site with given template with error: ${error.message}`);
+ } else {
+ logger.error(`Failed to initialize site with given template with error: ${error}`);
+ }
process.exitCode = 1;
}
@@ -31,12 +40,14 @@ async function init(root, options) {
await template.convert();
logger.info('Conversion success.');
} catch (error) {
- logger.error(error.message);
+ if (_.isError(error)) {
+ logger.error(error.message);
+ } else {
+ logger.error(`Unknown error occurred: ${error}`);
+ }
process.exitCode = 1;
}
}
}
-module.exports = {
- init,
-};
+export { init };
diff --git a/packages/cli/src/cmd/serve.js b/packages/cli/src/cmd/serve.ts
similarity index 75%
rename from packages/cli/src/cmd/serve.js
rename to packages/cli/src/cmd/serve.ts
index c051e5924b..a2f4453c05 100755
--- a/packages/cli/src/cmd/serve.js
+++ b/packages/cli/src/cmd/serve.ts
@@ -1,40 +1,45 @@
-const chokidar = require('chokidar');
-const path = require('path');
-const readline = require('readline');
+import chokidar from 'chokidar';
+import path from 'path';
+import readline from 'readline';
+import isError from 'lodash/isError';
-const { Site } = require('@markbind/core');
-const { pageVueServerRenderer } = require('@markbind/core/src/Page/PageVueServerRenderer');
+import { Site } from '@markbind/core';
+import { pageVueServerRenderer } from '@markbind/core/src/Page/PageVueServerRenderer';
-const fsUtil = require('@markbind/core/src/utils/fsUtil');
-const { INDEX_MARKDOWN_FILE } = require('@markbind/core/src/Site/constants');
+import * as fsUtil from '@markbind/core/src/utils/fsUtil';
+import { INDEX_MARKDOWN_FILE } from '@markbind/core/src/Site/constants';
-const cliUtil = require('../util/cliUtil');
-const liveServer = require('../lib/live-server');
-const logger = require('../util/logger');
-const {
+import * as cliUtil from '../util/cliUtil';
+import liveServer from '../lib/live-server';
+import * as logger from '../util/logger';
+import {
addHandler,
changeHandler,
lazyReloadMiddleware,
removeHandler,
-} = require('../util/serveUtil');
+} from '../util/serveUtil';
-const {
+import {
isValidServeHost,
isIPAddressZero,
-} = require('../util/ipUtil');
+} from '../util/ipUtil';
-function questionAsync(question) {
+const _ = {
+ isError,
+};
+
+function questionAsync(question: string): Promise {
const readlineInterface = readline.createInterface({ input: process.stdin, output: process.stdout });
return new Promise((resolve) => {
- readlineInterface.question(question, (response) => {
+ readlineInterface.question(question, (response: string) => {
readlineInterface.close();
resolve(response);
});
});
}
-function serve(userSpecifiedRoot, options) {
+function serve(userSpecifiedRoot: string, options: any) {
if (options.dev) {
logger.useDebugConsole();
}
@@ -49,13 +54,17 @@ function serve(userSpecifiedRoot, options) {
process.exit();
}
} catch (error) {
- logger.error(error.message);
- logger.error('This directory does not appear to contain a valid MarkBind site. '
- + 'Check that you are running the command in the correct directory!\n'
- + '\n'
- + 'To create a new MarkBind site, run:\n'
- + ' markbind init');
- cliUtil.cleanupFailedMarkbindBuild(userSpecifiedRoot);
+ if (_.isError(error)) {
+ logger.error(error.message);
+ logger.error('This directory does not appear to contain a valid MarkBind site. '
+ + 'Check that you are running the command in the correct directory!\n'
+ + '\n'
+ + 'To create a new MarkBind site, run:\n'
+ + ' markbind init');
+ } else {
+ logger.error(`Unknown error occurred: ${error}`);
+ }
+ cliUtil.cleanupFailedMarkbindBuild();
process.exitCode = 1;
process.exit();
}
@@ -82,7 +91,7 @@ function serve(userSpecifiedRoot, options) {
options.backgroundBuild, reloadAfterBackgroundBuild);
// server config
- const serverConfig = {
+ const serverConfig: any = {
open: options.open,
logLevel: 0,
root: outputFolder,
@@ -124,7 +133,7 @@ function serve(userSpecifiedRoot, options) {
const getMiddlewares = webpackDevConfig.clientEntry;
getMiddlewares(`${config.baseUrl}/markbind`)
- .forEach(middleware => serverConfig.middleware.push(middleware));
+ .forEach((middleware: any) => serverConfig.middleware.push(middleware));
}
if (onePagePath) {
@@ -135,7 +144,7 @@ function serve(userSpecifiedRoot, options) {
serverConfig.open = serverConfig.open && `${config.baseUrl}/`;
}
- return site.generate();
+ return site.generate('');
})
.then(() => {
const watcher = chokidar.watch(rootFolder, {
@@ -165,11 +174,15 @@ function serve(userSpecifiedRoot, options) {
});
})
.catch((error) => {
- logger.error(error.message);
+ if (_.isError(error)) {
+ logger.error(error.message);
+ } else {
+ logger.error(`Unknown error occurred: ${error}`);
+ }
process.exitCode = 1;
});
}
-module.exports = {
+export {
serve,
};
diff --git a/packages/cli/src/lib/live-server/index.d.ts b/packages/cli/src/lib/live-server/index.d.ts
new file mode 100644
index 0000000000..6c4ce61623
--- /dev/null
+++ b/packages/cli/src/lib/live-server/index.d.ts
@@ -0,0 +1,47 @@
+// Type definitions for live-server 1.2
+// Project: https://github.com/tapio/live-server#readme
+// Definitions by: Josh Cummings
+// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
+
+/**
+ * The live-server start params.
+ */
+export interface LiveServerParams {
+ /** Set the server port. Defaults to 8080. */
+ port?: number | undefined;
+ /** Set the address to bind to. Defaults to 0.0.0.0 or process.env.IP. */
+ host?: string | undefined;
+ /** Set root directory that's being served. Defaults to cwd. */
+ root?: string | undefined;
+ /** When false, it won't load your browser by default. */
+ open?: boolean | undefined;
+ /** Comma-separated string for paths to ignore. */
+ ignore?: string | undefined;
+ /** When set, serve this file (server root relative) for every 404 (useful for single-page applications). */
+ file?: string | undefined;
+ /** Waits for all changes, before reloading. Defaults to 0 sec. */
+ wait?: number | undefined;
+ /** Mount a directory to a route. */
+ mount?: string[][] | undefined;
+ /** 0 = errors only, 1 = some, 2 = lots */
+ logLevel?: 0 | 1 | 2 | undefined;
+ /** Takes an array of Connect-compatible middleware that are injected into the server middleware stack. */
+ middleware?: Array<(req: any, res: any, next: any) => void> | undefined;
+}
+
+/**
+ * Start live-server.
+ */
+// CHANGED: return type from void => Server
+export function start(params: LiveServerParams): Server;
+
+/**
+ * Shutdown live-server.
+ */
+export function shutdown(): void;
+
+// CHANGED: add reloadActiveTabs export
+export function reloadActiveTabs(): void;
+
+// CHANGED: add getActiveUrls export
+export function getActiveUrls(): string[]
diff --git a/packages/cli/src/util/cliUtil.js b/packages/cli/src/util/cliUtil.js
deleted file mode 100644
index 6b743ddfce..0000000000
--- a/packages/cli/src/util/cliUtil.js
+++ /dev/null
@@ -1,53 +0,0 @@
-const findUp = require('find-up');
-const fs = require('fs-extra');
-const path = require('path');
-const { SITE_CONFIG_NAME } = require('@markbind/core/src/Site/constants');
-
-const DIR_NOT_EMPTY_ERROR_CODE = 'ENOTEMPTY';
-
-function tryDeleteFolder(pathName) {
- if (!fs.pathExistsSync(pathName)) {
- return;
- }
- try {
- fs.rmdirSync(pathName);
- } catch (error) {
- // If directory is not empty, fail silently
- if (error.code !== DIR_NOT_EMPTY_ERROR_CODE) {
- // Warn for other unexpected errors
- // Use `console` instead of logger as we don't want to create a new logger instance
- // that might pollute the working directory again.
- // eslint-disable-next-line no-console
- console.warn(`WARNING: Failed to delete directory ${pathName}: ${error.message}`);
- }
- }
-}
-
-module.exports = {
- findRootFolder: (userSpecifiedRoot, siteConfigPath = SITE_CONFIG_NAME) => {
- if (userSpecifiedRoot) {
- const resolvedUserSpecifiedRoot = path.resolve(userSpecifiedRoot);
- const expectedConfigPath = path.join(resolvedUserSpecifiedRoot, siteConfigPath);
- if (!fs.existsSync(expectedConfigPath)) {
- throw new Error(`Config file not found at user specified root ${resolvedUserSpecifiedRoot}`);
- }
- return resolvedUserSpecifiedRoot;
- }
-
- const currentWorkingDir = process.cwd();
- // Enforces findUp uses value of process.cwd() to determine starting dir
- // This allows us to define starting dir when testing by mocking process.cwd()
- const foundConfigPath = findUp.sync(siteConfigPath, { cwd: currentWorkingDir });
- if (!foundConfigPath) {
- throw new Error(`No config file found in parent directories of ${currentWorkingDir}`);
- }
- return path.dirname(foundConfigPath);
- },
- cleanupFailedMarkbindBuild: () => {
- const markbindDir = path.join(process.cwd(), '_markbind');
- const logsDir = path.join(markbindDir, 'logs');
-
- tryDeleteFolder(logsDir);
- tryDeleteFolder(markbindDir);
- },
-};
diff --git a/packages/cli/src/util/cliUtil.ts b/packages/cli/src/util/cliUtil.ts
new file mode 100644
index 0000000000..3dd702d199
--- /dev/null
+++ b/packages/cli/src/util/cliUtil.ts
@@ -0,0 +1,64 @@
+import findUp from 'find-up';
+import fs from 'fs-extra';
+import path from 'path';
+import isString from 'lodash/isString';
+
+import { SITE_CONFIG_NAME } from '@markbind/core/src/Site/constants';
+
+const DIR_NOT_EMPTY_ERROR_CODE = 'ENOTEMPTY';
+
+function hasErrorCodeAndMessage(err: any): err is { code: string, message: string } {
+ return isString(err.code) && isString(err.message);
+}
+
+function tryDeleteFolder(pathName: string) {
+ if (!fs.pathExistsSync(pathName)) {
+ return;
+ }
+ try {
+ fs.rmdirSync(pathName);
+ } catch (error) {
+ if (hasErrorCodeAndMessage(error)) {
+ // If directory is not empty, fail silently
+ if (error.code !== DIR_NOT_EMPTY_ERROR_CODE) {
+ // Warn for other unexpected errors
+ // Use `console` instead of logger as we don't want to create a new logger instance
+ // that might pollute the working directory again.
+ // eslint-disable-next-line no-console
+ console.warn(`WARNING: Failed to delete directory ${pathName}: ${error.message}`);
+ }
+ } else {
+ // eslint-disable-next-line no-console
+ console.warn(`WARNING: Failed to delete directory ${pathName}: Unknown err ${error}`);
+ }
+ }
+}
+
+export function findRootFolder(
+ userSpecifiedRoot: string, siteConfigPath: string = SITE_CONFIG_NAME): string {
+ if (userSpecifiedRoot) {
+ const resolvedUserSpecifiedRoot = path.resolve(userSpecifiedRoot);
+ const expectedConfigPath = path.join(resolvedUserSpecifiedRoot, siteConfigPath);
+ if (!fs.existsSync(expectedConfigPath)) {
+ throw new Error(`Config file not found at user specified root ${resolvedUserSpecifiedRoot}`);
+ }
+ return resolvedUserSpecifiedRoot;
+ }
+
+ const currentWorkingDir = process.cwd();
+ // Enforces findUp uses value of process.cwd() to determine starting dir
+ // This allows us to define starting dir when testing by mocking process.cwd()
+ const foundConfigPath = findUp.sync(siteConfigPath, { cwd: currentWorkingDir });
+ if (!foundConfigPath) {
+ throw new Error(`No config file found in parent directories of ${currentWorkingDir}`);
+ }
+ return path.dirname(foundConfigPath);
+}
+
+export function cleanupFailedMarkbindBuild() {
+ const markbindDir = path.join(process.cwd(), '_markbind');
+ const logsDir = path.join(markbindDir, 'logs');
+
+ tryDeleteFolder(logsDir);
+ tryDeleteFolder(markbindDir);
+}
diff --git a/packages/cli/src/util/ipUtil.js b/packages/cli/src/util/ipUtil.ts
similarity index 88%
rename from packages/cli/src/util/ipUtil.js
rename to packages/cli/src/util/ipUtil.ts
index 47f3affb79..6fa2a6b6af 100644
--- a/packages/cli/src/util/ipUtil.js
+++ b/packages/cli/src/util/ipUtil.ts
@@ -4,7 +4,7 @@
*
* Credits to Danail Gabenski
*/
-const isIpv4Address = (address) => {
+const isIpv4Address = (address: string): boolean => {
const patternForIpV4 = /^((25[0-5]|(2[0-4]|1\d|[1-9]|)\d)\.?\b){4}$/;
return patternForIpV4.test(address);
@@ -16,7 +16,7 @@ const isIpv4Address = (address) => {
*
* Credits to David M. Syzdek
*/
-const isIpv6Address = (address) => {
+const isIpv6Address = (address: string): boolean => {
const patternForIpV6 = new RegExp(
'^(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}'
+ '|([0-9a-fA-F]{1,4}:){1,7}:'
@@ -38,7 +38,7 @@ const isIpv6Address = (address) => {
return patternForIpV6.test(address);
};
-function isValidServeHost(address) {
+function isValidServeHost(address: string): boolean {
if (address === 'localhost') {
return true;
}
@@ -46,14 +46,14 @@ function isValidServeHost(address) {
return isIpv4Address(address) || isIpv6Address(address);
}
-function isIPAddressZero(address) {
+function isIPAddressZero(address: string): boolean {
const patternForIPv4Zero = /^0(\.0)*$/;
const patternForIPv6Zero = /^([0]{0,4}:){0,7}([0]{0,4}){0,1}$/;
return patternForIPv4Zero.test(address) || patternForIPv6Zero.test(address);
}
-module.exports = {
+export {
isValidServeHost,
isIPAddressZero,
};
diff --git a/packages/cli/src/util/logger.js b/packages/cli/src/util/logger.ts
similarity index 50%
rename from packages/cli/src/util/logger.js
rename to packages/cli/src/util/logger.ts
index 693cc83e45..83c4e60158 100644
--- a/packages/cli/src/util/logger.js
+++ b/packages/cli/src/util/logger.ts
@@ -1,9 +1,8 @@
-const chalk = require('chalk');
-const figlet = require('figlet');
-const DailyRotateFile = require('winston-daily-rotate-file');
-const winston = require('winston');
+import chalk from 'chalk';
+import figlet from 'figlet';
-const coreLogger = require('@markbind/core/src/utils/logger');
+import * as winston from 'winston';
+import 'winston-daily-rotate-file';
// @markbind/core's consoleTransport but with level: info
const consoleTransport = new (winston.transports.Console)({
@@ -14,19 +13,17 @@ const consoleTransport = new (winston.transports.Console)({
showLevel: true,
});
-function useDebugConsole() {
+function useDebugConsole(): void {
consoleTransport.level = 'debug';
}
-const dailyRotateFileTransport = new DailyRotateFile({
+const dailyRotateFileTransport = new winston.transports.DailyRotateFile({
datePattern: 'YYYY-MM-DD',
dirname: '_markbind/logs',
filename: 'markbind-%DATE%.log',
handleExceptions: true,
- humanReadableUnhandledException: true,
level: 'debug',
maxFiles: 5,
- showLevel: true,
});
// Reconfigure the default instance logger winston provides with DailyRotateFile for markbind-cli
@@ -38,14 +35,19 @@ winston.configure({
],
});
-module.exports = {
- error: coreLogger.error,
- warn: coreLogger.warn,
- info: coreLogger.info,
- verbose: coreLogger.verbose,
- debug: coreLogger.debug,
- /* eslint-disable no-console */
- log: console.log,
- logo: () => console.log(chalk.cyan(figlet.textSync('MarkBind', { horizontalLayout: 'full' }))),
+export {
+ error,
+ warn,
+ info,
+ verbose,
+ debug,
+} from '@markbind/core/src/utils/logger';
+
+export {
useDebugConsole,
};
+
+// eslint-disable-next-line no-console
+export const logo = () => console.log(chalk.cyan(figlet.textSync('MarkBind', { horizontalLayout: 'full' })));
+// eslint-disable-next-line no-console
+export const log = (msg: string) => console.log(msg);
diff --git a/packages/cli/src/util/serveUtil.js b/packages/cli/src/util/serveUtil.js
deleted file mode 100755
index 81b21d6c21..0000000000
--- a/packages/cli/src/util/serveUtil.js
+++ /dev/null
@@ -1,110 +0,0 @@
-const fs = require('fs-extra');
-const path = require('path');
-
-const fsUtil = require('@markbind/core/src/utils/fsUtil');
-const {
- LAZY_LOADING_SITE_FILE_NAME,
-} = require('@markbind/core/src/Site/constants');
-
-const liveServer = require('../lib/live-server');
-const logger = require('./logger');
-
-const syncOpenedPages = (site) => {
- logger.info('Synchronizing opened pages list before reload');
- const normalizedActiveUrls = liveServer.getActiveUrls().map((url) => {
- const completeUrl = path.extname(url) === '' ? path.join(url, 'index') : url;
- return fsUtil.removeExtension(completeUrl);
- });
- site.changeCurrentOpenedPages(normalizedActiveUrls);
-};
-
-const addHandler = (site, onePagePath) => (filePath) => {
- logger.info(`[${new Date().toLocaleTimeString()}] Reload for file add: ${filePath}`);
- if (onePagePath) {
- syncOpenedPages(site);
- }
- Promise.resolve().then(async () => {
- if (site.isFilepathAPage(filePath) || site.isDependencyOfPage(filePath)) {
- return site.rebuildSourceFiles();
- }
- return site.buildAsset(filePath);
- }).catch((err) => {
- logger.error(err.message);
- });
-};
-
-const changeHandler = (site, onePagePath) => (filePath) => {
- logger.info(`[${new Date().toLocaleTimeString()}] Reload for file change: ${filePath}`);
- if (onePagePath) {
- syncOpenedPages(site);
- }
- Promise.resolve().then(async () => {
- if (path.basename(filePath) === path.basename(site.siteConfigPath)) {
- return site.reloadSiteConfig();
- }
- if (site.isDependencyOfPage(filePath)) {
- return site.rebuildAffectedSourceFiles(filePath);
- }
- return site.buildAsset(filePath);
- }).catch((err) => {
- logger.error(err.message);
- });
-};
-
-const removeHandler = (site, onePagePath) => (filePath) => {
- logger.info(`[${new Date().toLocaleTimeString()}] Reload for file deletion: ${filePath}`);
- if (onePagePath) {
- syncOpenedPages(site);
- }
- Promise.resolve().then(async () => {
- if (site.isFilepathAPage(filePath) || site.isDependencyOfPage(filePath)) {
- return site.rebuildSourceFiles();
- }
- return site.removeAsset(filePath);
- }).catch((err) => {
- logger.error(err.message);
- });
-};
-
-const lazyReloadMiddleware = (site, rootFolder, config) => (req, res, next) => {
- const urlExtension = path.posix.extname(req.url);
-
- const hasEndingSlash = req.url.endsWith('/');
- const hasNoExtension = urlExtension === '';
- const isHtmlFileRequest = urlExtension === '.html' || hasEndingSlash || hasNoExtension;
-
- if (!isHtmlFileRequest || req.url.endsWith('._include_.html')) {
- next();
- return;
- }
-
- if (hasNoExtension && !hasEndingSlash) {
- // Urls of type 'host/userGuide' - check if 'userGuide' is a raw file or does not exist
- const diskFilePath = path.resolve(rootFolder, req.url);
- if (!fs.existsSync(diskFilePath) || !(fs.statSync(diskFilePath).isDirectory())) {
- // Request for a raw file
- next();
- return;
- }
- }
-
- const urlWithoutBaseUrl = req.url.replace(config.baseUrl, '');
- // Map 'hostname/userGuide/' and 'hostname/userGuide' to hostname/userGuide/index.
- const urlWithIndex = (hasNoExtension || hasEndingSlash)
- ? path.posix.join(urlWithoutBaseUrl, 'index')
- : urlWithoutBaseUrl;
- const urlWithoutExtension = fsUtil.removeExtension(urlWithIndex);
-
- const didInitiateRebuild = site.changeCurrentPage(urlWithoutExtension);
- if (didInitiateRebuild) {
- req.url = fsUtil.ensurePosix(path.join(config.baseUrl || '/', LAZY_LOADING_SITE_FILE_NAME));
- }
- next();
-};
-
-module.exports = {
- addHandler,
- changeHandler,
- lazyReloadMiddleware,
- removeHandler,
-};
diff --git a/packages/cli/src/util/serveUtil.ts b/packages/cli/src/util/serveUtil.ts
new file mode 100755
index 0000000000..37c54322aa
--- /dev/null
+++ b/packages/cli/src/util/serveUtil.ts
@@ -0,0 +1,140 @@
+import fs from 'fs-extra';
+import path from 'path';
+
+import * as fsUtil from '@markbind/core/src/utils/fsUtil';
+import {
+ LAZY_LOADING_SITE_FILE_NAME,
+} from '@markbind/core/src/Site/constants';
+
+import * as liveServer from '../lib/live-server';
+import * as logger from './logger';
+
+/**
+ * Synchronizes opened pages list before reload
+ * @param site The site instance
+ */
+const syncOpenedPages = (site: any): void => {
+ logger.info('Synchronizing opened pages list before reload');
+ const normalizedActiveUrls = liveServer.getActiveUrls().map((url: string) => {
+ const completeUrl = path.extname(url) === '' ? path.join(url, 'index') : url;
+ return fsUtil.removeExtension(completeUrl);
+ });
+ site.changeCurrentOpenedPages(normalizedActiveUrls);
+};
+
+/**
+ * Handler for file addition events
+ * @param site The site instance
+ * @param onePagePath Flag indicating if one page mode is enabled
+ * @returns Function that handles the file addition
+ */
+const addHandler = (site: any, onePagePath?: boolean) => (filePath: string): void => {
+ logger.info(`[${new Date().toLocaleTimeString()}] Reload for file add: ${filePath}`);
+ if (onePagePath) {
+ syncOpenedPages(site);
+ }
+ Promise.resolve().then(async () => {
+ if (site.isFilepathAPage(filePath) || site.isDependencyOfPage(filePath)) {
+ return site.rebuildSourceFiles();
+ }
+ return site.buildAsset(filePath);
+ }).catch((err: Error) => {
+ logger.error(err.message);
+ });
+};
+
+/**
+ * Handler for file change events
+ * @param site The site instance
+ * @param onePagePath Flag indicating if one page mode is enabled
+ * @returns Function that handles the file change
+ */
+const changeHandler = (site: any, onePagePath?: boolean) => (filePath: string): void => {
+ logger.info(`[${new Date().toLocaleTimeString()}] Reload for file change: ${filePath}`);
+ if (onePagePath) {
+ syncOpenedPages(site);
+ }
+ Promise.resolve().then(async () => {
+ if (path.basename(filePath) === path.basename(site.siteConfigPath)) {
+ return site.reloadSiteConfig();
+ }
+ if (site.isDependencyOfPage(filePath)) {
+ return site.rebuildAffectedSourceFiles(filePath);
+ }
+ return site.buildAsset(filePath);
+ }).catch((err: Error) => {
+ logger.error(err.message);
+ });
+};
+
+/**
+ * Handler for file removal events
+ * @param site The site instance
+ * @param onePagePath Flag indicating if one page mode is enabled
+ * @returns Function that handles the file removal
+ */
+const removeHandler = (site: any, onePagePath?: boolean) => (filePath: string): void => {
+ logger.info(`[${new Date().toLocaleTimeString()}] Reload for file deletion: ${filePath}`);
+ if (onePagePath) {
+ syncOpenedPages(site);
+ }
+ Promise.resolve().then(async () => {
+ if (site.isFilepathAPage(filePath) || site.isDependencyOfPage(filePath)) {
+ return site.rebuildSourceFiles();
+ }
+ return site.removeAsset(filePath);
+ }).catch((err: Error) => {
+ logger.error(err.message);
+ });
+};
+
+/**
+ * Middleware for lazy reloading
+ * @param site The site instance
+ * @param rootFolder The root folder of the site
+ * @param config The site configuration
+ * @returns Middleware function
+ */
+const lazyReloadMiddleware
+ = (site: any, rootFolder: string, config: any) => (req: any, res: any, next: any) => {
+ const urlExtension = path.posix.extname(req.url);
+
+ const hasEndingSlash = req.url.endsWith('/');
+ const hasNoExtension = urlExtension === '';
+ const isHtmlFileRequest = urlExtension === '.html' || hasEndingSlash || hasNoExtension;
+
+ if (!isHtmlFileRequest || req.url.endsWith('._include_.html')) {
+ next();
+ return;
+ }
+
+ if (hasNoExtension && !hasEndingSlash) {
+ // Urls of type 'host/userGuide' - check if 'userGuide' is a raw file or does not exist
+ const diskFilePath = path.resolve(rootFolder, req.url);
+ if (!fs.existsSync(diskFilePath) || !(fs.statSync(diskFilePath).isDirectory())) {
+ // Request for a raw file
+ next();
+ return;
+ }
+ }
+
+ const urlWithoutBaseUrl = req.url.replace(config.baseUrl, '');
+ // Map 'hostname/userGuide/' and 'hostname/userGuide' to hostname/userGuide/index.
+ const urlWithIndex = (hasNoExtension || hasEndingSlash)
+ ? path.posix.join(urlWithoutBaseUrl, 'index')
+ : urlWithoutBaseUrl;
+ const urlWithoutExtension = fsUtil.removeExtension(urlWithIndex);
+
+ const didInitiateRebuild = site.changeCurrentPage(urlWithoutExtension);
+ if (didInitiateRebuild) {
+ req.url = fsUtil.ensurePosix(path.join(config.baseUrl || '/', LAZY_LOADING_SITE_FILE_NAME));
+ }
+ next();
+ };
+
+export {
+ addHandler,
+ changeHandler,
+ lazyReloadMiddleware,
+ removeHandler,
+};
diff --git a/packages/cli/test/functional/.eslintrc.js b/packages/cli/test/functional/.eslintrc.js
index c38aa97590..30e9070e6f 100644
--- a/packages/cli/test/functional/.eslintrc.js
+++ b/packages/cli/test/functional/.eslintrc.js
@@ -2,4 +2,7 @@ module.exports = {
env: {
browser: true,
},
+ rules: {
+ 'import/no-extraneous-dependencies': 'off',
+ },
};
diff --git a/packages/cli/test/functional/test.js b/packages/cli/test/functional/test.ts
similarity index 62%
rename from packages/cli/test/functional/test.js
rename to packages/cli/test/functional/test.ts
index be264d8ccb..2cb9580579 100644
--- a/packages/cli/test/functional/test.js
+++ b/packages/cli/test/functional/test.ts
@@ -1,33 +1,34 @@
-const path = require('path');
-const fs = require('fs-extra');
-const { execSync } = require('child_process');
-
-const { compare } = require('./testUtil/compare');
-
-const { cleanupConvert } = require('./testUtil/cleanup');
-
-const logger = require('../../../core/src/utils/logger');
-
-const {
+import path from 'path';
+import fs from 'fs-extra';
+import { execSync } from 'child_process';
+import isError from 'lodash/isError';
+import * as logger from '@markbind/core/src/utils/logger';
+import { ExecSyncOptions } from 'node:child_process';
+import { compare } from './testUtil/compare';
+import { cleanupConvert } from './testUtil/cleanup';
+import {
testSites,
testConvertSites,
testTemplateSites,
plantumlGeneratedFilesForTestSites,
plantumlGeneratedFilesForConvertSites,
plantumlGeneratedFilesForTemplateSites,
-} = require('./testSites');
+} from './testSites';
-/* eslint-disable no-console */
+const _ = { isError };
+// Path to the compiled CLI executable
+const CLI_PATH = path.resolve(__dirname, '../../index');
-function printFailedMessage(err, siteName) {
+/* eslint-disable no-console */
+function printFailedMessage(err: Error, siteName: string) {
console.log(err);
console.log(`Test result: ${siteName} FAILED`);
}
-process.env.TEST_MODE = true;
+process.env.TEST_MODE = 'true';
process.env.FORCE_COLOR = '3';
-const execOptions = {
+const execOptions: ExecSyncOptions = {
stdio: ['inherit', 'inherit', 'inherit'],
};
@@ -51,11 +52,15 @@ expectedErrors.forEach((error, index) => {
testSites.forEach((siteName) => {
console.log(`Running ${siteName} tests`);
try {
- execSync(`node ../../index.js build ${siteName}`, execOptions);
+ execSync(`node ${CLI_PATH} build ${siteName}`, execOptions);
const siteIgnoredFiles = plantumlGeneratedFilesForTestSites[siteName];
compare(siteName, 'expected', '_site', siteIgnoredFiles);
} catch (err) {
- printFailedMessage(err, siteName);
+ if (_.isError(err)) {
+ printFailedMessage(err, siteName);
+ } else {
+ console.error(`Unknown error for site ${siteName} occurred: ${err}`);
+ }
process.exit(1);
}
});
@@ -65,16 +70,20 @@ testConvertSites.forEach((sitePath) => {
const nonMarkBindSitePath = path.join(sitePath, 'non_markbind_site');
const siteName = sitePath.split('/')[1];
try {
- execSync(`node ../../index.js init ${nonMarkBindSitePath} -c`, execOptions);
- execSync(`node ../../index.js build ${nonMarkBindSitePath}`, execOptions);
+ execSync(`node ${CLI_PATH} init ${nonMarkBindSitePath} -c`, execOptions);
+ execSync(`node ${CLI_PATH} build ${nonMarkBindSitePath}`, execOptions);
const siteIgnoredFiles = plantumlGeneratedFilesForConvertSites[siteName];
compare(sitePath, 'expected', 'non_markbind_site/_site', siteIgnoredFiles);
} catch (err) {
- printFailedMessage(err, sitePath);
- cleanupConvert(path.resolve(__dirname, sitePath));
+ if (_.isError(err)) {
+ printFailedMessage(err, sitePath);
+ } else {
+ console.error(`Unknown error for site ${sitePath} occurred: ${err}`);
+ }
+ cleanupConvert(sitePath);
process.exit(1);
}
- cleanupConvert(path.resolve(__dirname, sitePath));
+ cleanupConvert(sitePath);
});
testTemplateSites.forEach((templateAndSitePath) => {
@@ -85,21 +94,25 @@ testTemplateSites.forEach((templateAndSitePath) => {
console.log(`Running ${sitePath} tests`);
try {
- execSync(`node ../../index.js init ${siteCreationTempPath} --template ${flag}`, execOptions);
- execSync(`node ../../index.js build ${siteCreationTempPath}`, execOptions);
+ execSync(`node ${CLI_PATH} init ${siteCreationTempPath} --template ${flag}`, execOptions);
+ execSync(`node ${CLI_PATH} build ${siteCreationTempPath}`, execOptions);
const siteIgnoredFiles = plantumlGeneratedFilesForTemplateSites[siteName];
compare(sitePath, 'expected', 'tmp/_site', siteIgnoredFiles);
} catch (err) {
- printFailedMessage(err, sitePath);
- fs.removeSync(path.resolve(__dirname, siteCreationTempPath));
+ if (_.isError(err)) {
+ printFailedMessage(err, sitePath);
+ } else {
+ console.error(`Unknown error for site ${sitePath} occurred: ${err}`);
+ }
+ fs.removeSync(siteCreationTempPath);
process.exit(1);
}
- fs.removeSync(path.resolve(__dirname, siteCreationTempPath));
+ fs.removeSync(siteCreationTempPath);
});
function testEmptyDirectoryBuild() {
const siteRootName = 'test_site_empty';
- const siteRootPath = path.join(__dirname, siteRootName);
+ const siteRootPath = path.join('./', siteRootName);
const emptySiteName = 'empty_dir';
const emptySitePath = path.join(siteRootPath, emptySiteName);
@@ -107,7 +120,7 @@ function testEmptyDirectoryBuild() {
const expectedSiteName = 'expected';
const expectedSitePath = path.join(siteRootPath, expectedSiteName);
- const execOptionsWithCwd = {
+ const execOptionsWithCwd: ExecSyncOptions = {
stdio: ['inherit', 'inherit', 'inherit'],
cwd: emptySitePath, // Set the working directory to testEmptyPath
};
@@ -121,7 +134,7 @@ function testEmptyDirectoryBuild() {
// Try to build in empty directory (should fail with specific error)
try {
- execSync(`node ../../../../index.js build ${emptySitePath}`, execOptionsWithCwd);
+ execSync(`node ${CLI_PATH} build ${emptySitePath}`, execOptionsWithCwd);
printFailedMessage(new Error('Expected build to fail but it succeeded'), siteRootName);
process.exit(1);
} catch (err) {
@@ -129,7 +142,11 @@ function testEmptyDirectoryBuild() {
try {
compare(siteRootName, 'expected', 'empty_dir', [], true);
} catch (compareErr) {
- printFailedMessage(compareErr, siteRootName);
+ if (_.isError(compareErr)) {
+ printFailedMessage(compareErr, siteRootName);
+ } else {
+ console.error(`Unknown error for site ${siteRootName} occurred: ${compareErr}`);
+ }
// Reset test_site_empty/empty_dir
fs.emptyDirSync(emptySitePath);
process.exit(1);
diff --git a/packages/cli/test/functional/testSites.js b/packages/cli/test/functional/testSites.ts
similarity index 79%
rename from packages/cli/test/functional/testSites.js
rename to packages/cli/test/functional/testSites.ts
index 198744c0a9..acadffe75c 100644
--- a/packages/cli/test/functional/testSites.js
+++ b/packages/cli/test/functional/testSites.ts
@@ -1,3 +1,8 @@
+// Type definitions for plantuml generated files
+interface PlantumlGeneratedFiles {
+ [key: string]: string[];
+}
+
const testSites = [
'test_site',
'test_site_algolia_plugin',
@@ -22,7 +27,7 @@ const testTemplateSites = [
// these files create git diffs every time they are generated,
// we decided to not commit them to the repository.
// However, we still want to verify that they are present.
-const plantumlGeneratedFilesForTestSites = {
+const plantumlGeneratedFilesForTestSites: PlantumlGeneratedFiles = {
test_site: [
'9c9e77fc0a983cb6b592e65733787bec.png',
'inline-output.png',
@@ -37,13 +42,13 @@ const plantumlGeneratedFilesForTestSites = {
],
};
-const plantumlGeneratedFilesForConvertSites = {};
+const plantumlGeneratedFilesForConvertSites: PlantumlGeneratedFiles = {};
-const plantumlGeneratedFilesForTemplateSites = {
+const plantumlGeneratedFilesForTemplateSites: PlantumlGeneratedFiles = {
test_project: ['diagrams/example.png'],
};
-module.exports = {
+export {
testSites,
testConvertSites,
testTemplateSites,
diff --git a/packages/cli/test/functional/testUtil/cleanup.js b/packages/cli/test/functional/testUtil/cleanup.ts
similarity index 91%
rename from packages/cli/test/functional/testUtil/cleanup.js
rename to packages/cli/test/functional/testUtil/cleanup.ts
index a41c8846e9..4be8769a67 100644
--- a/packages/cli/test/functional/testUtil/cleanup.js
+++ b/packages/cli/test/functional/testUtil/cleanup.ts
@@ -1,7 +1,7 @@
const fs = require('fs-extra');
const path = require('path');
-function cleanupConvert(siteName) {
+function cleanupConvert(siteName: string) {
const directoriesToRemove = [
path.join(siteName, 'non_markbind_site/_markbind'),
path.join(siteName, 'non_markbind_site/_site'),
@@ -20,6 +20,6 @@ function cleanupConvert(siteName) {
});
}
-module.exports = {
+export {
cleanupConvert,
};
diff --git a/packages/cli/test/functional/testUtil/compare.js b/packages/cli/test/functional/testUtil/compare.ts
similarity index 82%
rename from packages/cli/test/functional/testUtil/compare.js
rename to packages/cli/test/functional/testUtil/compare.ts
index 38a6d788c7..ed11a4ad3e 100644
--- a/packages/cli/test/functional/testUtil/compare.js
+++ b/packages/cli/test/functional/testUtil/compare.ts
@@ -1,13 +1,13 @@
-const fs = require('fs');
-const path = require('path');
-const ignore = require('ignore');
-const walkSync = require('walk-sync');
-const { isBinary } = require('istextorbinary');
-const diffChars = require('./diffChars');
+import fs from 'fs';
+import path from 'path';
+import ignore from 'ignore';
+import walkSync from 'walk-sync';
+import { isBinary } from 'istextorbinary';
+import isEqual from 'lodash/isEqual';
+import intersection from 'lodash/intersection';
+import { diffCharsAndPrint as diffChars } from './diffChars';
-const _ = {};
-_.isEqual = require('lodash/isEqual');
-_.intersection = require('lodash/intersection');
+const _ = { isEqual, intersection };
// List of file patterns to ignore during content diff comparison.
// Either binary files or files not recognized correctly by the istextorbinary package.
@@ -20,8 +20,8 @@ const TEST_BLACKLIST = ignore().add([
const CRLF_REGEX = /\r\n/g;
-function _readFileSync(...paths) {
- return fs.readFileSync(path.resolve(...paths), 'utf8');
+function _readFileSync(...paths: string[]) {
+ return fs.readFileSync(path.resolve(...paths));
}
/**
@@ -29,7 +29,7 @@ function _readFileSync(...paths) {
* @param {string[]} filePaths - List of file paths
* @returns {string[]} Filtered list without *.page-vue-render.js files
*/
-function filterPageVueRenderFiles(filePaths) {
+function filterPageVueRenderFiles(filePaths: string[]) {
return filePaths.filter(p => !p.endsWith('.page-vue-render.js'));
}
@@ -38,7 +38,7 @@ function filterPageVueRenderFiles(filePaths) {
* @param {string} dirPath - Existing directory path to analyze
* @returns {string[]} Sorted array of relative directory paths
*/
-function getDirectoryStructure(dirPath) {
+function getDirectoryStructure(dirPath: string) {
const allPaths = walkSync(dirPath, { directories: true, globs: ['**/*'] });
return allPaths
.filter(p => fs.statSync(path.join(dirPath, p))
@@ -59,8 +59,8 @@ function getDirectoryStructure(dirPath) {
* @param {string[]} ignoredPaths - Specify any paths to ignore for comparison, but still check for existence.
* @param {boolean} compareDirectories - Whether to compare directory structures (default: false)
*/
-function compare(root, expectedSiteRelativePath = 'expected', siteRelativePath = '_site',
- ignoredPaths = [], compareDirectories = false) {
+function compare(root: string, expectedSiteRelativePath = 'expected', siteRelativePath = '_site',
+ ignoredPaths: string[] = [], compareDirectories = false) {
const expectedDirectory = path.join(root, expectedSiteRelativePath);
const actualDirectory = path.join(root, siteRelativePath);
@@ -113,17 +113,21 @@ function compare(root, expectedSiteRelativePath = 'expected', siteRelativePath =
continue;
}
- const expected = _readFileSync(expectedDirectory, expectedFilePath)
- .replace(CRLF_REGEX, '\n');
- const actual = _readFileSync(actualDirectory, actualFilePath)
- .replace(CRLF_REGEX, '\n');
-
- if (isBinary(null, expected)) {
+ const expectedBuf = _readFileSync(expectedDirectory, expectedFilePath);
+ if (isBinary(null, expectedBuf)) {
// eslint-disable-next-line no-console
console.warn(`Unrecognised file extension ${expectedFilePath} contains null characters, skipping`);
continue;
}
+ // Get actual string content for comparison
+ const expected = expectedBuf
+ .toString('utf8')
+ .replace(CRLF_REGEX, '\n');
+ const actual = _readFileSync(actualDirectory, actualFilePath)
+ .toString('utf8')
+ .replace(CRLF_REGEX, '\n');
+
const hasDiff = diffChars(expected, actual, expectedFilePath);
error = error || hasDiff;
}
@@ -134,6 +138,6 @@ function compare(root, expectedSiteRelativePath = 'expected', siteRelativePath =
}
}
-module.exports = {
+export {
compare,
};
diff --git a/packages/cli/test/functional/testUtil/diffChars.js b/packages/cli/test/functional/testUtil/diffChars.ts
similarity index 54%
rename from packages/cli/test/functional/testUtil/diffChars.js
rename to packages/cli/test/functional/testUtil/diffChars.ts
index 52399363a9..cf33829f6f 100644
--- a/packages/cli/test/functional/testUtil/diffChars.js
+++ b/packages/cli/test/functional/testUtil/diffChars.ts
@@ -1,5 +1,5 @@
-const jsdiff = require('diff');
-const DiffPrinter = require('./diffPrinter');
+import { ChangeObject, diffChars } from 'diff';
+import { DiffPrinter } from './diffPrinter';
/**
* Checks for any diffs between expected.html and actual.html,
@@ -9,9 +9,9 @@ const DiffPrinter = require('./diffPrinter');
* @param {string} filePathName
* @returns {boolean} if diff was found
*/
-const diffCharsAndPrint = (expected, actual, filePathName) => {
- const diffParts = jsdiff.diffChars(expected, actual);
- const isDiff = part => part.added || part.removed;
+const diffCharsAndPrint = (expected: string, actual: string, filePathName: string) => {
+ const diffParts = diffChars(expected, actual);
+ const isDiff = ((part: ChangeObject) => part.added || part.removed);
const hasDiff = diffParts.some(isDiff);
if (hasDiff) {
DiffPrinter.printDiffFoundMessage(filePathName);
@@ -20,4 +20,4 @@ const diffCharsAndPrint = (expected, actual, filePathName) => {
return hasDiff;
};
-module.exports = diffCharsAndPrint;
+export { diffCharsAndPrint };
diff --git a/packages/cli/test/functional/testUtil/diffPrinter.js b/packages/cli/test/functional/testUtil/diffPrinter.ts
similarity index 87%
rename from packages/cli/test/functional/testUtil/diffPrinter.js
rename to packages/cli/test/functional/testUtil/diffPrinter.ts
index 3cef6514ad..e7b4a9f8b8 100644
--- a/packages/cli/test/functional/testUtil/diffPrinter.js
+++ b/packages/cli/test/functional/testUtil/diffPrinter.ts
@@ -1,18 +1,26 @@
+import { ChangeObject } from 'diff';
+
const chalk = require('chalk');
const EMPTY_LINE = '|-------------------empty-line-------------------|';
const CONSECUTIVE_NEWLINE_REGEX = /\n{2,}/g;
const WHITESPACE_REGEX = /\s+/g;
+interface Printable {
+ value: string,
+ diff: boolean,
+ toPrint?: boolean
+}
+
class DiffPrinter {
/**
* Replaces all newlines except the first with EMPTY_LINE.
*/
- static prependNewLines(match) {
+ static prependNewLines(match: string) {
return `\n${match.replace('\n', '').split('\n').join(`${EMPTY_LINE}\n`)}`;
}
- static formatNewLines(value, prevVal, nextVal) {
+ static formatNewLines(value: string, prevVal: string, nextVal: string) {
let printValue;
printValue = value.replace(CONSECUTIVE_NEWLINE_REGEX, this.prependNewLines);
@@ -41,8 +49,8 @@ class DiffPrinter {
* @param {Array} diffObjects array of change objects returned by jsdiff#diffWords
* @returns {Array} change objects where their value contains a single line
*/
- static generateLineParts(diffObjects) {
- const parts = [];
+ static generateLineParts(diffObjects: ChangeObject[]) {
+ const parts: Printable[] = [];
diffObjects.forEach(({ value, added, removed }, i) => {
let printValue = value;
if (added || removed) {
@@ -76,7 +84,7 @@ class DiffPrinter {
* @param {Array} lineParts array of line objects after being split
* into lines by DiffPrinter#generateLineParts
*/
- static setPartsToPrint(lineParts) {
+ static setPartsToPrint(lineParts: Printable[]) {
lineParts.forEach((linePart, i) => {
if (linePart.diff) {
for (let j = -3; j <= 3; j += 1) {
@@ -87,7 +95,7 @@ class DiffPrinter {
});
}
- static printDiffFoundMessage(filePath) {
+ static printDiffFoundMessage(filePath: string) {
const message = chalk.grey(`\n-------------------------------------\nDiff found in ${filePath}\n\n`);
process.stderr.write(message);
}
@@ -98,7 +106,7 @@ class DiffPrinter {
* @param {Array} lineParts array of line objects after being set for printing
* in DiffPrinter#setPartsToPrint
*/
- static printLineParts(lineParts) {
+ static printLineParts(lineParts: Printable[]) {
lineParts.forEach((linePart, i) => {
const prevPart = lineParts[i - 1];
if (linePart.toPrint) {
@@ -114,11 +122,11 @@ class DiffPrinter {
* Prints diff with ANSI Escape Codes for colour
* @param {Array} parts array of change of objects as returned by jsdiff#diffWords
*/
- static printDiff(parts) {
+ static printDiff(parts: ChangeObject[]) {
const lineParts = this.generateLineParts(parts);
this.setPartsToPrint(lineParts);
this.printLineParts(lineParts);
}
}
-module.exports = DiffPrinter;
+export { DiffPrinter };
diff --git a/packages/cli/test/functional/updatetest.js b/packages/cli/test/functional/updatetest.ts
similarity index 65%
rename from packages/cli/test/functional/updatetest.js
rename to packages/cli/test/functional/updatetest.ts
index 5494da16fd..ec31b07dcd 100644
--- a/packages/cli/test/functional/updatetest.js
+++ b/packages/cli/test/functional/updatetest.ts
@@ -1,26 +1,28 @@
-const path = require('path');
-const fs = require('fs-extra');
-const { execSync } = require('child_process');
+import path from 'path';
+import fs from 'fs-extra';
+import { execSync } from 'child_process';
+import isError from 'lodash/isError';
+import { ExecSyncOptions } from 'node:child_process';
+import { cleanupConvert } from './testUtil/cleanup';
-const { cleanupConvert } = require('./testUtil/cleanup');
-
-const {
+import {
testSites,
testConvertSites,
testTemplateSites,
-} = require('./testSites');
+} from './testSites';
-/* eslint-disable no-console */
+const _ = { isError };
-function printFailedMessage(err, siteName) {
+/* eslint-disable no-console */
+function printFailedMessage(err: string, siteName: string) {
console.log(err);
console.log(`Failed to update: ${siteName}`);
}
-process.env.TEST_MODE = true;
+process.env.TEST_MODE = String(true);
process.env.FORCE_COLOR = '3';
-const execOptions = {
+const execOptions: ExecSyncOptions = {
stdio: ['inherit', 'inherit', 'inherit'],
};
@@ -29,7 +31,11 @@ testSites.forEach((siteName) => {
try {
execSync(`node ../../index.js build ${siteName} ${siteName}/expected`, execOptions);
} catch (err) {
- printFailedMessage(err, siteName);
+ if (_.isError(err)) {
+ printFailedMessage(err.message, siteName);
+ } else {
+ console.error(`Unknown error occurred ${err} for site ${siteName}`);
+ }
process.exit(1);
}
});
@@ -42,7 +48,11 @@ testConvertSites.forEach((siteName) => {
execSync(`node ../../index.js init ${nonMarkBindSitePath} -c`, execOptions);
execSync(`node ../../index.js build ${nonMarkBindSitePath} ${expectedOutputDirectory}`, execOptions);
} catch (err) {
- printFailedMessage(err, siteName);
+ if (_.isError(err)) {
+ printFailedMessage(err.message, siteName);
+ } else {
+ console.error(`Unknown error occurred ${err} for site ${siteName}`);
+ }
cleanupConvert(path.resolve(__dirname, siteName));
process.exit(1);
}
@@ -60,7 +70,11 @@ testTemplateSites.forEach((templateAndSitePath) => {
execSync(`node ../../index.js init ${siteCreationTempPath} --template ${flag}`, execOptions);
execSync(`node ../../index.js build ${siteCreationTempPath} ${expectedOutputDirectory}`, execOptions);
} catch (err) {
- printFailedMessage(err, sitePath);
+ if (_.isError(err)) {
+ printFailedMessage(err.message, sitePath);
+ } else {
+ console.error(`Unknown error occurred ${err} for site ${sitePath}`);
+ }
fs.removeSync(path.resolve(__dirname, siteCreationTempPath));
process.exit(1);
}
diff --git a/packages/cli/test/unit/cliUtil.test.js b/packages/cli/test/unit/cliUtil.test.ts
similarity index 98%
rename from packages/cli/test/unit/cliUtil.test.js
rename to packages/cli/test/unit/cliUtil.test.ts
index 1c85a49735..1d4a4c8bf7 100644
--- a/packages/cli/test/unit/cliUtil.test.js
+++ b/packages/cli/test/unit/cliUtil.test.ts
@@ -2,7 +2,7 @@ const fs = require('fs');
const path = require('path');
const { SITE_JSON_DEFAULT } = require('@markbind/core/test/unit/utils/data');
-const cliUtil = require('../../src/util/cliUtil');
+const cliUtil = require('../../dist/src/util/cliUtil');
jest.mock('fs');
jest.mock('process');
diff --git a/packages/cli/test/unit/ipUtil.test.js b/packages/cli/test/unit/ipUtil.test.ts
similarity index 96%
rename from packages/cli/test/unit/ipUtil.test.js
rename to packages/cli/test/unit/ipUtil.test.ts
index 50a7b34137..50f2c9ce3a 100644
--- a/packages/cli/test/unit/ipUtil.test.js
+++ b/packages/cli/test/unit/ipUtil.test.ts
@@ -1,4 +1,4 @@
-const { isValidServeHost, isIPAddressZero } = require('../../src/util/ipUtil');
+const { isValidServeHost, isIPAddressZero } = require('../../dist/src/util/ipUtil');
describe('isValidServeHost', () => {
test('returns true for localhost', () => {
diff --git a/packages/cli/tsconfig.json b/packages/cli/tsconfig.json
new file mode 100644
index 0000000000..f7d8fe5e15
--- /dev/null
+++ b/packages/cli/tsconfig.json
@@ -0,0 +1,11 @@
+{
+ "extends": "../../tsconfig_base.json",
+ "exclude": ["node_modules", "**/*.test.ts", "dist", "**/*.test.js", "test/**/*.js", "**/__mocks__", "coverage"],
+ "references": [
+ { "path": "../core/tsconfig.json" }
+ ],
+ "compilerOptions": {
+ "outDir": "./dist",
+ "allowJs": true,
+ }
+}
diff --git a/packages/core/tsconfig.json b/packages/core/tsconfig.json
index 77ea88399b..c34078c7eb 100644
--- a/packages/core/tsconfig.json
+++ b/packages/core/tsconfig.json
@@ -1,4 +1,7 @@
{
"extends": "../../tsconfig_base.json",
- "exclude": ["node_modules", "**/*.test.ts"]
+ "exclude": ["node_modules", "**/*.test.ts"],
+ "compilerOptions": {
+ "composite": true,
+ },
}
diff --git a/tsconfig.json b/tsconfig.json
index de8717f81b..dd96e2de98 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,4 +1,10 @@
{
"extends": "./tsconfig_base.json",
- "exclude": ["**/node_modules", "**/*.test.ts"]
+ "exclude": ["**/node_modules", "**/*.test.ts"],
+ // Prevent just `tsc` from building files - always use `tsc --build`
+ "files": [],
+ "references": [
+ { "path": "./packages/cli/tsconfig.json" },
+ { "path": "./packages/core/tsconfig.json" }
+ ]
}
diff --git a/tsconfig_base.json b/tsconfig_base.json
index 89b7e27cfd..18609eaf77 100644
--- a/tsconfig_base.json
+++ b/tsconfig_base.json
@@ -10,6 +10,7 @@
"declarationMap": true,
"forceConsistentCasingInFileNames": true,
"newLine": "lf",
- "skipLibCheck": true
+ "skipLibCheck": true,
+ "resolveJsonModule": true
}
}