Skip to content

Dev#121

Merged
matteobruni merged 87 commits intomainfrom
dev
Feb 24, 2026
Merged

Dev#121
matteobruni merged 87 commits intomainfrom
dev

Conversation

@matteobruni
Copy link
Contributor

@matteobruni matteobruni commented Feb 24, 2026

Summary by CodeRabbit

Release Notes

  • New Features

    • Added automated npm package publishing workflow with pre-release tag support.
    • Introduced dependency configuration management tool.
  • Chores

    • Upgraded build system from Babel to SWC for faster JavaScript transpilation.
    • Enhanced CI/CD pipeline with Nx Cloud integration and improved caching.
    • Transitioned build commands from Lerna to Nx for better monorepo management.
    • Updated core dependencies: ESLint, TypeScript, Prettier, and related tooling.
    • Enabled stricter TypeScript compiler checks across all packages.
    • Released version 3.1.8.

matteobruni and others added 30 commits December 28, 2025 13:57
chore(deps): update dependency @types/node to v25.0.8
…62.x

fix(deps): update dependency eslint-plugin-jsdoc to v62
chore(deps): update actions/checkout action to v6
chore(deps): update actions/cache action to v5
chore(deps): update actions/setup-node action to v6
…orepo

chore(deps): update dependency @stylistic/eslint-plugin to v5.7.0
chore(deps): update dependency node to v24
chore(deps): update babel monorepo to v7.28.6
…norepo

chore(deps): update dependency typescript-eslint to v8.53.0
@nx-cloud
Copy link

nx-cloud bot commented Feb 24, 2026

View your CI Pipeline Execution ↗ for commit c2d6bec

Command Status Duration Result
nx affected -t build:ci ✅ Succeeded <1s View ↗

☁️ Nx Cloud last updated this comment at 2026-02-24 09:55:15 UTC

@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

Warning

Rate limit exceeded

@matteobruni has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 21 minutes and 17 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between ad0ed3e and c2d6bec.

📒 Files selected for processing (1)
  • .github/workflows/node.js-ci.yml
📝 Walkthrough

Walkthrough

Comprehensive monorepo update introducing Nx Cloud integration, CI workflow restructuring with new npm-publish automation, Babel-to-SWC migration in webpack-config, new depcruise-config package, ESLint config refactoring, stricter TypeScript compilation options, and version bump to 3.1.8 across multiple packages.

Changes

Cohort / File(s) Summary
CI/Workflows
.github/workflows/node.js-ci.yml, .github/workflows/npm-publish.yml
Node.js CI refactored for Nx Cloud distributed execution and dynamic ref handling; new npm-publish workflow added for automated package publishing on version tags with pre-release support for alpha/beta.
Root Configuration
lerna.json, nx.json, package.json, pnpm-workspace.yaml
Nx Cloud integration added to nx.json with target dependencies and task runners; lerna updated with forcePublish and conventionalCommits flags; package.json swapped build commands to Nx; pnpm workspace restricted to onlyBuiltDependencies.
Depcruise Config Package (New)
packages/depcruise-config/*
New configuration package introduced with dependency-cruiser rules, loader module, configuration export, and comprehensive build setup including tsconfig, tsup, and package manifest.
ESLint Config
packages/eslint-config/src/eslint.config.ts, packages/eslint-config/package.json, packages/eslint-config/CHANGELOG.md
ESLint config refactored from tseslint.config to defineConfig pattern with expanded TypeScript rules, stricter type checking, and updated tooling (jiti added, ts-eslint bumped); scripts updated to use custom ESLint config path.
Prettier & TSConfig Updates
packages/prettier-config/*, packages/tsconfig/*
Prettier config tab width reduced to 2, main entry moved to dist/; tsconfig stricter options enabled (noImplicitAny, noUnusedLocals, moduleResolution NodeNext); versions bumped to 3.1.8.
Webpack Config Migration
packages/webpack-config/src/common/getConfig.ts, packages/webpack-config/.babelrc, packages/webpack-config/package.json
Babel-to-SWC loader migration with updated regex for ES modules; minification switched to TerserPlugin.swcMinify; browserlist baseline updated from 2019 to 2021; devDependencies swapped babel packages for swc/core and swc-loader.
Webpack Config Build Files (Formatting)
packages/webpack-config/src/.../*.ts (20\+ files)
Formatting and indentation adjustments across bundle, effect, engine, interaction, move, path, plugin, preset, shape, template, updater, and export build files; banner strings expanded with MIT license lines; control flow and logic preserved.
Changelogs & Documentation
CHANGELOG.md, packages/*/CHANGELOG.md (5 files)
Version 3.1.8 entries added with version bump notes; existing entries preserved.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Updated deps #49 — Overlapping root-level manifest and CI configuration changes, including devDependencies, scripts, and Nx/lerna version management.
  • 3.0.6 #87 — Webpack-config package source modifications affecting loader, build file structure, and tooling configuration.

Suggested labels

size/XL

Poem

🐰 Hopping through workflows with newfound grace,
SWC replaces Babel's pace,
Depcruise joined the crew so bright,
Stricter types and configs right,
Nx Cloud racing through the night!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Dev' is vague and generic, failing to convey any meaningful information about the changeset's primary objectives or main modifications. Consider renaming the title to be more descriptive of the main changes, such as 'Upgrade CI workflows and tooling stack' or 'Migrate to SWC and update monorepo configuration' to better communicate the changeset's purpose.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/webpack-config/package.json (1)

16-17: ⚠️ Potential issue | 🟡 Minor

Update lint scripts to use flat config properly instead of --ext flag.

The --ext flag is not recommended for ESLint 9 flat config. While --ext was reintroduced in ESLint 9.21.0 for CLI-only linting, the proper flat config approach is to define file patterns in eslint.config.js. Since webpack-config already has a flat config in place, the scripts should rely on that configuration instead.

Suggested fix
-    "lint": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
-    "lint:ci": "eslint src --ext .js,.jsx,.ts,.tsx",
+    "lint": "eslint src --fix",
+    "lint:ci": "eslint src",

Verify that eslint.config.js includes explicit file patterns (e.g., files: ["**/*.{js,jsx,ts,tsx}"]) to ensure the linting targets the intended file types.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/package.json` around lines 16 - 17, The lint scripts
in package.json ("lint" and "lint:ci") still use the deprecated --ext flag;
remove the --ext usage and have the scripts rely on the existing flat config
(e.g., change the commands to call eslint without --ext or let them target the
src dir only). Ensure eslint.config.js contains a files pattern like files:
["**/*.{js,jsx,ts,tsx}"] so ESLint flat config determines which files to lint
and the package scripts simply invoke eslint (with --fix for "lint" and without
for "lint:ci").
🧹 Nitpick comments (19)
packages/webpack-config/src/shapes/buildShape.ts (2)

30-30: Use ES6 shorthand property for minBanner.

minBanner: minBanner is redundant when the key and variable name match.

♻️ Proposed refactor
-    minBanner: minBanner,
+    minBanner,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/shapes/buildShape.ts` at line 30, Replace the
redundant object property assignment "minBanner: minBanner" with the ES6
shorthand "minBanner" in the build shape object (look for the object literal
that defines minBanner in buildShape.ts); update the property inside the object
where minBanner is currently mapped to itself so the key uses the shorthand
form.

