Skip to content

3.1.7#98

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

3.1.7#98
matteobruni merged 19 commits intomainfrom
dev

Conversation

@matteobruni
Copy link
Contributor

@matteobruni matteobruni commented Feb 24, 2026

Summary by CodeRabbit

  • Chores
    • Updated dependencies and development tools to latest versions
    • Enhanced CI/CD workflows with improved build processes
    • Added automated npm package publishing workflow with support for alpha and beta releases
    • Bumped package version to 3.1.7
    • Optimized build system configuration

@coderabbitai
Copy link

coderabbitai bot commented Feb 24, 2026

📝 Walkthrough

Walkthrough

This pull request updates CI/CD workflows, dependency versions, refactors the build system to use a new configuration loading mechanism for dependency-cruiser, and updates TypeScript configuration inheritance paths to use distributable versions from @tsparticles/tsconfig packages.

Changes

Cohort / File(s) Summary
GitHub Actions Workflows
.github/workflows/node.js-ci.yml, .github/workflows/npm-publish.yml
Removed pnpm version pin and --no-frozen-lockfile flag from CI workflow; added new npm publish workflow with OIDC authentication, tag-based triggers (v\*), and pre-release tag handling (alpha/beta).
TypeScript Configuration
files/empty-project/tsconfig*.json
Updated all five tsconfig extends paths from @tsparticles/tsconfig/tsconfig.* to @tsparticles/tsconfig/dist/tsconfig.* (base, browser, json, module, types, umd).
Package Manifests
package.json, files/empty-project/package.json
Bumped root package version to 3.1.7, added packageManager field (pnpm@10.30.2), updated publishConfig with tagVersionPrefix, added repository field; updated devDependencies across both files (e.g., @swc/core, webpack, typescript-eslint, @tsparticles/\* packages); added @tsparticles/depcruise-config.
Build System Refactoring
src/build/build-circular-deps.ts, src/build/build-eslint.ts, src/build/build-tsc.ts, src/build/build.ts
Refactored build-circular-deps to load dependency-cruiser config at runtime via loadDependencyCruiserConfig, removing filesystem checks and dynamic imports; consolidated variable declarations in build-eslint; updated tsconfig extends paths in build-tsc fallbacks from non-dist to dist paths; reordered variable declarations in build.ts.

Possibly Related PRs

  • 3.1.1 #89: Introduced dependency-cruiser integration and .dependency-cruiser.cjs configuration file, which directly corresponds to the refactored configuration loading mechanism in src/build/build-circular-deps.ts.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Hop along, dear dependencies, now in dist we call home,
OIDC tokens bloom, npm packages roam,
Build scripts dance with cruiser's grace,
Version bumps find their rightful place,
From madge's past to config's light,
Our workflows hop through day and night! 📦✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title '3.1.7' is a version number that is vague and does not describe the actual changes in the pull request. Replace the title with a clear, descriptive summary of the main changes, such as 'Update dependencies and TypeScript configurations' or 'Bump version to 3.1.7 and refactor build tooling'.
✅ 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 docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 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.

@matteobruni matteobruni merged commit 27a42e6 into main Feb 24, 2026
2 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

🧹 Nitpick comments (2)
.github/workflows/npm-publish.yml (1)

56-66: Unquoted variable expansion of $BASE_CMD may cause issues in edge cases.

While the current value won't trigger word-splitting issues, it's a good shell hygiene practice to quote the expansion or use an array/function instead.

