@tsparticles/cli 3.3.0 → 3.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/.github/dependabot.yml +7 -0
  2. package/.planning/codebase/ARCHITECTURE.md +132 -3
  3. package/.planning/codebase/CONCERNS.md +105 -3
  4. package/.planning/codebase/CONVENTIONS.md +91 -3
  5. package/.planning/codebase/INTEGRATIONS.md +82 -3
  6. package/.planning/codebase/STACK.md +88 -8
  7. package/.planning/codebase/STRUCTURE.md +138 -3
  8. package/.planning/codebase/TESTING.md +156 -3
  9. package/dist/build/build-distfiles.js +14 -13
  10. package/dist/build/build-diststats.js +8 -7
  11. package/dist/build/build-prettier.d.ts +2 -2
  12. package/dist/build/build-prettier.js +26 -25
  13. package/dist/build/build-tsc.js +4 -3
  14. package/dist/build/build.js +10 -8
  15. package/dist/cli.js +3 -3
  16. package/dist/create/plugin/create-plugin.js +4 -3
  17. package/dist/create/preset/create-preset.js +4 -3
  18. package/dist/create/shape/create-shape.js +4 -3
  19. package/dist/tsconfig.tsbuildinfo +1 -1
  20. package/dist/utils/file-utils.js +7 -6
  21. package/dist/utils/template-utils.js +4 -3
  22. package/files/empty-project/package.json +7 -7
  23. package/files/empty-project/webpack.config.js +11 -11
  24. package/package.json +9 -11
  25. package/renovate.json +3 -0
  26. package/src/build/build-distfiles.ts +15 -14
  27. package/src/build/build-diststats.ts +8 -8
  28. package/src/build/build-prettier.ts +25 -26
  29. package/src/build/build-tsc.ts +4 -3
  30. package/src/build/build.ts +10 -10
  31. package/src/cli.ts +3 -3
  32. package/src/create/plugin/create-plugin.ts +4 -3
  33. package/src/create/preset/create-preset.ts +4 -3
  34. package/src/create/shape/create-shape.ts +4 -3
  35. package/src/utils/file-utils.ts +7 -6
  36. package/src/utils/template-utils.ts +4 -3
  37. package/tests/create-plugin.test.ts +25 -25
  38. package/tests/create-preset.test.ts +25 -25
  39. package/tests/create-shape.test.ts +25 -25
  40. package/tests/file-utils.test.ts +87 -78
  41. package/tests/tsconfig.json +12 -11
  42. package/tsconfig.json +52 -53