17-24: Consider splitting the comma-chained const into separate declarations.

Declaring multiple bindings in a single const with comma separators is non-idiomatic TypeScript and especially hard to read when one of the values is a multi-line template literal. Separate const statements are cleaner and easier to maintain.

♻️ Proposed refactor
-  const { moduleName, shapeName, version, dir, additionalExternals } = params,
-    banner = `Author : Matteo Bruni
+  const { moduleName, shapeName, version, dir, additionalExternals } = params;
+  const banner = `Author : Matteo Bruni
 MIT license: https://opensource.org/licenses/MIT
 Demo / Generator : https://particles.js.org/
 GitHub : https://www.github.com/matteobruni/tsparticles
 How to use? : Check the GitHub README
-v${version}`,
-    minBanner = `tsParticles ${shapeName} Shape v${version} by Matteo Bruni`;
+v${version}`;
+  const minBanner = `tsParticles ${shapeName} Shape v${version} by Matteo Bruni`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/shapes/buildShape.ts` around lines 17 - 24, The
current comma-chained const declaration that extracts params and defines
banner/minBanner (symbols: params, moduleName, shapeName, version, dir,
additionalExternals, banner, minBanner) is hard to read because it mixes
destructions with multi-line template literals; refactor by splitting into
separate const statements: one const for the destructured params ({ moduleName,
shapeName, version, dir, additionalExternals }) and then individual const
declarations for banner and minBanner, preserving the same template literals and
values.
packages/webpack-config/src/paths/buildPath.ts (2)

34-34: Use ES shorthand property for minBanner.

♻️ Proposed refactor
-    minBanner: minBanner,
+    minBanner,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/paths/buildPath.ts` at line 34, The object
literal currently uses the verbose property assignment "minBanner: minBanner";
replace it with the ES shorthand property by using just "minBanner" in the
object where this appears (look for the object containing minBanner in
buildPath.ts) so the property name and variable are merged into the short form.

17-24: Consider splitting the chained const declaration.

Comma-chaining three independent bindings under a single const is syntactically valid but non-idiomatic and reduces readability; separate declarations are clearer.

♻️ Proposed refactor
-  const { moduleName, pluginName, version, dir, additionalExternals } = params,
-    banner = `Author : Matteo Bruni
+  const { moduleName, pluginName, version, dir, additionalExternals } = params;
+  const banner = `Author : Matteo Bruni
 MIT license: https://opensource.org/licenses/MIT
 Demo / Generator : https://particles.js.org/
 GitHub : https://www.github.com/matteobruni/tsparticles
 How to use? : Check the GitHub README
-v${version}`,
-    minBanner = `tsParticles ${pluginName} Path v${version} by Matteo Bruni`;
+v${version}`;
+  const minBanner = `tsParticles ${pluginName} Path v${version} by Matteo Bruni`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/paths/buildPath.ts` around lines 17 - 24, Split
the chained const declaration that destructures params and defines
banner/minBanner into separate, clearer declarations: first declare const {
moduleName, pluginName, version, dir, additionalExternals } = params; then
declare banner = `...v${version}` and minBanner = `...v${version}` as separate
const statements (keeping the same template strings). Update references to
banner and minBanner accordingly so moduleName, pluginName, version, dir, and
additionalExternals remain unchanged.
packages/webpack-config/src/updaters/buildUpdater.ts (2)

17-24: Consider splitting the comma-chained const into separate declarations.

Combining the destructuring, multi-line banner template literal, and minBanner in one const statement makes the declaration harder to scan than three independent const statements would be.

♻️ Proposed refactor
-  const { moduleName, updaterName, version, dir, additionalExternals } = params,
-    banner = `Author : Matteo Bruni
-MIT license: https://opensource.org/licenses/MIT
-Demo / Generator : https://particles.js.org/
-GitHub : https://www.github.com/matteobruni/tsparticles
-How to use? : Check the GitHub README
-v${version}`,
-    minBanner = `tsParticles ${updaterName} Updater v${version} by Matteo Bruni`;
+  const { moduleName, updaterName, version, dir, additionalExternals } = params;
+  const banner = `Author : Matteo Bruni
+MIT license: https://opensource.org/licenses/MIT
+Demo / Generator : https://particles.js.org/
+GitHub : https://www.github.com/matteobruni/tsparticles
+How to use? : Check the GitHub README
+v${version}`;
+  const minBanner = `tsParticles ${updaterName} Updater v${version} by Matteo Bruni`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/updaters/buildUpdater.ts` around lines 17 - 24,
Split the single comma-chained const that destructures params and defines banner
and minBanner into three separate const declarations to improve readability: one
const for the destructuring of params (moduleName, updaterName, version, dir,
additionalExternals), one const for the multi-line banner template literal, and
one const for minBanner; update any references that rely on those symbols
(banner, minBanner, moduleName, updaterName, version) accordingly in
buildUpdater.ts so behavior is unchanged but declarations are easier to scan.

30-30: minBanner: minBanner — use property shorthand for consistency.

All other properties in this object (version, banner, dir, additionalExternals) use ES shorthand. minBanner: minBanner is the only outlier.

♻️ Proposed fix
-    minBanner: minBanner,
+    minBanner,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/updaters/buildUpdater.ts` at line 30, The object
literal contains an unnecessary explicit assignment "minBanner: minBanner" while
other properties use ES6 shorthand; update the object to use property shorthand
by replacing that explicit assignment with just "minBanner" so it matches the
existing shorthand style used for version, banner, dir, and additionalExternals
(locate the object in buildUpdater.ts where those properties are defined).
packages/webpack-config/src/effects/buildEffect.ts (1)

30-30: Use ES6 property shorthand for minBanner.

♻️ Proposed refactor
-    minBanner: minBanner,
+    minBanner,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/effects/buildEffect.ts` at line 30, The object
literal in buildEffect uses the redundant longhand property "minBanner:
minBanner"; change it to ES6 property shorthand by replacing that entry with
just "minBanner" where the object or config is constructed (look for the
buildEffect function/object that defines minBanner) so the property name and
identifier are the same and the code is more concise.
packages/webpack-config/src/templates/buildTemplate.ts (2)

31-31: Use property shorthand for minBanner.

minBanner: minBanner can be simplified to minBanner in both getConfig calls (lines 31 and 40).

♻️ Proposed refactor
-      minBanner: minBanner,
+      minBanner,

