@tsparticles/cli 2.0.5 → 2.2.0

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.
@@ -35,7 +35,7 @@ jobs:
35
35
  run: |
36
36
  echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
37
37
 
38
- - uses: actions/cache@v3
38
+ - uses: actions/cache@v4
39
39
  name: Setup pnpm cache
40
40
  with:
41
41
  path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
@@ -73,7 +73,7 @@ jobs:
73
73
  run: |
74
74
  echo "::set-output name=pnpm_cache_dir::$(pnpm store path)"
75
75
 
76
- - uses: actions/cache@v3
76
+ - uses: actions/cache@v4
77
77
  name: Setup pnpm cache
78
78
  with:
79
79
  path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.buildCircularDeps = void 0;
7
+ const madge_1 = __importDefault(require("madge"));
8
+ const path_1 = __importDefault(require("path"));
9
+ /**
10
+ *
11
+ * @param basePath -
12
+ * @returns true if no circular dependencies are found, false otherwise
13
+ */
14
+ async function buildCircularDeps(basePath) {
15
+ let res = false;
16
+ try {
17
+ const madgeRes = await (0, madge_1.default)(path_1.default.join(basePath, "src"), {
18
+ fileExtensions: ["ts"],
19
+ detectiveOptions: {
20
+ skipTypeImports: true,
21
+ },
22
+ }), circularDeps = madgeRes.circular();
23
+ if (circularDeps.length) {
24
+ throw new Error(`Circular dependencies found: ${circularDeps.join(", ")}`);
25
+ }
26
+ res = true;
27
+ }
28
+ catch (e) {
29
+ console.error(e);
30
+ }
31
+ console.log("Finished checking circular dependencies.");
32
+ return res;
33
+ }
34
+ exports.buildCircularDeps = buildCircularDeps;
@@ -32,13 +32,14 @@ buildCommand.option("-a, --all", "Do all build steps (default if no flags are sp
32
32
  buildCommand.option("-b, --bundle", "Bundle the library using Webpack", false);
33
33
  buildCommand.option("-c, --clean", "Clean the dist folder", false);
34
34
  buildCommand.option("--ci", "Do all build steps for CI, no fixing files, only checking if they are formatted correctly", false);
35
+ buildCommand.option("-cd, --circular-deps", "Check for circular dependencies", false);
35
36
  buildCommand.option("-d, --dist", "Build the dist files", false);
36
37
  buildCommand.option("-l, --lint", "Lint the source files", false);
37
38
  buildCommand.option("-p, --prettify", "Prettify the source files", false);
38
39
  buildCommand.option("-t, --tsc", "Build the library using TypeScript", false);
39
40
  buildCommand.argument("[path]", `Path to the project root folder, default is "src"`, "src");
40
41
  buildCommand.action(async (argPath) => {
41
- const opts = buildCommand.opts(), ci = !!opts.ci, all = !!opts.all || (!opts.bundle && !opts.clean && !opts.dist && !opts.lint && !opts.prettify && !opts.tsc), doBundle = all || !!opts.bundle, clean = all || !!opts.clean, distfiles = all || !!opts.dist, doLint = all || !!opts.lint, prettier = all || !!opts.prettify, tsc = all || !!opts.tsc;
42
+ const opts = buildCommand.opts(), ci = !!opts.ci, all = !!opts.all || (!opts.bundle && !opts.clean && !opts.dist && !opts.lint && !opts.prettify && !opts.tsc), doBundle = all || !!opts.bundle, circularDeps = all || !!opts.circularDeps, clean = all || !!opts.clean, distfiles = all || !!opts.dist, doLint = all || !!opts.lint, prettier = all || !!opts.prettify, tsc = all || !!opts.tsc;
42
43
  const basePath = process.cwd(), { getDistStats } = await Promise.resolve().then(() => __importStar(require("./build-diststats.js"))), oldStats = await getDistStats(basePath);
43
44
  if (clean) {
44
45
  const { clearDist } = await Promise.resolve().then(() => __importStar(require("./build-clear.js")));
@@ -61,6 +62,10 @@ buildCommand.action(async (argPath) => {
61
62
  const { buildTS } = await Promise.resolve().then(() => __importStar(require("./build-tsc.js")));
62
63
  canContinue = await buildTS(basePath);
63
64
  }
65
+ if (canContinue && circularDeps) {
66
+ const { buildCircularDeps } = await Promise.resolve().then(() => __importStar(require("./build-circular-deps.js")));
67
+ canContinue = await buildCircularDeps(basePath);
68
+ }
64
69
  if (canContinue && doBundle) {
65
70
  const { bundle } = await Promise.resolve().then(() => __importStar(require("./build-bundle.js")));
66
71
  canContinue = await bundle(basePath);
@@ -1,41 +1,10 @@
1
- import type { Container, Engine, IPlugin, ISourceOptions, Options } from "@tsparticles/engine";
2
- import { PluginInstance } from "./PluginInstance";
3
-
4
- /**
5
- */
6
- class Plugin implements IPlugin {
7
- readonly id;
8
-
9
- private readonly _engine;
10
-
11
- constructor(engine: Engine) {
12
- this.id = "#template#";
13
-
14
- this._engine = engine;
15
- }
16
-
17
- getPlugin(container: Container): PluginInstance {
18
- return new PluginInstance(container, this._engine);
19
- }
20
-
21
- loadOptions(_options: Options, _source?: ISourceOptions): void {
22
- if (!this.needsPlugin()) {
23
- // ignore plugin options when not needed
24
-
25
- return;
26
- }
27
-
28
- // Load your options here
29
- }
30
-
31
- needsPlugin(_options?: ISourceOptions): boolean {
32
- return true; // add your condition here, replace true with condition if needed
33
- }
34
- }
1
+ import type { Engine } from "@tsparticles/engine";
35
2
 
36
3
  /**
37
4
  * @param engine - The engine instance
38
5
  */
39
6
  export async function loadTemplatePlugin(engine: Engine): Promise<void> {
7
+ const { Plugin } = await import("./plugin.js");
8
+
40
9
  await engine.addPlugin(new Plugin(engine));
41
10
  }
@@ -0,0 +1,36 @@
1
+ import { type Container, type Engine, type IPlugin, type ISourceOptions, type Options } from "@tsparticles/engine";
2
+ import type { PluginInstance } from "./PluginInstance.js";
3
+
4
+ /**
5
+ */
6
+ export class Plugin implements IPlugin {
7
+ readonly id;
8
+
9
+ private readonly _engine;
10
+
11
+ constructor(engine: Engine) {
12
+ this.id = "#template#";
13
+
14
+ this._engine = engine;
15
+ }
16
+
17
+ async getPlugin(container: Container): Promise<PluginInstance> {
18
+ const { PluginInstance } = await import("./PluginInstance.js");
19
+
20
+ return new PluginInstance(container, this._engine);
21
+ }
22
+
23
+ loadOptions(_options: Options, _source?: ISourceOptions): void {
24
+ if (!this.needsPlugin()) {
25
+ // ignore plugin options when not needed
26
+
27
+ return;
28
+ }
29
+
30
+ // Load your options here
31
+ }
32
+
33
+ needsPlugin(_options?: ISourceOptions): boolean {
34
+ return true; // add your condition here, replace true with condition if needed
35
+ }
36
+ }
@@ -1,11 +1,12 @@
1
1
  import type { Engine } from "@tsparticles/engine";
2
- import { options } from "./options";
3
2
 
4
3
  /**
5
4
  *
6
5
  * @param engine - the engine instance to load the preset into
7
6
  */
8
7
  export async function loadTemplatePreset(engine: Engine): Promise<void> {
8
+ const { options } = await import("./options");
9
+
9
10
  // TODO: additional modules must be loaded here
10
11
 
11
12
  // Adds the preset to the engine, with the given options
@@ -1,7 +1,7 @@
1
1
  import type { IShapeDrawData, IShapeDrawer } from "@tsparticles/engine";
2
2
 
3
3
  export class ShapeDrawer implements IShapeDrawer {
4
- draw(_data: IShapeDrawData): void {
4
+ async draw(_data: IShapeDrawData): Promise<void> {
5
5
  // draw the particle using the context
6
6
  // which is already centered in the particle position
7
7
  // colors are already handled, just draw the shape
@@ -10,5 +10,8 @@ export class ShapeDrawer implements IShapeDrawer {
10
10
  // pixelRatio is the canvas ratio used by the tsParticles instance, you may need it for density-independent shapes
11
11
  // the parameters have an underscore prefix because they're not used in this example
12
12
  // the underscore prefix can be removed for used parameters, the unused ones can be removed too
13
+
14
+ // remove this if there's already an await call
15
+ await Promise.resolve();
13
16
  }
14
17
  }
@@ -1,9 +1,10 @@
1
1
  import type { Engine } from "@tsparticles/engine";
2
- import { ShapeDrawer } from "./ShapeDrawer";
3
2
 
4
3
  /**
5
4
  * @param engine - the engine instance to load the shape into
6
5
  */
7
6
  export async function loadTemplateShape(engine: Engine): Promise<void> {
7
+ const { ShapeDrawer } = await import("./ShapeDrawer");
8
+
8
9
  await engine.addShape("#template#", new ShapeDrawer());
9
10
  }
@@ -83,14 +83,14 @@
83
83
  "prettier": "@tsparticles/prettier-config",
84
84
  "devDependencies": {
85
85
  "@babel/core": "^7.23.9",
86
- "@tsparticles/cli": "^2.0.5",
87
- "@tsparticles/eslint-config": "^2.1.0",
86
+ "@tsparticles/cli": "^2.2.0",
87
+ "@tsparticles/eslint-config": "^2.1.4",
88
88
  "@tsparticles/prettier-config": "^2.1.0",
89
89
  "@tsparticles/tsconfig": "^2.0.1",
90
- "@tsparticles/webpack-plugin": "^2.1.0",
90
+ "@tsparticles/webpack-plugin": "^2.1.4",
91
91
  "@types/webpack-env": "^1.18.4",
92
- "@typescript-eslint/eslint-plugin": "^6.19.1",
93
- "@typescript-eslint/parser": "^6.19.1",
92
+ "@typescript-eslint/eslint-plugin": "^6.20.0",
93
+ "@typescript-eslint/parser": "^6.20.0",
94
94
  "babel-loader": "^9.1.3",
95
95
  "browserslist": "^4.22.3",
96
96
  "copyfiles": "^2.4.1",
@@ -105,6 +105,6 @@
105
105
  "webpack-cli": "^5.1.4"
106
106
  },
107
107
  "dependencies": {
108
- "@tsparticles/engine": "^3.0.3"
108
+ "@tsparticles/engine": "^3.2.0"
109
109
  }
110
110
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tsparticles/cli",
3
- "version": "2.0.5",
3
+ "version": "2.2.0",
4
4
  "license": "MIT",
5
5
  "bin": {
6
6
  "tsparticles-cli": "dist/cli.js"
@@ -10,12 +10,12 @@
10
10
  },
11
11
  "prettier": "@tsparticles/prettier-config",
12
12
  "dependencies": {
13
- "@tsparticles/eslint-config": "^2.1.0",
13
+ "@tsparticles/eslint-config": "^2.1.4",
14
14
  "@tsparticles/prettier-config": "^2.1.0",
15
15
  "@tsparticles/tsconfig": "^2.0.1",
16
- "@tsparticles/webpack-plugin": "^2.1.0",
17
- "@typescript-eslint/eslint-plugin": "^6.19.1",
18
- "@typescript-eslint/parser": "^6.19.1",
16
+ "@tsparticles/webpack-plugin": "^2.1.4",
17
+ "@typescript-eslint/eslint-plugin": "^6.20.0",
18
+ "@typescript-eslint/parser": "^6.20.0",
19
19
  "commander": "^11.1.0",
20
20
  "eslint": "^8.56.0",
21
21
  "eslint-config-prettier": "^9.1.0",
@@ -24,6 +24,7 @@
24
24
  "fs-extra": "^11.2.0",
25
25
  "klaw": "^4.1.0",
26
26
  "lookpath": "^1.2.2",
27
+ "madge": "^6.1.0",
27
28
  "path-scurry": "^1.10.1",
28
29
  "prettier": "^3.2.4",
29
30
  "prettier-plugin-multiline-arrays": "^3.0.1",
@@ -36,8 +37,9 @@
36
37
  "@types/chai": "^4.3.11",
37
38
  "@types/fs-extra": "^11.0.4",
38
39
  "@types/klaw": "^3.0.6",
40
+ "@types/madge": "^5.0.3",
39
41
  "@types/mocha": "^10.0.6",
40
- "@types/node": "^20.11.9",
42
+ "@types/node": "^20.11.13",
41
43
  "@types/prompts": "^2.4.9",
42
44
  "chai": "^4.4.0",
43
45
  "cross-env": "^7.0.3",
@@ -55,12 +57,13 @@
55
57
  "prettify:readme": "prettier --write ./README.md",
56
58
  "lint": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
57
59
  "lint:ci": "eslint src --ext .js,.jsx,.ts,.tsx",
60
+ "circular-deps": "madge --circular --extensions ts src",
58
61
  "compile": "pnpm run build:ts",
59
62
  "compile:ci": "pnpm run build:ts",
60
63
  "build:ts": "pnpm run build:ts:cjs",
61
64
  "build:ts:cjs": "tsc -p src",
62
65
  "test": "cross-env TS_NODE_PROJECT='./tests/tsconfig.json' nyc mocha --timeout 300000",
63
- "build": "pnpm run clear:dist && pnpm run prettify:src && pnpm run lint && pnpm run compile && pnpm run prettify:readme && chmod +x dist/cli.js && chmod +x dist/build/build.js && chmod +x dist/create/create.js && chmod +x dist/create/preset/preset.js",
66
+ "build": "pnpm run clear:dist && pnpm run prettify:src && pnpm run lint && pnpm run compile && pnpm run circular-deps && pnpm run prettify:readme && chmod +x dist/cli.js && chmod +x dist/build/build.js && chmod +x dist/create/create.js && chmod +x dist/create/preset/preset.js",
64
67
  "build:ci": "pnpm run clear:dist && pnpm run prettify:ci:src && pnpm run lint:ci && pnpm run compile && pnpm run prettify:ci:readme",
65
68
  "clear:dist": "rimraf ./dist",
66
69
  "version": "node scripts/postversion.js && git add files/empty-project/package.json"
@@ -0,0 +1,33 @@
1
+ import madge from "madge";
2
+ import path from "path";
3
+
4
+ /**
5
+ *
6
+ * @param basePath -
7
+ * @returns true if no circular dependencies are found, false otherwise
8
+ */
9
+ export async function buildCircularDeps(basePath: string): Promise<boolean> {
10
+ let res = false;
11
+
12
+ try {
13
+ const madgeRes = await madge(path.join(basePath, "src"), {
14
+ fileExtensions: ["ts"],
15
+ detectiveOptions: {
16
+ skipTypeImports: true,
17
+ },
18
+ }),
19
+ circularDeps = madgeRes.circular();
20
+
21
+ if (circularDeps.length) {
22
+ throw new Error(`Circular dependencies found: ${circularDeps.join(", ")}`);
23
+ }
24
+
25
+ res = true;
26
+ } catch (e) {
27
+ console.error(e);
28
+ }
29
+
30
+ console.log("Finished checking circular dependencies.");
31
+
32
+ return res;
33
+ }
@@ -15,6 +15,7 @@ buildCommand.option(
15
15
  "Do all build steps for CI, no fixing files, only checking if they are formatted correctly",
16
16
  false,
17
17
  );
18
+ buildCommand.option("-cd, --circular-deps", "Check for circular dependencies", false);
18
19
  buildCommand.option("-d, --dist", "Build the dist files", false);
19
20
  buildCommand.option("-l, --lint", "Lint the source files", false);
20
21
  buildCommand.option("-p, --prettify", "Prettify the source files", false);
@@ -26,6 +27,7 @@ buildCommand.action(async (argPath: string) => {
26
27
  ci = !!opts.ci,
27
28
  all = !!opts.all || (!opts.bundle && !opts.clean && !opts.dist && !opts.lint && !opts.prettify && !opts.tsc),
28
29
  doBundle = all || !!opts.bundle,
30
+ circularDeps = all || !!opts.circularDeps,
29
31
  clean = all || !!opts.clean,
30
32
  distfiles = all || !!opts.dist,
31
33
  doLint = all || !!opts.lint,
@@ -70,6 +72,12 @@ buildCommand.action(async (argPath: string) => {
70
72
  canContinue = await buildTS(basePath);
71
73
  }
72
74
 
75
+ if (canContinue && circularDeps) {
76
+ const { buildCircularDeps } = await import("./build-circular-deps.js");
77
+
78
+ canContinue = await buildCircularDeps(basePath);
79
+ }
80
+
73
81
  if (canContinue && doBundle) {
74
82
  const { bundle } = await import("./build-bundle.js");
75
83