Suggested fix
-          BASE_CMD="npx pnpm publish --ignore-scripts --no-git-checks"
-
-          if [[ "$TAG" == *"-alpha."* ]]; then
-            $BASE_CMD --pre-dist-tag alpha
-          elif [[ "$TAG" == *"-beta."* ]]; then
-            $BASE_CMD --pre-dist-tag beta
-          else
-            $BASE_CMD
-          fi
+          publish() {
+            npx pnpm publish --ignore-scripts --no-git-checks "$@"
+          }
+
+          if [[ "$TAG" == *"-alpha."* ]]; then
+            publish --pre-dist-tag alpha
+          elif [[ "$TAG" == *"-beta."* ]]; then
+            publish --pre-dist-tag beta
+          else
+            publish
+          fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/npm-publish.yml around lines 56 - 66, The workflow
unquoted the variable expansion BASE_CMD when executing it (and in the
conditional branches), which can lead to word-splitting or globbing edge cases;
update the script to safely invoke the prepared command by either quoting the
expansion ("$BASE_CMD") when running it or, better, store the command as an
array/func (e.g., base_cmd=(npx pnpm publish --ignore-scripts --no-git-checks))
and call it with "${base_cmd[@]}" and then append the --pre-dist-tag arg when
TAG contains "-alpha." or "-beta." so BASE_CMD is executed safely in the alpha,
beta, and default branches.
src/build/build-circular-deps.ts (1)

31-31: Fragile type cast on cycle step extraction.

(step as { name: string }).name assumes each cycle step has a name property. If the dependency-cruiser API changes the cycle step shape, this will throw at runtime without a helpful error. Consider adding a guard or using the library's own type for cycle steps.

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

In `@src/build/build-circular-deps.ts` at line 31, The mapping of violation.cycle
to extract names is using a fragile cast (step as { name: string }).name; update
the extraction in build-circular-deps.ts to safely access a name field (or the
library's official cycle-step type) by checking for step && typeof (step as
any).name === 'string' before reading it, falling back to a safe representation
(e.g., step.path or String(step)) when name is missing, or import and use
dependency-cruiser’s CycleStep type to type the array and access the property
safely; ensure the variable cyclePath still becomes an array of strings even
when some steps lack name.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/npm-publish.yml:
- Around line 54-66: The publish step "Publish to NPM (OIDC Auth)" will fail
without an auth token; update the step that builds BASE_CMD and runs the publish
by either exporting NODE_AUTH_TOKEN from your secret (e.g., set env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} so pnpm can use classic token auth)
or, if you intend OIDC provenance, append --provenance to BASE_CMD and ensure
the action obtains and exposes the OIDC token expected by npm; adjust the
conditional branches that call $BASE_CMD (and the TAG handling) so they call the
chosen authenticated BASE_CMD consistently.

In `@src/build/build-circular-deps.ts`:
- Around line 17-25: Change the incorrect type cast of the cruise() result from
Partial<ICruiseResult> to IReporterOutput: replace the cast assigned to
cruiseResult (currently "result as Partial<ICruiseResult>") with "result as
IReporterOutput" and add IReporterOutput to the imports from dependency-cruiser
if missing; keep the rest of the logic that extracts violations and builds
circularViolations (the variables violations and circularViolations should
remain unchanged).

---

Nitpick comments:
In @.github/workflows/npm-publish.yml:
- Around line 56-66: The workflow unquoted the variable expansion BASE_CMD when
executing it (and in the conditional branches), which can lead to word-splitting
or globbing edge cases; update the script to safely invoke the prepared command
by either quoting the expansion ("$BASE_CMD") when running it or, better, store
the command as an array/func (e.g., base_cmd=(npx pnpm publish --ignore-scripts
--no-git-checks)) and call it with "${base_cmd[@]}" and then append the
--pre-dist-tag arg when TAG contains "-alpha." or "-beta." so BASE_CMD is
executed safely in the alpha, beta, and default branches.