Apply the same change at line 40.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/templates/buildTemplate.ts` at line 31, The
object literal passed into getConfig currently uses the long-form property
assignment "minBanner: minBanner"; change both occurrences (the two getConfig
calls in buildTemplate.ts) to use ES6 property shorthand by replacing
"minBanner: minBanner" with simply "minBanner" so the object keys are succinct
and consistent.

17-24: Consider splitting the comma-chained const declaration into separate statements.

Mixing a destructuring declarator with plain variable declarators in a single const chain is valid but less idiomatic TypeScript. Separate const statements improve readability and make it easier to add or remove individual declarations later.

♻️ Proposed refactor
-  const { moduleName, templateName, version, dir, additionalExternals } = params,
-    banner = `Author : Matteo Bruni
-MIT license: https://opensource.org/licenses/MIT
-Demo / Generator : https://particles.js.org/
-GitHub : https://www.github.com/matteobruni/tsparticles
-How to use? : Check the GitHub README
-v${version}`,
-    minBanner = `tsParticles ${templateName} Template v${version} by Matteo Bruni`;
+  const { moduleName, templateName, version, dir, additionalExternals } = params;
+  const banner = `Author : Matteo Bruni
+MIT license: https://opensource.org/licenses/MIT
+Demo / Generator : https://particles.js.org/
+GitHub : https://www.github.com/matteobruni/tsparticles
+How to use? : Check the GitHub README
+v${version}`;
+  const minBanner = `tsParticles ${templateName} Template v${version} by Matteo Bruni`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/templates/buildTemplate.ts` around lines 17 - 24,
Split the combined const declaration into separate statements for clarity: first
destructure params with "const { moduleName, templateName, version, dir,
additionalExternals } = params;" then declare the banner and minBanner in their
own consts ("const banner = `...v${version}`;" and "const minBanner =
`tsParticles ${templateName} Template v${version} by Matteo Bruni`;"). Update
any references to banner/minBanner unchanged; this improves readability in
buildTemplate.ts and makes edits to
moduleName/templateName/version/dir/additionalExternals easier.
packages/webpack-config/src/engine/buildEngine.ts (3)

30-30: Use shorthand property for minBanner.

minBanner: minBanner can be simplified to minBanner.

♻️ Proposed fix
-    minBanner: minBanner,
+    minBanner,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/engine/buildEngine.ts` at line 30, In the object
literal where minBanner is set (the property currently written as "minBanner:
minBanner"), replace the explicit key/value with the ES6 shorthand by using just
"minBanner" so the property uses the variable of the same name; this change
should be applied in buildEngine where the object contains minBanner to simplify
the code without changing behavior.

15-24: Consider splitting the comma-chained const declaration for readability.

Declaring destructuring and scalar variables in a single const via comma-chaining is valid but non-idiomatic TypeScript and increases cognitive load, especially with a multi-line template string in the middle.

♻️ Proposed refactor
-  const { additionalExternals, dir, version } = params,
-    banner = `tsParticles Engine v${version}
+  const { additionalExternals, dir, version } = params;
+  const banner = `tsParticles Engine v${version}
 Author: Matteo Bruni
 MIT license: https://opensource.org/licenses/MIT
 Website: https://particles.js.org/
 Confetti Website: https://confetti.js.org
 GitHub: https://www.github.com/matteobruni/tsparticles
 How to use?: Check the GitHub README
-------------------------------------------------------`,
-    minBanner = `tsParticles Engine v${version} by Matteo Bruni`;
+------------------------------------------------------`;
+  const minBanner = `tsParticles Engine v${version} by Matteo Bruni`;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/engine/buildEngine.ts` around lines 15 - 24,
Split the comma-chained const into separate, clearer declarations: first
destructure params into const { additionalExternals, dir, version } = params;
then declare banner and minBanner as their own const bindings (const banner =
`...` and const minBanner = `...`), preserving the same template strings and
interpolations for version; update any references to banner/minBanner or the
destructured names (additionalExternals, dir, version) accordingly in
buildEngine.ts so behavior is unchanged but readability is improved.

27-27: Add a clarifying comment distinguishing the two bundle properties.

The bundle: false at line 27 (inside entry) determines the entry point filename (index.js vs bundle.js), while the top-level bundle: false at line 32 controls which external dependencies are included in the webpack configuration. While not redundant, they serve distinct purposes, and a brief inline comment would clarify this intent for future maintainers.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/engine/buildEngine.ts` at line 27, Add an inline
comment next to the entry object (entry: { format: "engine", bundle: false })
clarifying that this bundle flag controls the entry filename (e.g., index.js vs
bundle.js), and distinguish it from the top-level bundle property in the same
webpack config (the other bundle: false) which controls inclusion/exclusion of
external dependencies in the final build; place the comment immediately beside
the entry property so future maintainers understand the two distinct meanings.
packages/webpack-config/src/common/getExternals.ts (1)

17-42: Consider splitting the comma-chained const into two separate declarations.

transformExternal and getExternals are declared in a single const statement joined by a comma, which is non-idiomatic and reduces readability/discoverability. Separating them makes each function's scope and intent immediately clear.

♻️ Suggested refactor
-const transformExternal = (external: ExternalData): unknown => {
-    return {
-      [external.name]: external.data,
-    };
-  },
-  getExternals = (params: ExternalsParams): unknown[] => {
+const transformExternal = (external: ExternalData): unknown => {
+  return {
+    [external.name]: external.data,
+  };
+};
+
+const getExternals = (params: ExternalsParams): unknown[] => {
     const { additionalExternals, bundle } = params,
       externals = additionalExternals ?? [];
     ...
   };
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/common/getExternals.ts` around lines 17 - 42, The
file currently declares transformExternal and getExternals in one
comma-separated const statement which hurts readability; split them into two
separate declarations by defining const transformExternal = (external:
ExternalData): unknown => { ... }; on its own, then define const getExternals =
(params: ExternalsParams): unknown[] => { ... }; using the same implementations
(including the bundle branch and the runtime externals function that calls
getExternalObject), remove the comma-chaining and ensure both identifiers remain
in the same module scope with identical behavior.
pnpm-workspace.yaml (1)

4-9: Consider migrating to the newer allowBuilds field, which unifies onlyBuiltDependencies and ignoredBuiltDependencies.

The current combination of ignoredBuiltDependencies and onlyBuiltDependencies is valid and functional — pnpm's own approve-builds command populates both arrays in pnpm-workspace.yaml. However, the allowBuilds field replaces onlyBuiltDependencies and ignoredBuiltDependencies, which are deprecated by this new setting, providing a single source of truth.

The equivalent allowBuilds configuration would be:

♻️ Optional migration to allowBuilds
 packages:
   - packages/*
 
-ignoredBuiltDependencies:
-  - nx
-
-onlyBuiltDependencies:
-  - '@swc/core'
-  - esbuild
+allowBuilds:
+  '@swc/core': true
+  esbuild: true
+  nx: false
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@pnpm-workspace.yaml` around lines 4 - 9, Replace the deprecated combination
of ignoredBuiltDependencies and onlyBuiltDependencies with the unified
allowBuilds field in pnpm-workspace.yaml: remove ignoredBuiltDependencies and
onlyBuiltDependencies and add a single allowBuilds mapping that includes the
same package names (e.g., '@swc/core', 'esbuild' as allowed builds and 'nx' as
ignored via the allowBuilds structure); ensure the resulting allowBuilds schema
mirrors pnpm's expected format so the previous semantics are preserved.
lerna.json (1)

4-10: conventionalCommits is duplicated.

conventionalCommits: true at the root (line 4) is already shorthand for command.version.conventionalCommits: true. The entry on line 10 is redundant and can be removed.

♻️ Proposed cleanup
     "version": {
       "message": "chore(release): published new version",
       "forcePublish": true,
-      "yes": true,
-      "conventionalCommits": true
+      "yes": true
     },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lerna.json` around lines 4 - 10, Remove the duplicate conventionalCommits key
by keeping the root-level "conventionalCommits": true and deleting the nested
"conventionalCommits" inside the "command.version" object; update the JSON so
only the root "conventionalCommits" exists and ensure "command.version.message",
"command.version.forcePublish", and "command.version.yes" remain unchanged,
referencing the "conventionalCommits" and "command.version" keys to locate the
redundant entry.
packages/webpack-config/tsconfig.json (1)

40-44: strictFunctionTypes, strictBindCallApply, and noImplicitThis are redundant with strict: true.

All three are already activated by the "strict": true flag on line 34. The meaningful additions here are noUnusedLocals, noUnusedParameters, and noImplicitReturns (lines 49–51), which are not covered by strict. Consider removing the redundant lines to reduce noise.

♻️ Proposed cleanup
         "strict": true,
         /* Enable all strict type-checking options. */
         "noImplicitAny": true,
         /* Raise error on expressions and declarations with an implied 'any' type. */
         "strictNullChecks": true,
         /* Enable strict null checks. */
-        "strictFunctionTypes": true,           /* Enable strict checking of function types. */
-        "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
         "strictPropertyInitialization": true,
         /* Enable strict checking of property initialization in classes. */
-        "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
         "alwaysStrict": true,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/tsconfig.json` around lines 40 - 44, Remove the
redundant compiler options "strictFunctionTypes", "strictBindCallApply", and
"noImplicitThis" from the tsconfig.json because they are already enabled by
"strict": true; keep and/or emphasize the explicit options that are not covered
by strict (e.g., "noUnusedLocals", "noUnusedParameters", "noImplicitReturns").
Locate the block containing the keys "strict", "strictFunctionTypes",
"strictBindCallApply", and "noImplicitThis" and delete those three specific
entries and their comments so the file is less noisy while preserving the other
explicit flags.
packages/depcruise-config/src/loadConfig.ts (1)

36-41: Avoid returning a module namespace when no default export exists.

Line 40-41 returns the module namespace as IConfiguration; for ESM configs with only named exports this will silently return { config: ... } and fail later. Consider validating shape (or throwing) to force a default export.

🔧 Suggested guard
       if (isConfigModule(mod) && mod.default) {
         return mod.default;
       }
 
-      if (isConfigModule(mod)) {
-        return mod as IConfiguration;
-      }
+      if (isConfigModule(mod)) {
+        const candidate = mod as Record<string, unknown>;
+        if ("forbidden" in candidate && "options" in candidate) {
+          return mod as IConfiguration;
+        }
+      }
+
+      throw new Error(`Invalid dependency-cruiser config module: ${fullPath}`);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/depcruise-config/src/loadConfig.ts` around lines 36 - 41, The
current loadConfig logic returns the module namespace as IConfiguration when
isConfigModule(mod) is true but no default exists, which causes ESM configs with
only named exports to silently return an incorrect shape; update the loadConfig
flow (around isConfigModule and the mod variable) to validate that mod.default
is present and is the expected configuration shape before returning, and if not
either throw a clear error instructing the consumer to provide a default export
or explicitly extract and validate a named export like config; ensure the
validation references the IConfiguration shape and the isConfigModule/mod checks
so callers never receive a module namespace masquerading as IConfiguration.
packages/eslint-config/package.json (1)

40-42: peerDependencies for ESLint is overly restrictive.

The peer dependency was narrowed from ^9.0.0 to ^9.39.3. This forces consumers to use a very recent ESLint 9 release. If the intent is to require the minimum version that supports defineConfig from "eslint/config", consider setting it to the actual minimum required version rather than pinning to the current latest.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/eslint-config/package.json` around lines 40 - 42, Summary: The
peerDependencies entry in packages/eslint-config's package.json pins ESLint to
^9.39.3 which is unnecessarily restrictive. Update the peerDependencies "eslint"
range to a looser constraint that reflects the actual minimum required version
for using defineConfig from "eslint/config" (for example change "eslint":
"^9.39.3" to "eslint": "^9.0.0" or to a semver range like ">=9.0.0 <10.0.0") so
consumers on earlier 9.x releases can use this package; edit the
peerDependencies block in package.json accordingly and run a quick install/test
to ensure compatibility.
packages/webpack-config/package.json (1)

28-53: Dev-only tools are listed under dependencies instead of devDependencies.

Packages like eslint, prettier, @types/node, rimraf, typescript, @stylistic/eslint-plugin, eslint-config-prettier, eslint-plugin-*, prettier-plugin-multiline-arrays, and @tsparticles/eslint-config/@tsparticles/prettier-config are build/lint-time tools, not runtime dependencies of a webpack plugin. Listing them under dependencies means every consumer of @tsparticles/webpack-plugin will transitively install all of these.

Only packages that consumers actually need at build time when using the plugin (e.g., webpack, webpack-cli, terser-webpack-plugin, swc-loader, @swc/core, browserslist, copyfiles, webpack-bundle-analyzer) should remain in dependencies (or be moved to peerDependencies). The rest should be devDependencies.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/package.json` around lines 28 - 53, The package.json
currently puts lint/build tools in "dependencies"; move dev-only packages into
"devDependencies" and leave only true runtime/consumer deps (or convert to
peerDependencies where appropriate). Specifically, remove eslint, prettier,
`@types/node`, rimraf, typescript, `@stylistic/eslint-plugin`,
eslint-config-prettier, eslint-plugin-import/jsdoc/tsdoc,
prettier-plugin-multiline-arrays, `@tsparticles/eslint-config`, and
`@tsparticles/prettier-config` from "dependencies" and add them to
"devDependencies"; keep/verify that webpack, webpack-cli, terser-webpack-plugin,
swc-loader, `@swc/core`, browserslist, copyfiles, and webpack-bundle-analyzer
remain in "dependencies" or move to "peerDependencies" if consumers must provide
them. Update the package.json accordingly and run npm/yarn install to regenerate
the lockfile.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lerna.json`:
- Around line 7-15: The current lerna config sets command.version.forcePublish
and command.version.yes plus command.publish.yes, which removes interactive
gates for both version and publish; update the config so local/manual runs are
safe by removing or disabling automatic confirmation and broad force publishing:
remove or set to false the "yes" flag under "command.version" and
"command.publish" and set "forcePublish" to false (or move forcePublish and any
"yes" usage behind a CI-only conditional), and ensure any automated publishes
are invoked only from CI with an explicit approval step (e.g., require a
workflow manual approval or CI-only env check before running "lerna
version"/"lerna publish").

In `@packages/depcruise-config/src/defaultConfig.ts`:
- Around line 105-155: Fix two typos in rule comments: in the
"no-duplicate-dep-types" rule comment replace "bot as" with "both as"; in the
"not-to-dev-dep" rule comment ensure the concatenated strings include a
separating space between the sentence fragments so the output reads correctly
(add a trailing or leading space to one of the adjacent string literals where
the comment is concatenated).

In `@packages/depcruise-config/tsconfig.json`:
- Around line 13-14: Add an explicit "rootDir": "./src" entry to the
tsconfig.json (next to "sourceRoot" and "sourceMap") so TypeScript does not
infer the input root from included files and to ensure consistent output layout
under "outDir"; mirror the sibling config by adding the "rootDir" key with value
"./src".

In `@packages/eslint-config/src/eslint.config.ts`:
- Around line 13-15: The config currently sets parserProject to undefined when
no tsconfig.json exists (consumerTsconfig / parserProject) but always spreads
tseslint.configs.strictTypeChecked and stylisticTypeChecked which require type
information; update eslint.config.ts to only include/spread
tseslint.configs.strictTypeChecked and tseslint.configs.stylisticTypeChecked
into the exported config when parserProject is defined (i.e.,
fs.existsSync(consumerTsconfig) true), otherwise omit those type-checked rule
sets (or alternatively throw/emit a clear error asking for a tsconfig.json) so
rules that require a `project` do not run without type info.
- Line 163: Replace the deprecated rule key "@typescript-eslint/no-var-requires"
in the ESLint config with the new "@typescript-eslint/no-require-imports" rule:
locate the rule entry where "@typescript-eslint/no-var-requires": "error" is
declared and change the rule name to "@typescript-eslint/no-require-imports"
while keeping the same severity (e.g., "error") so the behavior and config
structure remain unchanged.
- Around line 25-31: The plugins map currently registers eslint-plugin-prettier
under the nonstandard key "prettierPlugin"; remove that entry from the plugins
object (delete the "prettierPlugin" line) and rely on the existing
prettierRecommended configuration to provide the plugin and settings, or if you
intentionally need a manual registration, use the standard "prettier" key
instead; refer to the plugins object and the prettierRecommended usage to make
the change.

In `@packages/webpack-config/src/common/getExternals.ts`:
- Around line 32-39: The externals handler currently types its parameter as {
request: string } and calls request.startsWith(...) which will throw when
webpack passes undefined; change the parameter to accept an optional request
(e.g., { request?: string }) and add a guard so you only call startsWith when
request is a non-empty string (or use a single conditional like request &&
(request === "tsparticles" || request.startsWith("tsparticles-") ||
request.startsWith("@tsparticles/"))). Ensure the cb(null,
getExternalObject(request)) branch only runs when request is defined.

In `@packages/webpack-config/src/effects/buildEffect.ts`:
- Line 24: The minified banner string incorrectly uses "Shape" — update the
assignment that sets minBanner (the line creating `minBanner = \`tsParticles
${effectName} Shape v${version} by Matteo Bruni\``) to use "Effect" instead so
it reads `tsParticles ${effectName} Effect v${version} by Matteo Bruni`; locate
the minBanner variable in buildEffect.ts (inside loadParticlesEffect/related
build logic) and replace the word "Shape" with "Effect" to correct the artifact
label.

