@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.
- package/.github/dependabot.yml +7 -0
- package/.planning/codebase/ARCHITECTURE.md +132 -3
- package/.planning/codebase/CONCERNS.md +105 -3
- package/.planning/codebase/CONVENTIONS.md +91 -3
- package/.planning/codebase/INTEGRATIONS.md +82 -3
- package/.planning/codebase/STACK.md +88 -8
- package/.planning/codebase/STRUCTURE.md +138 -3
- package/.planning/codebase/TESTING.md +156 -3
- package/dist/build/build-distfiles.js +14 -13
- package/dist/build/build-diststats.js +8 -7
- package/dist/build/build-prettier.d.ts +2 -2
- package/dist/build/build-prettier.js +26 -25
- package/dist/build/build-tsc.js +4 -3
- package/dist/build/build.js +10 -8
- package/dist/cli.js +3 -3
- package/dist/create/plugin/create-plugin.js +4 -3
- package/dist/create/preset/create-preset.js +4 -3
- package/dist/create/shape/create-shape.js +4 -3
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/utils/file-utils.js +7 -6
- package/dist/utils/template-utils.js +4 -3
- package/files/empty-project/package.json +7 -7
- package/files/empty-project/webpack.config.js +11 -11
- package/package.json +9 -11
- package/renovate.json +3 -0
- package/src/build/build-distfiles.ts +15 -14
- package/src/build/build-diststats.ts +8 -8
- package/src/build/build-prettier.ts +25 -26
- package/src/build/build-tsc.ts +4 -3
- package/src/build/build.ts +10 -10
- package/src/cli.ts +3 -3
- package/src/create/plugin/create-plugin.ts +4 -3
- package/src/create/preset/create-preset.ts +4 -3
- package/src/create/shape/create-shape.ts +4 -3
- package/src/utils/file-utils.ts +7 -6
- package/src/utils/template-utils.ts +4 -3
- package/tests/create-plugin.test.ts +25 -25
- package/tests/create-preset.test.ts +25 -25
- package/tests/create-shape.test.ts +25 -25
- package/tests/file-utils.test.ts +87 -78
- package/tests/tsconfig.json +12 -11
- package/tsconfig.json +52 -53
|
@@ -1,3 +1,156 @@
|
|
|
1
|
-
Testing
|
|
2
|
-
|
|
3
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
39
|
+
await copyFile(src, dest);
|
|
39
40
|
}
|
|
40
41
|
const scriptsPath = path.join(basePath, "scripts"), distScriptsPath = path.join(distPath, "scripts");
|
|
41
|
-
if ((
|
|
42
|
-
await
|
|
42
|
+
if (existsSync(scriptsPath) && !existsSync(distScriptsPath)) {
|
|
43
|
+
await mkdir(distScriptsPath);
|
|
43
44
|
const installPath = path.join(scriptsPath, "install.js");
|
|
44
|
-
if (
|
|
45
|
-
await
|
|
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
|
|
53
|
-
await
|
|
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
|
|
63
|
-
await
|
|
64
|
-
await
|
|
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
|
|
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 (!(
|
|
15
|
+
if (!existsSync(folderPath)) {
|
|
15
16
|
return stats;
|
|
16
17
|
}
|
|
17
|
-
const dir = await
|
|
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
|
|
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 = (
|
|
44
|
-
? JSON.parse((await
|
|
45
|
-
: {}, bundlePath = (
|
|
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
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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,
|
|
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
|
|
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
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
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 (!
|
|
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
|
|
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
|
|
240
|
+
await writeFile(file.path, formatted, "utf8");
|
|
240
241
|
}
|
|
241
242
|
}
|
|
242
243
|
res = true;
|
package/dist/build/build-tsc.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import
|
|
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 (
|
|
19
|
-
const data = await
|
|
19
|
+
if (existsSync(tsconfigPath)) {
|
|
20
|
+
const data = await readFile(path.join(basePath, file));
|
|
20
21
|
return data.toString();
|
|
21
22
|
}
|
|
22
23
|
return undefined;
|
package/dist/build/build.js
CHANGED
|
@@ -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
|
|
23
|
-
if (!(
|
|
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
|
-
|
|
67
|
-
?
|
|
68
|
-
:
|
|
69
|
-
|
|
70
|
-
?
|
|
71
|
-
:
|
|
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
|
-
|
|
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
|
|
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
|
|
114
|
-
|
|
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
|
|
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
|
|
131
|
-
|
|
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
|
|
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
|
|
119
|
-
|
|
118
|
+
await cp(sourcePath, destPath, {
|
|
119
|
+
recursive: true,
|
|
120
|
+
force: true,
|
|
120
121
|
filter: copyFilter,
|
|
121
122
|
});
|
|
122
123
|
await updateIndexFile(destPath, name);
|