@@ -1,3 +1,156 @@
1
- Testing
2
- - Vitest configuration present
3
- - Run with pnpm test
1
+ # Testing Patterns
2
+
3
+ **Analysis Date:** 2026-03-10
4
+
5
+ ## Test Framework
6
+
7
+ Runner:
8
+
9
+ - Vitest (see `package.json` devDependencies `vitest` and `vitest.config.ts`).
10
+ - Config file: `vitest.config.ts` (sets `globals: true`, `environment: "node"`, `include: ["tests/**/*.test.ts"]`).
11
+
12
+ Run Commands:
13
+
14
+ ```bash
15
+ pnpm test # Runs: `vitest run` (non-watch)
16
+ pnpm run test # Alias to the same command
17
+ ```
18
+
19
+ ## Test File Organization
20
+
21
+ Location:
22
+
23
+ - Tests live in the `tests/` directory at project root.
24
+ - Files: `tests/create-shape.test.ts`, `tests/create-preset.test.ts`, `tests/create-plugin.test.ts`, `tests/file-utils.test.ts`, `tests/string-utils.test.ts`.
25
+ - Pattern: tests are colocated under a top-level `tests/` folder rather than next to source files.
26
+
27
+ Naming:
28
+
29
+ - Pattern: `*.test.ts` suffix for test files (see `vitest.config.ts` include pattern).
30
+
31
+ Structure:
32
+
33
+ ```
34
+ tests/
35
+ ├── <feature>.test.ts # top-level test file for a single module/feature
36
+ ```
37
+
38
+ ## Test Structure and Patterns
39
+
40
+ Suite Organization:
41
+
42
+ - Tests use `describe` blocks to group scenarios and `it` for assertions (Vitest globals enabled). Example: `tests/file-utils.test.ts`.
43
+
44
+ Setup / Teardown:
45
+
46
+ - Tests frequently perform async setup at the top-level of `describe` by awaiting operations before `it` blocks. Example: in `tests/file-utils.test.ts` the `baseDir` is created with `await fs.ensureDir(baseDir)` before assertions.
47
+ - Teardown uses `afterAll` to remove temporary test artifacts. Example: `afterAll(async () => { await fs.remove(baseDir); });` in `tests/file-utils.test.ts`.
48
+
49
+ Assertions:
50
+
51
+ - Vitest's `expect` is used with matchers like `toBe`.
52
+
53
+ Async Tests:
54
+
55
+ - Most IO-heavy tests are `async` and use `await`. Pattern:
56
+
57
+ ```typescript
58
+ it("does something async", async () => {
59
+ const result = await someAsyncFunction();
60
+ expect(result).toBe(...);
61
+ });
62
+ ```
63
+
64
+ Error Testing Pattern:
65
+
66
+ - When verifying exceptions, tests use try/catch with a boolean flag and assert the flag at the end. Example in `tests/file-utils.test.ts`:
67
+
68
+ ```typescript
69
+ let ex = false;
70
+ try {
71
+ await getDestinationDir(path.join("tmp-files", "baz"));
72
+ } catch {
73
+ ex = true;
74
+ }
75
+ expect(ex).toBe(true);
76
+ ```
77
+
78
+ Prefer using `await expect(...).rejects.toThrow()` for clearer intent when adding tests.
79
+
80
+ ## Mocking
81
+
82
+ Framework:
83
+
84
+ - No mocking libraries observed; tests perform filesystem operations against a temporary directory (`tests/tmp-files`) and rely on actual `fs-extra` operations.
85
+
86
+ Patterns:
87
+
88
+ - Tests use real file operations (create files, write content, call functions under test, assert file contents). Example: `tests/file-utils.test.ts` writes files into `tmp-files` and later reads them.
89
+
90
+ What to mock / not to mock:
91
+
92
+ - Current tests intentionally avoid mocking to validate filesystem interactions. Continue to avoid mocking for these utilities unless external network/long-running processes are involved (e.g., `exec` calls in `template-utils.ts` could be mocked if tests should not run `npm install` or `npm run build`).
93
+
94
+ ## Fixtures and Factories
95
+
96
+ Test Data:
97
+
98
+ - Tests create temporary files under `tests/tmp-files` using `fs-extra`. Example: `tests/create-shape.test.ts` writes to `tests/tmp-files/foo-shape` and later removes it.
99
+
100
+ Location:
101
+
102
+ - Temporary test artifacts are written under `tests/tmp-files/` and removed by test code or CI before/after runs (CI workflow runs `rm -rf tests/tmp-files`). See `.github/workflows/node.js-ci.yml`.
103
+
104
+ ## Coverage
105
+
106
+ Coverage tool: Not enforced in repo (no explicit coverage script), but `.nyc_output` directory exists suggesting past use of NYC. No CI step collects coverage.
107
+
108
+ To run coverage (suggested): add a script using `vitest run --coverage` and configure thresholds in `package.json` if required.
109
+
110
+ ## Test Types
111
+
112
+ Unit Tests:
113
+
114
+ - Scope: small, deterministic units that interact with filesystem helpers and template generation functions. Examples: `tests/string-utils.test.ts`, `tests/file-utils.test.ts`.
115
+
116
+ Integration-ish Tests:
117
+
118
+ - Scope: template creation tests (`tests/create-*.test.ts`) copy files and run `runInstall`/`runBuild` indirectly; these can execute `npm` commands if present (templating functions call `runInstall` and `runBuild` which execute `npm` if `lookpath('npm')` returns true). These tests currently run in CI where `pnpm install` is executed and `npm` may be present.
119
+
120
+ E2E Tests:
121
+
122
+ - Not used.
123
+
124
+ ## Common Patterns and Recommendations
125
+
126
+ 1. Use `afterAll` to clean up filesystem artifacts (example: `tests/file-utils.test.ts` removes `baseDir`).
127
+ 2. Prefer `await expect(promise).rejects.toThrow()` for negative tests instead of boolean-flag try/catch pattern.
128
+ 3. Keep filesystem-based tests under `tests/tmp-files` and ensure CI cleans them before runs (CI step already removes `tests/tmp-files`). See `.github/workflows/node.js-ci.yml` lines 44-46 and 84-86.
129
+ 4. If tests should avoid running `npm install`/`npm run build` during template creation, add a test flag or mock `lookpath`/`exec` in `src/utils/template-utils.ts` to bypass `runInstall`/`runBuild` during tests.
130
+
131
+ ## Example Test Template (observed pattern)
132
+
133
+ ```typescript
134
+ import { describe, it, expect } from "vitest";
135
+ import fs from "fs-extra";
136
+ import path from "node:path";
137
+ import { someFunction } from "../src/utils/some.ts";
138
+
139
+ describe("someFunction", () => {
140
+ it("behaves correctly", async () => {
141
+ const dest = path.join(__dirname, "tmp-files", "some");
142
+ await fs.ensureDir(dest);
143
+
144
+ await someFunction(dest);
145
+
146
+ const data = await fs.readFile(path.join(dest, "file.txt"), "utf8");
147
+ expect(data).toBe("expected");
148
+
149
+ await fs.remove(dest);
150
+ });
151
+ });
152
+ ```
153
+
154
+ ---
155
+
156
+ _Testing analysis: 2026-03-10_
@@ -1,4 +1,5 @@
1
- import fs from "fs-extra";
1
+ import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
2
3
  import klaw from "klaw";