---

Outside diff comments:
In `@packages/webpack-config/package.json`:
- Around line 16-17: The lint scripts in package.json ("lint" and "lint:ci")
still use the deprecated --ext flag; remove the --ext usage and have the scripts
rely on the existing flat config (e.g., change the commands to call eslint
without --ext or let them target the src dir only). Ensure eslint.config.js
contains a files pattern like files: ["**/*.{js,jsx,ts,tsx}"] so ESLint flat
config determines which files to lint and the package scripts simply invoke
eslint (with --fix for "lint" and without for "lint:ci").

---

Nitpick comments:
In `@lerna.json`:
- Around line 4-10: Remove the duplicate conventionalCommits key by keeping the
root-level "conventionalCommits": true and deleting the nested
"conventionalCommits" inside the "command.version" object; update the JSON so
only the root "conventionalCommits" exists and ensure "command.version.message",
"command.version.forcePublish", and "command.version.yes" remain unchanged,
referencing the "conventionalCommits" and "command.version" keys to locate the
redundant entry.

In `@packages/depcruise-config/src/loadConfig.ts`:
- Around line 36-41: The current loadConfig logic returns the module namespace
as IConfiguration when isConfigModule(mod) is true but no default exists, which
causes ESM configs with only named exports to silently return an incorrect
shape; update the loadConfig flow (around isConfigModule and the mod variable)
to validate that mod.default is present and is the expected configuration shape
before returning, and if not either throw a clear error instructing the consumer
to provide a default export or explicitly extract and validate a named export
like config; ensure the validation references the IConfiguration shape and the
isConfigModule/mod checks so callers never receive a module namespace
masquerading as IConfiguration.