In `@src/build/build-circular-deps.ts`:
- Line 31: The mapping of violation.cycle to extract names is using a fragile
cast (step as { name: string }).name; update the extraction in
build-circular-deps.ts to safely access a name field (or the library's official
cycle-step type) by checking for step && typeof (step as any).name === 'string'
before reading it, falling back to a safe representation (e.g., step.path or
String(step)) when name is missing, or import and use dependency-cruiser’s
CycleStep type to type the array and access the property safely; ensure the
variable cyclePath still becomes an array of strings even when some steps lack
name.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6eb7f49 and e076cd5.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • .github/workflows/node.js-ci.yml
  • .github/workflows/npm-publish.yml
  • files/empty-project/package.json
  • files/empty-project/tsconfig.base.json
  • files/empty-project/tsconfig.browser.json
  • files/empty-project/tsconfig.json
  • files/empty-project/tsconfig.module.json
  • files/empty-project/tsconfig.types.json
  • files/empty-project/tsconfig.umd.json
  • package.json
  • src/build/build-circular-deps.ts
  • src/build/build-eslint.ts
  • src/build/build-tsc.ts
  • src/build/build.ts

Comment on lines +54 to +66
- name: Publish to NPM (OIDC Auth)
run: |
TAG="${GITHUB_REF#refs/tags/}"

BASE_CMD="npx pnpm publish --ignore-scripts --no-git-checks"

if [[ "$TAG" == *"-alpha."* ]]; then
$BASE_CMD --pre-dist-tag alpha
elif [[ "$TAG" == *"-beta."* ]]; then
$BASE_CMD --pre-dist-tag beta
else
$BASE_CMD
fi
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Missing NODE_AUTH_TOKEN environment variable — publish will fail.

The workflow sets up OIDC permissions (id-token: write) but the publish step neither passes NODE_AUTH_TOKEN nor uses --provenance to leverage OIDC-based npm authentication. Without one of these, pnpm publish will fail with a 401/403 from the npm registry.

If OIDC provenance-based publishing is intended, add --provenance and the token. If classic token auth is intended, supply the secret:

Proposed fix (OIDC provenance)
      - name: Publish to NPM (OIDC Auth)
        run: |
          TAG="${GITHUB_REF#refs/tags/}"
          
-          BASE_CMD="npx pnpm publish --ignore-scripts --no-git-checks"
+          BASE_CMD="npx pnpm publish --ignore-scripts --no-git-checks --provenance"

           if [[ "$TAG" == *"-alpha."* ]]; then
             $BASE_CMD --pre-dist-tag alpha
           elif [[ "$TAG" == *"-beta."* ]]; then
             $BASE_CMD --pre-dist-tag beta
           else
             $BASE_CMD
           fi
+        env:
+          NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Publish to NPM (OIDC Auth)
run: |
TAG="${GITHUB_REF#refs/tags/}"
BASE_CMD="npx pnpm publish --ignore-scripts --no-git-checks"
if [[ "$TAG" == *"-alpha."* ]]; then
$BASE_CMD --pre-dist-tag alpha
elif [[ "$TAG" == *"-beta."* ]]; then
$BASE_CMD --pre-dist-tag beta
else
$BASE_CMD
fi
- name: Publish to NPM (OIDC Auth)
run: |
TAG="${GITHUB_REF#refs/tags/}"
BASE_CMD="npx pnpm publish --ignore-scripts --no-git-checks --provenance"
if [[ "$TAG" == *"-alpha."* ]]; then
$BASE_CMD --pre-dist-tag alpha
elif [[ "$TAG" == *"-beta."* ]]; then
$BASE_CMD --pre-dist-tag beta
else
$BASE_CMD
fi
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/npm-publish.yml around lines 54 - 66, The publish step
"Publish to NPM (OIDC Auth)" will fail without an auth token; update the step
that builds BASE_CMD and runs the publish by either exporting NODE_AUTH_TOKEN
from your secret (e.g., set env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} so
pnpm can use classic token auth) or, if you intend OIDC provenance, append
--provenance to BASE_CMD and ensure the action obtains and exposes the OIDC
token expected by npm; adjust the conditional branches that call $BASE_CMD (and
the TAG handling) so they call the chosen authenticated BASE_CMD consistently.