3
4
  import path from "node:path";
4
5
  /**
@@ -12,7 +13,7 @@ export async function buildDistFiles(basePath, silent) {
12
13
  }
13
14
  let res;
14
15
  try {
15
- const pkgInfo = JSON.parse((await fs.readFile(path.join(basePath, "package.json"))).toString()), libPackage = path.join(basePath, "package.dist.json"), distPath = path.join(basePath, pkgInfo.publishConfig?.directory ?? "dist"), data = await fs.readFile(libPackage), text = data.toString(), libObj = JSON.parse(text);
16
+ const pkgInfo = JSON.parse((await readFile(path.join(basePath, "package.json"))).toString()), libPackage = path.join(basePath, "package.dist.json"), distPath = path.join(basePath, pkgInfo.publishConfig?.directory ?? "dist"), data = await readFile(libPackage), text = data.toString(), libObj = JSON.parse(text);
16
17
  libObj["version"] = pkgInfo.version;
17
18
  if (pkgInfo.dependencies) {
18
19
  libObj["dependencies"] = JSON.parse(JSON.stringify(pkgInfo.dependencies).replaceAll("workspace:", ""));
@@ -21,7 +22,7 @@ export async function buildDistFiles(basePath, silent) {
21
22
  libObj["peerDependencies"] = JSON.parse(JSON.stringify(pkgInfo.peerDependencies).replaceAll("workspace:", ""));
22
23
  }
23
24
  const jsonIndent = 2;
24
- await fs.writeFile(libPackage, `${JSON.stringify(libObj, undefined, jsonIndent)}\n`, "utf8");
25
+ await writeFile(libPackage, `${JSON.stringify(libObj, undefined, jsonIndent)}\n`, "utf8");
25
26
  if (!silent) {
26
27
  console.log(`package.dist.json updated successfully to version ${pkgInfo.version}`);
27
28
  }
@@ -35,22 +36,22 @@ export async function buildDistFiles(basePath, silent) {
35
36
  ];
36
37
  for (const file of rootFilesToCopy) {
37
38
  const src = path.join(basePath, typeof file === "string" ? file : file.source), dest = path.join(distPath, typeof file === "string" ? file : file.destination);
38
- await fs.copyFile(src, dest);
39
+ await copyFile(src, dest);
39
40
  }
40
41
  const scriptsPath = path.join(basePath, "scripts"), distScriptsPath = path.join(distPath, "scripts");
41
- if ((await fs.exists(scriptsPath)) && !(await fs.exists(distScriptsPath))) {
42
- await fs.mkdir(distScriptsPath);
42
+ if (existsSync(scriptsPath) && !existsSync(distScriptsPath)) {
43
+ await mkdir(distScriptsPath);
43
44
  const installPath = path.join(scriptsPath, "install.js");
44
- if (await fs.exists(installPath)) {
45
- await fs.copyFile(installPath, path.join(distScriptsPath, "install.js"));
45
+ if (existsSync(installPath)) {
46
+ await copyFile(installPath, path.join(distScriptsPath, "install.js"));
46
47
  }
47
48
  }
48
49
  for await (const file of klaw(distPath)) {
49
50
  if (file.stats.isDirectory()) {
50
51
  continue;
51
52
  }
52
- const contents = await fs.readFile(file.path, "utf8");
53
- await fs.writeFile(file.path, contents.replaceAll("__VERSION__", `"${pkgInfo.version}"`), "utf8");
53
+ const contents = await readFile(file.path, "utf8");
54
+ await writeFile(file.path, contents.replaceAll("__VERSION__", `"${pkgInfo.version}"`), "utf8");
54
55
  }
55
56
  /* for await (const file of klaw(path.join(distPath, "cjs"))) {
56
57
  await fs.rename(file.path, file.path.replace(/\.js$/, ".cjs"));
@@ -59,9 +60,9 @@ export async function buildDistFiles(basePath, silent) {
59
60
  for await (const file of klaw(path.join(distPath, "esm"))) {
60
61
  await fs.rename(file.path, file.path.replace(/\.js$/, ".mjs"));
61
62
  } */