In `@packages/eslint-config/package.json`:
- Around line 40-42: Summary: The peerDependencies entry in
packages/eslint-config's package.json pins ESLint to ^9.39.3 which is
unnecessarily restrictive. Update the peerDependencies "eslint" range to a
looser constraint that reflects the actual minimum required version for using
defineConfig from "eslint/config" (for example change "eslint": "^9.39.3" to
"eslint": "^9.0.0" or to a semver range like ">=9.0.0 <10.0.0") so consumers on
earlier 9.x releases can use this package; edit the peerDependencies block in
package.json accordingly and run a quick install/test to ensure compatibility.

In `@packages/webpack-config/package.json`:
- Around line 28-53: The package.json currently puts lint/build tools in
"dependencies"; move dev-only packages into "devDependencies" and leave only
true runtime/consumer deps (or convert to peerDependencies where appropriate).
Specifically, remove eslint, prettier, `@types/node`, rimraf, typescript,
`@stylistic/eslint-plugin`, eslint-config-prettier,
eslint-plugin-import/jsdoc/tsdoc, prettier-plugin-multiline-arrays,
`@tsparticles/eslint-config`, and `@tsparticles/prettier-config` from "dependencies"
and add them to "devDependencies"; keep/verify that webpack, webpack-cli,
terser-webpack-plugin, swc-loader, `@swc/core`, browserslist, copyfiles, and
webpack-bundle-analyzer remain in "dependencies" or move to "peerDependencies"
if consumers must provide them. Update the package.json accordingly and run
npm/yarn install to regenerate the lockfile.

In `@packages/webpack-config/src/common/getExternals.ts`:
- Around line 17-42: The file currently declares transformExternal and
getExternals in one comma-separated const statement which hurts readability;
split them into two separate declarations by defining const transformExternal =
(external: ExternalData): unknown => { ... }; on its own, then define const
getExternals = (params: ExternalsParams): unknown[] => { ... }; using the same
implementations (including the bundle branch and the runtime externals function
that calls getExternalObject), remove the comma-chaining and ensure both
identifiers remain in the same module scope with identical behavior.

In `@packages/webpack-config/src/effects/buildEffect.ts`:
- Line 30: The object literal in buildEffect uses the redundant longhand
property "minBanner: minBanner"; change it to ES6 property shorthand by
replacing that entry with just "minBanner" where the object or config is
constructed (look for the buildEffect function/object that defines minBanner) so
the property name and identifier are the same and the code is more concise.