Comment on lines +17 to +25
const result = await cruise([srcPath], {
...cruiseOptions.options,
ruleSet: {
forbidden: extendedConfig.forbidden ?? [],
forbidden: cruiseOptions.forbidden ?? [],
},
};
} else {
console.log("No .dependency-cruiser.js found, applying default circular check.");

cruiseOptions.ruleSet = {
forbidden: [
{
name: "no-circular",
severity: "error",
from: {},
to: { circular: true },
},
],
};
}

const result: unknown = await cruise([srcPath], cruiseOptions),
}),
cruiseResult = result as Partial<ICruiseResult>,
violations: IViolation[] = cruiseResult.summary?.violations ?? [],
circularViolations = violations.filter((violation: IViolation) => violation.rule.name === "no-circular");
circularViolations = violations.filter(violation => violation.rule.name === "no-circular");
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

🧩 Analysis chain

🌐 Web query:

dependency-cruiser cruise function async v17 API

💡 Result:

In dependency-cruiser v17, the programmatic API is ESM-only and cruise() is async, so you call it with await and it returns a Promise<IReporterOutput>. [1]

cruise() call shape (v17)

import { cruise } from "dependency-cruiser";

const result = await cruise(
  ["src"],          // filesOrDirectories
  cruiseOptions,    // (optional) ICruiseOptions
  resolveOptions,   // (optional) webpack/enhanced-resolve-style options
  { tsConfig }      // (optional) transpilation options object (supports tsConfig, babelConfig)
);

This parameter structure (notably the 4th param as an object that can include tsConfig and/or babelConfig) is the “new” signature introduced when the API became async/ESM. [1][2]

Notes that commonly trip people up

  • Validation is off by default in the API; set cruiseOptions.validate = true and pass a ruleSet if you want rule violations in the output. [1]
  • There was a specific fix for “Using the API but tsconfig does not work” in the v17.3.0 line—so if TS path mapping etc. seems ignored, ensure you’re on ≥ 17.3.0. [3]

Sources:
[1] dependency-cruiser doc/api.md (usage examples + options) (raw.githubusercontent.com)
[2] Breaking changes note (API is async/ESM; cruise signature change; 4th param object for tsConfig/babelConfig) (github.com)
[3] v17.3.0 release notes (fix: “Using the API but tsconfig does not work”) (github.com)

Citations:


🏁 Script executed:

# Check the package.json to see the version of dependency-cruiser
find . -name "package.json" -type f | head -5 | xargs grep -l "dependency-cruiser" 2>/dev/null

# Also check the specific file mentioned in the review
cat -n src/build/build-circular-deps.ts 2>/dev/null | head -40

Repository: tsparticles/cli

Length of output: 1787


🏁 Script executed:

# Check if there are type definitions or other imports that show the actual types
rg "IReporterOutput|ICruiseResult" src/ --type ts --type tsx -C 2

Repository: tsparticles/cli

Length of output: 86


🏁 Script executed:

# Search for type definitions with just ts files
rg "IReporterOutput|ICruiseResult" src/ -C 2

Repository: tsparticles/cli

Length of output: 761


🏁 Script executed:

# Check the package.json to see the exact version of dependency-cruiser being used
cat package.json | grep -A 2 -B 2 "dependency-cruiser"

Repository: tsparticles/cli

Length of output: 198


Update type cast to use the correct v17 return type.

The await on line 17 is correct—cruise() is async in dependency-cruiser v17. However, the return type in v17 is IReporterOutput, not ICruiseResult. Update the type cast on line 23 from Partial<ICruiseResult> to IReporterOutput, and add it to the imports if not already present.

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

In `@src/build/build-circular-deps.ts` around lines 17 - 25, Change the incorrect
type cast of the cruise() result from Partial<ICruiseResult> to IReporterOutput:
replace the cast assigned to cruiseResult (currently "result as
Partial<ICruiseResult>") with "result as IReporterOutput" and add
IReporterOutput to the imports from dependency-cruiser if missing; keep the rest
of the logic that extracts violations and builds circularViolations (the
variables violations and circularViolations should remain unchanged).

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