62
- await fs.writeFile(path.join(distPath, "cjs", "package.json"), `{ "type": "commonjs" }`);
63
- await fs.writeFile(path.join(distPath, "esm", "package.json"), `{ "type": "module" }`);
64
- await fs.writeFile(path.join(distPath, "browser", "package.json"), `{ "type": "module" }`);
63
+ await writeFile(path.join(distPath, "cjs", "package.json"), `{ "type": "commonjs" }`);
64
+ await writeFile(path.join(distPath, "esm", "package.json"), `{ "type": "module" }`);
65
+ await writeFile(path.join(distPath, "browser", "package.json"), `{ "type": "module" }`);
65
66
  res = true;
66
67
  }
67
68
  catch (e) {
@@ -1,4 +1,5 @@
1
- import fs from "fs-extra";
1
+ import { opendir, readFile, stat } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
2
3
  /**
3
4
  * @param folderPath - the path to the folder to get the stats for
4
5
  * @param bundlePath - the bundle path to get the bundle size for
@@ -11,10 +12,10 @@ async function getFolderStats(folderPath, bundlePath) {
11
12
  totalFolders: 0,
12
13
  totalSize: 0,
13
14
  };
14
- if (!(await fs.pathExists(folderPath))) {
15
+ if (!existsSync(folderPath)) {
15
16
  return stats;
16
17
  }
17
- const dir = await fs.promises.opendir(folderPath), path = await import("path");
18
+ const dir = await opendir(folderPath), path = await import("path");
18
19
  for await (const dirent of dir) {
19
20
  const increment = 1;
20
21
  if (dirent.isDirectory()) {
@@ -24,7 +25,7 @@ async function getFolderStats(folderPath, bundlePath) {
24
25
  stats.totalSize += subDirStats.totalSize;
25
26
  }
26
27
  else {
27
- const fileStats = await fs.stat(path.join(folderPath, dirent.name));
28
+ const fileStats = await stat(path.join(folderPath, dirent.name));
28
29
  stats.totalFiles++;
29
30
  stats.totalSize += fileStats.size;
30
31
  if (bundlePath && path.join(folderPath, dirent.name) === bundlePath) {
@@ -40,8 +41,8 @@ async function getFolderStats(folderPath, bundlePath) {
40
41
  * @returns the stats for the dist folder
41
42
  */
42
43
  export async function getDistStats(basePath) {
43
- const path = await import("path"), distFolder = path.join(basePath, "dist"), pkgInfo = (await fs.exists(path.join(distFolder, "package.json")))
44
- ? JSON.parse((await fs.readFile(path.join(distFolder, "package.json"))).toString())
45
- : {}, bundlePath = (await fs.exists(distFolder)) && pkgInfo.jsdelivr ? path.join(distFolder, pkgInfo.jsdelivr) : undefined;
44
+ const path = await import("path"), distFolder = path.join(basePath, "dist"), pkgInfo = existsSync(path.join(distFolder, "package.json"))
45
+ ? JSON.parse((await readFile(path.join(distFolder, "package.json"))).toString())
46
+ : {}, bundlePath = existsSync(distFolder) && pkgInfo.jsdelivr ? path.join(distFolder, pkgInfo.jsdelivr) : undefined;
46
47
  return await getFolderStats(distFolder, bundlePath);
47
48
  }
@@ -15,11 +15,11 @@ export declare function prettifySrc(basePath: string, srcPath: string, ci: boole
15
15
  export declare function prettifyPackageJson(basePath: string, ci: boolean, silent: boolean): Promise<boolean>;
16
16
  /**
17
17
  * @param basePath -
18
- * @param _ci -
18
+ * @param ci -
19
19
  * @param silent -
20
20
  * @returns true if the prettify package.dist.json process was successful
21
21
  */
22
- export declare function prettifyPackageDistJson(basePath: string, _ci: boolean, silent: boolean): Promise<boolean>;
22
+ export declare function prettifyPackageDistJson(basePath: string, ci: boolean, silent: boolean): Promise<boolean>;
23
23
  /**
24
24
  * @param basePath -
25
25
  * @param ci -
@@ -1,4 +1,5 @@
1
- import fs from "fs-extra";
1
+ import { readFile, writeFile } from "node:fs/promises";
2
+ import { existsSync } from "node:fs";
2
3
  import klaw from "klaw";
3
4
  import path from "node:path";
4
5
  import prettier from "prettier";
@@ -19,7 +20,7 @@ export async function prettifySrc(basePath, srcPath, ci, silent) {
19
20
  if (file.stats.isDirectory()) {
20
21
  continue;
21
22
  }
22
- const contents = await fs.readFile(file.path, "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
23
+ const contents = await readFile(file.path, "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
23
24
  options.printWidth = 120;
24
25
  options.endOfLine = "lf";
25
26
  options.parser = "typescript";
@@ -32,7 +33,7 @@ export async function prettifySrc(basePath, srcPath, ci, silent) {
32
33
  }
33
34
  else {
34
35
  const formatted = await prettier.format(contents, options);
35
- await fs.writeFile(file.path, formatted, "utf8");
36
+ await writeFile(file.path, formatted, "utf8");
36
37
  }
37
38
  }
38
39
  res = true;
@@ -58,7 +59,7 @@ export async function prettifyPackageJson(basePath, ci, silent) {
58
59
  }
59
60
  let res;
60
61
  try {
61
- const contents = await fs.readFile("package.json", "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
62
+ const contents = await readFile("package.json", "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
62
63
  options.tabWidth = 2;
63
64
  options.printWidth = 120;
64
65
  options.endOfLine = "lf";
@@ -70,7 +71,7 @@ export async function prettifyPackageJson(basePath, ci, silent) {
70
71
  }
71
72
  else {
72
73
  const formatted = await prettier.format(contents, options);
73
- await fs.writeFile("package.json", formatted, "utf8");
74
+ await writeFile("package.json", formatted, "utf8");
74
75
  }
75
76
  res = true;
76
77
  }
@@ -85,30 +86,30 @@ export async function prettifyPackageJson(basePath, ci, silent) {
85
86
  }
86
87
  /**
87
88
  * @param basePath -
88
- * @param _ci -
89
+ * @param ci -
89
90
  * @param silent -
90
91
  * @returns true if the prettify package.dist.json process was successful
91
92
  */
92
- export async function prettifyPackageDistJson(basePath, _ci, silent) {
93
+ export async function prettifyPackageDistJson(basePath, ci, silent) {
93
94
  if (!silent) {
94
95
  console.log("Prettier - started on package.dist.json");
95
96
  }
96
97
  let res;
97
98
  try {
98
- const contents = await fs.readFile("package.dist.json", "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
99
+ const contents = await readFile("package.dist.json", "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
99
100
  options.tabWidth = 2;
100
101
  options.printWidth = 120;
101
102
  options.endOfLine = "lf";
102
103
  options.parser = "json";
103
- // TODO: disabled this check until "prettier-plugin-multiline-arrays" package is compatible with Prettier 3.0.0
104
- /* if (ci) {
105
- if (!(await prettier.check(contents, options))) {
106
- throw new Error(`package.dist.json is not formatted correctly`);
107
- }
108
- } else { */
109
- const formatted = await prettier.format(contents, options);
110
- await fs.writeFile("package.dist.json", formatted, "utf8");
111
- // }
104
+ if (ci) {
105
+ if (!(await prettier.check(contents, options))) {
106
+ throw new Error(`package.dist.json is not formatted correctly`);
107
+ }
108
+ }
109
+ else {
110
+ const formatted = await prettier.format(contents, options);
111
+ await writeFile("package.dist.json", formatted, "utf8");
112
+ }
112
113
  res = true;
113
114
  }
114
115
  catch (e) {
@@ -132,7 +133,7 @@ export async function prettifyReadme(basePath, ci, silent) {
132
133
  }
133
134
  let res;
134
135
  try {
135
- const contents = await fs.readFile("README.md", "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
136
+ const contents = await readFile("README.md", "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
136
137
  options.printWidth = 120;
137
138
  options.endOfLine = "lf";
138
139
  options.parser = "markdown";
@@ -143,7 +144,7 @@ export async function prettifyReadme(basePath, ci, silent) {
143
144
  }
144
145
  else {
145
146
  const formatted = await prettier.format(contents, options);
146
- await fs.writeFile("README.md", formatted, "utf8");
147
+ await writeFile("README.md", formatted, "utf8");
147
148
  }
148
149
  res =
149
150
  (await prettifyTraductions(basePath, ci, silent)) && (await prettifyMarkdownTypeDocFiles(basePath, ci, silent));
@@ -170,7 +171,7 @@ async function prettifyTraductions(basePath, ci, silent) {
170
171
  let res = false;
171
172
  try {
172
173
  const folder = "traduction", folderPath = path.join(basePath, folder);
173
- if (!fs.existsSync(folderPath)) {
174
+ if (!existsSync(folderPath)) {
174
175
  res = true;
175
176
  }
176
177
  if (!res) {
@@ -178,7 +179,7 @@ async function prettifyTraductions(basePath, ci, silent) {
178
179
  if (file.stats.isDirectory()) {
179
180
  continue;
180
181
  }
181
- const contents = await fs.readFile(file.path, "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
182
+ const contents = await readFile(file.path, "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
182
183
  options.printWidth = 120;
183
184
  options.endOfLine = "lf";
184
185
  options.parser = "markdown";
@@ -189,7 +190,7 @@ async function prettifyTraductions(basePath, ci, silent) {
189
190
  }
190
191
  else {
191
192
  const formatted = await prettier.format(contents, options);
192
- await fs.writeFile(file.path, formatted, "utf8");
193
+ await writeFile(file.path, formatted, "utf8");
193
194
  }
194
195
  }
195
196
  res = true;
@@ -217,7 +218,7 @@ async function prettifyMarkdownTypeDocFiles(basePath, ci, silent) {
217
218
  let res = false;
218
219
  try {
219
220
  const folder = "markdown", folderPath = path.join(basePath, folder);
220
- if (!fs.existsSync(folderPath)) {
221
+ if (!existsSync(folderPath)) {
221
222
  res = true;
222
223
  }
223
224
  if (!res) {
@@ -225,7 +226,7 @@ async function prettifyMarkdownTypeDocFiles(basePath, ci, silent) {
225
226
  if (file.stats.isDirectory()) {
226
227
  continue;
227
228
  }
228
- const contents = await fs.readFile(file.path, "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
229
+ const contents = await readFile(file.path, "utf8"), options = (await prettier.resolveConfig(basePath)) ?? {};
229
230
  options.printWidth = 120;
230
231
  options.endOfLine = "lf";
231
232
  options.parser = "markdown";
@@ -236,7 +237,7 @@ async function prettifyMarkdownTypeDocFiles(basePath, ci, silent) {
236
237
  }
237
238
  else {
238
239
  const formatted = await prettier.format(contents, options);
239
- await fs.writeFile(file.path, formatted, "utf8");
240
+ await writeFile(file.path, formatted, "utf8");
240
241
  }
241
242
  }
242
243
  res = true;
@@ -1,5 +1,6 @@
1
- import fs from "fs-extra";
1
+ import { existsSync } from "node:fs";
2
2
  import path from "node:path";
3
+ import { readFile } from "node:fs/promises";
3
4
  var ExitCodes;
4
5
  (function (ExitCodes) {
5
6
  ExitCodes[ExitCodes["OK"] = 0] = "OK";
@@ -15,8 +16,8 @@ var ExitCodes;
15
16
  */
16
17
  async function readConfig(basePath, file) {
17
18
  const tsconfigPath = path.join(basePath, file);
18
- if (await fs.pathExists(tsconfigPath)) {
19
- const data = await fs.readFile(path.join(basePath, file));
19
+ if (existsSync(tsconfigPath)) {
20
+ const data = await readFile(path.join(basePath, file));
20
21
  return data.toString();
21
22
  }
22
23
  return undefined;
@@ -1,4 +1,6 @@
1
1
  import { Command } from "commander";
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
2
4
  const buildCommand = new Command("build");
3
5
  buildCommand.description("Build the tsParticles library using TypeScript");
4
6
  buildCommand.option("-a, --all", "Do all build steps (default if no flags are specified) (same as -b -c -d -l -p -t)", false);
@@ -19,8 +21,8 @@ buildCommand.action(async (argPath) => {
19
21
  const { clearDist } = await import("./build-clear.js");
20
22
  await clearDist(basePath, silent);
21
23
  }
22
- const path = await import("path"), srcPath = path.join(basePath, argPath), fs = await import("fs-extra");
23
- if (!(await fs.pathExists(srcPath))) {
24
+ const srcPath = path.join(basePath, argPath);
25
+ if (!existsSync(srcPath)) {
24
26
  throw new Error("Provided path does not exist");
25
27
  }
26
28
  let canContinue = true;
@@ -63,12 +65,12 @@ buildCommand.action(async (argPath) => {
63
65
  const newStats = await getDistStats(basePath), diffSize = newStats.totalSize - oldStats.totalSize, bundleDiffSize = newStats.bundleSize - oldStats.bundleSize, minSize = 0, bundleSizeIncreased = bundleDiffSize > minSize, bundleSizeIncreasedText = bundleSizeIncreased ? "increased" : "decreased", diffSizeIncreasedText = diffSize > minSize ? "increased" : "decreased";
64
66
  outputFunc = bundleSizeIncreased ? console.warn : console.info;
65
67
  texts = [
66
- !bundleDiffSize
67
- ? "Bundle size unchanged"
68
- : `Bundle size ${bundleSizeIncreasedText} from ${oldStats.bundleSize.toString()} to ${newStats.bundleSize.toString()} (${Math.abs(bundleDiffSize).toString()}B)`,
69
- !diffSize
70
- ? "Size unchanged"
71
- : `Size ${diffSizeIncreasedText} from ${oldStats.totalSize.toString()} to ${newStats.totalSize.toString()} (${Math.abs(diffSize).toString()}B)`,
68
+ bundleDiffSize
69
+ ? `Bundle size ${bundleSizeIncreasedText} from ${oldStats.bundleSize.toString()} to ${newStats.bundleSize.toString()} (${Math.abs(bundleDiffSize).toString()}B)`
70
+ : "Bundle size unchanged",
71
+ diffSize
72
+ ? `Size ${diffSizeIncreasedText} from ${oldStats.totalSize.toString()} to ${newStats.totalSize.toString()} (${Math.abs(diffSize).toString()}B)`
73
+ : "Size unchanged",
72
74
  `Files count changed from ${oldStats.totalFiles.toString()} to ${newStats.totalFiles.toString()} (${(newStats.totalFiles - oldStats.totalFiles).toString()})`,
73
75
  `Folders count changed from ${oldStats.totalFolders.toString()} to ${newStats.totalFolders.toString()} (${(newStats.totalFolders - oldStats.totalFolders).toString()})`,
74
76
  ];
package/dist/cli.js CHANGED
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
2
  import { buildCommand } from "./build/build.js";
3
3
  import { createCommand } from "./create/create.js";
4
- import { fileURLToPath } from "url";
5
- import fs from "fs-extra";
4
+ import { fileURLToPath } from "node:url";
6
5
  import path from "node:path";
7
6
  import { program } from "commander";
8
- const __filename = fileURLToPath(import.meta.url), __dirname = path.dirname(__filename), rootPkgPath = path.join(__dirname, "..", "package.json"), pkg = (await fs.readJson(rootPkgPath));
7
+ import { readFile } from "node:fs/promises";
8
+ const __filename = fileURLToPath(import.meta.url), __dirname = path.dirname(__filename), rootPkgPath = path.join(__dirname, "..", "package.json"), pkg = JSON.parse(await readFile(rootPkgPath, "utf-8"));
9
9
  program.name("tsparticles-cli");
10
10
  program.description("tsParticles CLI");
11
11
  program.version(pkg.version, "-v, --version", "output the current version");
@@ -1,6 +1,6 @@
1
1
  import { camelize, capitalize, dash } from "../../utils/string-utils.js";
2
2
  import { copyEmptyTemplateFiles, copyFilter, runBuild, runInstall, updatePackageDistFile, updatePackageFile, updateWebpackFile, } from "../../utils/template-utils.js";
3
- import fs from "fs-extra";
3
+ import { cp } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { replaceTokensInFile } from "../../utils/file-utils.js";
6
6
  /**
@@ -110,8 +110,9 @@ async function updatePluginWebpackFile(destPath, name, description) {
110
110
  export async function createPluginTemplate(name, description, repoUrl, destPath) {
111
111
  const sourcePath = path.join(__dirname, "..", "..", "..", "files", "create-plugin");
112
112
  await copyEmptyTemplateFiles(destPath);
113
- await fs.copy(sourcePath, destPath, {
114
- overwrite: true,
113
+ await cp(sourcePath, destPath, {
114
+ recursive: true,
115
+ force: true,
115
116
  filter: copyFilter,
116
117
  });
117
118
  await updateIndexFile(destPath, name);
@@ -1,6 +1,6 @@
1
1
  import { camelize, capitalize, dash } from "../../utils/string-utils.js";
2
2
  import { copyEmptyTemplateFiles, copyFilter, runBuild, runInstall, updatePackageDistFile, updatePackageFile, updateWebpackFile, } from "../../utils/template-utils.js";
3
- import fs from "fs-extra";
3
+ import { cp } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { replaceTokensInFile } from "../../utils/file-utils.js";
6
6
  /**
@@ -127,8 +127,9 @@ async function updatePresetWebpackFile(destPath, name, description) {
127
127
  export async function createPresetTemplate(name, description, repoUrl, destPath) {
128
128
  const sourcePath = path.join(__dirname, "..", "..", "..", "files", "create-preset");
129
129
  await copyEmptyTemplateFiles(destPath);
130
- await fs.copy(sourcePath, destPath, {
131
- overwrite: true,
130
+ await cp(sourcePath, destPath, {
131
+ recursive: true,
132
+ force: true,
132
133
  filter: copyFilter,
133
134
  });
134
135
  await updateBundleFile(destPath, name);
@@ -1,6 +1,6 @@
1
1
  import { camelize, capitalize, dash } from "../../utils/string-utils.js";
2
2
  import { copyEmptyTemplateFiles, copyFilter, runBuild, runInstall, updatePackageDistFile, updatePackageFile, updateWebpackFile, } from "../../utils/template-utils.js";
3
- import fs from "fs-extra";
3
+ import { cp } from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { replaceTokensInFile } from "../../utils/file-utils.js";
6
6
  /**
@@ -115,8 +115,9 @@ async function updateShapeWebpackFile(destPath, name, description) {
115
115
  export async function createShapeTemplate(name, description, repoUrl, destPath) {
116
116
  const sourcePath = path.join(__dirname, "..", "..", "..", "files", "create-shape");
117
117
  await copyEmptyTemplateFiles(destPath);
118
- await fs.copy(sourcePath, destPath, {
119
- overwrite: true,
118
+ await cp(sourcePath, destPath, {
119
+ recursive: true,
120
+ force: true,
120
121
  filter: copyFilter,
121
122
  });
122
123
  await updateIndexFile(destPath, name);