In `@packages/webpack-config/src/engine/buildEngine.ts`:
- Line 30: In the object literal where minBanner is set (the property currently
written as "minBanner: minBanner"), replace the explicit key/value with the ES6
shorthand by using just "minBanner" so the property uses the variable of the
same name; this change should be applied in buildEngine where the object
contains minBanner to simplify the code without changing behavior.
- Around line 15-24: Split the comma-chained const into separate, clearer
declarations: first destructure params into const { additionalExternals, dir,
version } = params; then declare banner and minBanner as their own const
bindings (const banner = `...` and const minBanner = `...`), preserving the same
template strings and interpolations for version; update any references to
banner/minBanner or the destructured names (additionalExternals, dir, version)
accordingly in buildEngine.ts so behavior is unchanged but readability is
improved.
- Line 27: Add an inline comment next to the entry object (entry: { format:
"engine", bundle: false }) clarifying that this bundle flag controls the entry
filename (e.g., index.js vs bundle.js), and distinguish it from the top-level
bundle property in the same webpack config (the other bundle: false) which
controls inclusion/exclusion of external dependencies in the final build; place
the comment immediately beside the entry property so future maintainers
understand the two distinct meanings.

In `@packages/webpack-config/src/paths/buildPath.ts`:
- Line 34: The object literal currently uses the verbose property assignment
"minBanner: minBanner"; replace it with the ES shorthand property by using just
"minBanner" in the object where this appears (look for the object containing
minBanner in buildPath.ts) so the property name and variable are merged into the
short form.
- Around line 17-24: Split the chained const declaration that destructures
params and defines banner/minBanner into separate, clearer declarations: first
declare const { moduleName, pluginName, version, dir, additionalExternals } =
params; then declare banner = `...v${version}` and minBanner = `...v${version}`
as separate const statements (keeping the same template strings). Update
references to banner and minBanner accordingly so moduleName, pluginName,
version, dir, and additionalExternals remain unchanged.

In `@packages/webpack-config/src/shapes/buildShape.ts`:
- Line 30: Replace the redundant object property assignment "minBanner:
minBanner" with the ES6 shorthand "minBanner" in the build shape object (look
for the object literal that defines minBanner in buildShape.ts); update the
property inside the object where minBanner is currently mapped to itself so the
key uses the shorthand form.
- Around line 17-24: The current comma-chained const declaration that extracts
params and defines banner/minBanner (symbols: params, moduleName, shapeName,
version, dir, additionalExternals, banner, minBanner) is hard to read because it
mixes destructions with multi-line template literals; refactor by splitting into
separate const statements: one const for the destructured params ({ moduleName,
shapeName, version, dir, additionalExternals }) and then individual const
declarations for banner and minBanner, preserving the same template literals and
values.

In `@packages/webpack-config/src/templates/buildTemplate.ts`:
- Line 31: The object literal passed into getConfig currently uses the long-form
property assignment "minBanner: minBanner"; change both occurrences (the two
getConfig calls in buildTemplate.ts) to use ES6 property shorthand by replacing
"minBanner: minBanner" with simply "minBanner" so the object keys are succinct
and consistent.
- Around line 17-24: Split the combined const declaration into separate
statements for clarity: first destructure params with "const { moduleName,
templateName, version, dir, additionalExternals } = params;" then declare the
banner and minBanner in their own consts ("const banner = `...v${version}`;" and
"const minBanner = `tsParticles ${templateName} Template v${version} by Matteo
Bruni`;"). Update any references to banner/minBanner unchanged; this improves
readability in buildTemplate.ts and makes edits to
moduleName/templateName/version/dir/additionalExternals easier.

In `@packages/webpack-config/src/updaters/buildUpdater.ts`:
- Around line 17-24: Split the single comma-chained const that destructures
params and defines banner and minBanner into three separate const declarations
to improve readability: one const for the destructuring of params (moduleName,
updaterName, version, dir, additionalExternals), one const for the multi-line
banner template literal, and one const for minBanner; update any references that
rely on those symbols (banner, minBanner, moduleName, updaterName, version)
accordingly in buildUpdater.ts so behavior is unchanged but declarations are
easier to scan.
- Line 30: The object literal contains an unnecessary explicit assignment
"minBanner: minBanner" while other properties use ES6 shorthand; update the
object to use property shorthand by replacing that explicit assignment with just
"minBanner" so it matches the existing shorthand style used for version, banner,
dir, and additionalExternals (locate the object in buildUpdater.ts where those
properties are defined).

In `@packages/webpack-config/tsconfig.json`:
- Around line 40-44: Remove the redundant compiler options
"strictFunctionTypes", "strictBindCallApply", and "noImplicitThis" from the
tsconfig.json because they are already enabled by "strict": true; keep and/or
emphasize the explicit options that are not covered by strict (e.g.,
"noUnusedLocals", "noUnusedParameters", "noImplicitReturns"). Locate the block
containing the keys "strict", "strictFunctionTypes", "strictBindCallApply", and
"noImplicitThis" and delete those three specific entries and their comments so
the file is less noisy while preserving the other explicit flags.

In `@pnpm-workspace.yaml`:
- Around line 4-9: Replace the deprecated combination of
ignoredBuiltDependencies and onlyBuiltDependencies with the unified allowBuilds
field in pnpm-workspace.yaml: remove ignoredBuiltDependencies and
onlyBuiltDependencies and add a single allowBuilds mapping that includes the
same package names (e.g., '@swc/core', 'esbuild' as allowed builds and 'nx' as
ignored via the allowBuilds structure); ensure the resulting allowBuilds schema
mirrors pnpm's expected format so the previous semantics are preserved.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f6ea9a6 and 2096267.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (53)
  • .github/workflows/node.js-ci.yml
  • .github/workflows/npm-publish.yml
  • CHANGELOG.md
  • lerna.json
  • nx.json
  • package.json
  • packages/depcruise-config/CHANGELOG.md
  • packages/depcruise-config/LICENSE
  • packages/depcruise-config/README.md
  • packages/depcruise-config/eslint.config.js
  • packages/depcruise-config/package.json
  • packages/depcruise-config/src/defaultConfig.ts
  • packages/depcruise-config/src/index.ts
  • packages/depcruise-config/src/loadConfig.ts
  • packages/depcruise-config/tsconfig.json
  • packages/depcruise-config/tsup.config.ts
  • packages/eslint-config/CHANGELOG.md
  • packages/eslint-config/package.json
  • packages/eslint-config/src/eslint.config.ts
  • packages/prettier-config/CHANGELOG.md
  • packages/prettier-config/package.json
  • packages/prettier-config/prettier-config.json
  • packages/tsconfig/CHANGELOG.md
  • packages/tsconfig/package.json
  • packages/tsconfig/tsconfig.base.json
  • packages/tsconfig/tsconfig.browser.json
  • packages/webpack-config/.babelrc
  • packages/webpack-config/.browserslistrc
  • packages/webpack-config/CHANGELOG.md
  • packages/webpack-config/package.json
  • packages/webpack-config/src/bundles/buildBundle.ts
  • packages/webpack-config/src/common/ExternalData.ts
  • packages/webpack-config/src/common/getConfig.ts
  • packages/webpack-config/src/common/getEntry.ts
  • packages/webpack-config/src/common/getExternals.ts
  • packages/webpack-config/src/effects/buildEffect.ts
  • packages/webpack-config/src/engine/buildEngine.ts
  • packages/webpack-config/src/interactions/buildInteraction.ts
  • packages/webpack-config/src/interactions/external/buildInteractionExternal.ts
  • packages/webpack-config/src/interactions/particles/buildInteractionParticles.ts
  • packages/webpack-config/src/moves/buildMove.ts
  • packages/webpack-config/src/paths/buildPath.ts
  • packages/webpack-config/src/plugins/buildPlugin.ts
  • packages/webpack-config/src/plugins/easings/buildEasing.ts
  • packages/webpack-config/src/plugins/emittersShapes/buildEmittersShape.ts
  • packages/webpack-config/src/plugins/exports/buildExport.ts
  • packages/webpack-config/src/presets/buildPreset.ts
  • packages/webpack-config/src/shapes/buildShape.ts
  • packages/webpack-config/src/templates/buildTemplate.ts
  • packages/webpack-config/src/updaters/buildUpdater.ts
  • packages/webpack-config/src/webpack-tsparticles.ts
  • packages/webpack-config/tsconfig.json
  • pnpm-workspace.yaml
💤 Files with no reviewable changes (1)
  • packages/webpack-config/.babelrc

@matteobruni matteobruni merged commit d381997 into main Feb 24, 2026
4 of 5 checks passed
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (4)
packages/webpack-config/src/effects/buildEffect.ts (1)

24-24: minBanner "Shape" → "Effect" fix confirmed.

The previously flagged copy-paste error has been resolved. The banner now correctly identifies the artifact as an Effect plugin.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/effects/buildEffect.ts` at line 24, Previously
the minBanner string incorrectly said "Shape" due to copy-paste; update the
banner so it correctly reads "Effect" by setting minBanner = `tsParticles
${effectName} Effect v${version} by Matteo Bruni` (verify the change in the
minBanner declaration and that it uses effectName and version), and scan other
banner/label constants to ensure no other copy-paste "Shape" occurrences remain.
lerna.json (1)

7-14: ⚠️ Potential issue | 🟠 Major

Publish safety gates still disabled.
forcePublish: true plus yes: true removes confirmation safeguards for local/manual runs. Please ensure these flags are CI-only or add explicit approval gates.

#!/bin/bash
# Verify where lerna publish/version is invoked and whether it's CI-gated.
rg -n "lerna (publish|version)" -S
rg -n "forcePublish|command\\.publish|command\\.version" lerna.json
rg -n "publish|version" .github -S
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@lerna.json` around lines 7 - 14, The lerna.json currently sets forcePublish:
true and yes: true which bypass local/manual confirmation gates; update the
publish configuration so these flags are only used in CI or removed: either
remove or set "forcePublish" and top-level "yes" to false in lerna.json and
instead inject them from CI (e.g., via an environment-controlled override) or
add an explicit approval gate/requirement before runs; locate the keys
"forcePublish", "yes", "conventionalCommits" and the "publish" section in
lerna.json and ensure local developer runs do not inherit unconditional
confirmation flags.
packages/eslint-config/src/eslint.config.ts (2)

25-31: prettierPlugin registered under a non-standard key — still unresolved.

Previously flagged: line 30 registers eslint-plugin-prettier under the shorthand key "prettierPlugin" instead of the conventional "prettier". Since prettierRecommended (line 245) already registers the plugin under "prettier" and activates prettier/prettier: "error", this manual entry is both redundant and uses a non-standard namespace that no rules reference.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/eslint-config/src/eslint.config.ts` around lines 25 - 31, The
plugins object currently registers eslint-plugin-prettier under the non-standard
key "prettierPlugin" (see the plugins block and the identifier prettierPlugin)
even though prettierRecommended already adds the plugin under "prettier"; remove
the redundant "prettierPlugin" entry from the plugins object so the plugin is
only provided via prettierRecommended (verify prettierRecommended is still
included elsewhere).

21-22: Type-checked rule sets still spread unconditionally regardless of parserProject.

This was flagged in a prior review and remains unresolved: tseslint.configs.strictTypeChecked and tseslint.configs.stylisticTypeChecked are always spread into the config, but the project in parserOptions is only set when parserProject is defined (line 34–39). Rules that require type information — no-floating-promises, no-misused-promises, prefer-nullish-coalescing, switch-exhaustiveness-check, restrict-template-expressions, etc. — will throw at lint time when no tsconfig.json exists in CWD.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/eslint-config/src/eslint.config.ts` around lines 21 - 22, The config
unconditionally spreads ts-eslint type-checked rule sets
(tseslint.configs.strictTypeChecked and tseslint.configs.stylisticTypeChecked)
even when parserProject isn't provided, causing type-aware rules to error;
change the spread to be conditional on parserProject (or on
parserOptions.project being set) so those rule sets are only merged when
parserProject exists — e.g. replace the direct spreads with conditional spreads
that return an empty object when parserProject is falsy, and ensure
parserOptions.project remains set only when parserProject is provided.
🧹 Nitpick comments (3)
packages/webpack-config/src/effects/buildEffect.ts (1)

30-30: Use ES6 shorthand property.

minBanner: minBanner can be simplified.

♻️ Proposed refactor
-    minBanner: minBanner,
+    minBanner,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/webpack-config/src/effects/buildEffect.ts` at line 30, Replace the
verbose object property assignment `minBanner: minBanner` with ES6 shorthand
`minBanner` in the object literal inside the buildEffect function (where the
webpack config/effect object is constructed in buildEffect.ts) so the property
name and variable name are collapsed to the shorthand form.
packages/eslint-config/src/eslint.config.ts (2)

244-245: prettierConfig is redundant — prettierRecommended already includes eslint-config-prettier.

For flat configuration, eslint-plugin-prettier/recommended sets up both eslint-plugin-prettier and eslint-config-prettier in one go. Having prettierConfig (line 244) immediately before prettierRecommended (line 245) applies the same rule disablements twice without effect.

♻️ Proposed simplification
-  prettierConfig,
   prettierRecommended,
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/eslint-config/src/eslint.config.ts` around lines 244 - 245,
prettierConfig is redundant because prettierRecommended already applies
eslint-config-prettier; remove the redundant prettierConfig entry from the
exported configuration so only prettierRecommended remains (ensure the
array/object that currently lists prettierConfig followed by prettierRecommended
is updated to drop prettierConfig and keep prettierRecommended in place).

203-203: "no-restricted-syntax": "error" without any selector patterns is a no-op.

no-restricted-syntax requires an array of { selector, message } objects in its options to restrict anything. Configured with only a severity and no patterns, it checks nothing and never fires. Either remove it or populate it with the syntax patterns you intend to forbid.

♻️ Example of a meaningful configuration
-      "no-restricted-syntax": "error",
+      "no-restricted-syntax": [
+        "error",
+        {
+          selector: "ForInStatement",
+          message: "Use Object.keys/values/entries instead of for...in.",
+        },
+      ],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/eslint-config/src/eslint.config.ts` at line 203, The
"no-restricted-syntax" entry is a no-op as currently specified; either remove
that rule entry or change it to include the rule options array of restriction
objects (e.g., ["error", [{ selector: "...", message: "..." }, ...]]); update
the eslint config where "no-restricted-syntax" is declared so it either is
deleted/disabled or populated with the intended selector/message objects that
enumerate the syntax you want to forbid.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/eslint-config/src/eslint.config.ts`:
- Line 219: The rule "prefer-arrow-callback" set to "error" is being overridden
to "off" by prettierRecommended (from eslint-plugin-prettier/recommended)
because prettierRecommended is merged after the rules block; either remove the
"prefer-arrow-callback": "error" entry from the main rules block to let Prettier
control it, or move/add an explicit override that sets "prefer-arrow-callback":
"error" in a config block placed after prettierRecommended so it wins (ensure
the change references the same rule name "prefer-arrow-callback" and the preset
identifier "prettierRecommended" so the final merged config enforces the
intended setting).
- Line 1: The current config uses an "ignores" property inside the combined
object created by defineConfig which makes patterns like "dist/" and
"node_modules/" local to that object and they still get linted by earlier
configs; fix this by importing globalIgnores from "eslint/config" and moving
those patterns out of the local "ignores" object into a top-level call to
globalIgnores([...]) passed to the exported defineConfig so the directories are
treated as global ignores (update the import to include globalIgnores and remove
the local "ignores" entry from the combined config object).

---

Duplicate comments:
In `@lerna.json`:
- Around line 7-14: The lerna.json currently sets forcePublish: true and yes:
true which bypass local/manual confirmation gates; update the publish
configuration so these flags are only used in CI or removed: either remove or
set "forcePublish" and top-level "yes" to false in lerna.json and instead inject
them from CI (e.g., via an environment-controlled override) or add an explicit
approval gate/requirement before runs; locate the keys "forcePublish", "yes",
"conventionalCommits" and the "publish" section in lerna.json and ensure local
developer runs do not inherit unconditional confirmation flags.

In `@packages/eslint-config/src/eslint.config.ts`:
- Around line 25-31: The plugins object currently registers
eslint-plugin-prettier under the non-standard key "prettierPlugin" (see the
plugins block and the identifier prettierPlugin) even though prettierRecommended
already adds the plugin under "prettier"; remove the redundant "prettierPlugin"
entry from the plugins object so the plugin is only provided via
prettierRecommended (verify prettierRecommended is still included elsewhere).
- Around line 21-22: The config unconditionally spreads ts-eslint type-checked
rule sets (tseslint.configs.strictTypeChecked and
tseslint.configs.stylisticTypeChecked) even when parserProject isn't provided,
causing type-aware rules to error; change the spread to be conditional on
parserProject (or on parserOptions.project being set) so those rule sets are
only merged when parserProject exists — e.g. replace the direct spreads with
conditional spreads that return an empty object when parserProject is falsy, and
ensure parserOptions.project remains set only when parserProject is provided.

In `@packages/webpack-config/src/effects/buildEffect.ts`:
- Line 24: Previously the minBanner string incorrectly said "Shape" due to
copy-paste; update the banner so it correctly reads "Effect" by setting
minBanner = `tsParticles ${effectName} Effect v${version} by Matteo Bruni`
(verify the change in the minBanner declaration and that it uses effectName and
version), and scan other banner/label constants to ensure no other copy-paste
"Shape" occurrences remain.

---

Nitpick comments:
In `@packages/eslint-config/src/eslint.config.ts`:
- Around line 244-245: prettierConfig is redundant because prettierRecommended
already applies eslint-config-prettier; remove the redundant prettierConfig
entry from the exported configuration so only prettierRecommended remains
(ensure the array/object that currently lists prettierConfig followed by
prettierRecommended is updated to drop prettierConfig and keep
prettierRecommended in place).
- Line 203: The "no-restricted-syntax" entry is a no-op as currently specified;
either remove that rule entry or change it to include the rule options array of
restriction objects (e.g., ["error", [{ selector: "...", message: "..." },
...]]); update the eslint config where "no-restricted-syntax" is declared so it
either is deleted/disabled or populated with the intended selector/message
objects that enumerate the syntax you want to forbid.

In `@packages/webpack-config/src/effects/buildEffect.ts`:
- Line 30: Replace the verbose object property assignment `minBanner: minBanner`
with ES6 shorthand `minBanner` in the object literal inside the buildEffect
function (where the webpack config/effect object is constructed in
buildEffect.ts) so the property name and variable name are collapsed to the
shorthand form.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2096267 and ad0ed3e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (25)
  • CHANGELOG.md
  • lerna.json
  • nx.json
  • package.json
  • packages/depcruise-config/CHANGELOG.md
  • packages/depcruise-config/package.json
  • packages/eslint-config/CHANGELOG.md
  • packages/eslint-config/package.json
  • packages/eslint-config/src/eslint.config.ts
  • packages/prettier-config/CHANGELOG.md
  • packages/prettier-config/package.json
  • packages/prettier-config/src/prettier-config.json
  • packages/tsconfig/CHANGELOG.md
  • packages/tsconfig/package.json
  • packages/tsconfig/src/tsconfig.base.json
  • packages/tsconfig/src/tsconfig.browser.json
  • packages/tsconfig/src/tsconfig.json
  • packages/tsconfig/src/tsconfig.module.json
  • packages/tsconfig/src/tsconfig.types.json
  • packages/tsconfig/src/tsconfig.umd.json
  • packages/webpack-config/CHANGELOG.md
  • packages/webpack-config/package.json
  • packages/webpack-config/src/common/getExternals.ts
  • packages/webpack-config/src/effects/buildEffect.ts
  • pnpm-workspace.yaml
✅ Files skipped from review due to trivial changes (1)
  • packages/tsconfig/CHANGELOG.md
🚧 Files skipped from review as they are similar to previous changes (10)
  • packages/depcruise-config/package.json
  • pnpm-workspace.yaml
  • nx.json
  • packages/depcruise-config/CHANGELOG.md
  • packages/webpack-config/src/common/getExternals.ts
  • packages/eslint-config/package.json
  • packages/tsconfig/package.json
  • packages/webpack-config/CHANGELOG.md
  • package.json
  • packages/prettier-config/package.json

@@ -1,210 +1,246 @@
import path from "path";
import fs from "fs";
import { defineConfig } from "eslint/config";
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

ignores inside a combined config object is local, not global — dist/ will still be linted by preceding configs.

When ignores is used with other properties in the same configuration object, the patterns act as non-global ignores and apply only to the configuration object in which they are defined. Because ignores here shares an object with plugins, languageOptions, and rules, dist and node_modules are only excluded from that one block. They remain linted by js.configs.recommended, stylistic.configs.recommended, and the spread tseslint.configs.strictTypeChecked entries that precede it.

The correct approach with defineConfig is to use the globalIgnores() helper, imported from "eslint/config". Ignoring directories works the same way as ignoring files — pass the pattern to globalIgnores().

🐛 Proposed fix
-import { defineConfig } from "eslint/config";
+import { defineConfig, globalIgnores } from "eslint/config";
 ...
 export default defineConfig([
+  globalIgnores(["dist", "node_modules"]),
   js.configs.recommended,
   stylistic.configs.recommended,
   ...
   {
-    ignores: ["dist", "node_modules"],
     plugins: {

Also applies to: 23-24

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/eslint-config/src/eslint.config.ts` at line 1, The current config
uses an "ignores" property inside the combined object created by defineConfig
which makes patterns like "dist/" and "node_modules/" local to that object and
they still get linted by earlier configs; fix this by importing globalIgnores
from "eslint/config" and moving those patterns out of the local "ignores" object
into a top-level call to globalIgnores([...]) passed to the exported
defineConfig so the directories are treated as global ignores (update the import
to include globalIgnores and remove the local "ignores" entry from the combined
config object).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant