From 38422e44411c8d87649966ac89a7de6bde3f82c2 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 10 Dec 2025 17:24:45 +0100 Subject: [PATCH 1/7] refactor: add bundle-stats plugin package and fix CI --- eslint.config.js | 2 +- package-lock.json | 8489 ++++++--- package.json | 1 - .../.eslint/eslint-report.json | 5272 ++++++ packages/plugin-bundle-stats/CONTRIBUTING.md | 35 + packages/plugin-bundle-stats/README.md | 500 + ...ode-pushup.minimal-esbuild-sonda.config.ts | 45 + .../code-pushup.minimal-esbuild.config.ts | 869 + packages/plugin-bundle-stats/debug-test.js | 57 + packages/plugin-bundle-stats/docs/select.md | 334 + packages/plugin-bundle-stats/docs/table.md | 429 + packages/plugin-bundle-stats/docs/tree.md | 458 + packages/plugin-bundle-stats/eslint.config.js | 59 + .../fixtures/angular-minimal/.editorconfig | 17 + .../mocks/fixtures/angular-minimal/.gitignore | 0 .../mocks/fixtures/angular-minimal/README.md | 68 + .../fixtures/angular-minimal/angular.json | 87 + .../angular-minimal/package-lock.json | 14866 ++++++++++++++++ .../fixtures/angular-minimal/package.json | 39 + .../angular-minimal/public/favicon.ico | 0 .../angular-minimal/src/app/app.component.css | 3 + .../src/app/app.component.html | 360 + .../angular-minimal/src/app/app.component.ts | 0 .../angular-minimal/src/app/app.config.ts | 0 .../angular-minimal/src/app/app.routes.ts | 0 .../src/app/route-1.component.ts | 0 .../fixtures/angular-minimal/src/index.html | 13 + .../fixtures/angular-minimal/src/main.ts | 0 .../fixtures/angular-minimal/src/styles.css | 55 + .../angular-minimal/tsconfig.app.json | 11 + .../fixtures/angular-minimal/tsconfig.json | 27 + .../angular-minimal/tsconfig.spec.json | 10 + .../node-minimal/.sonda/sonda-report.json | 111 + .../mocks/fixtures/node-minimal/README.md | 47 + .../node-minimal/esbuild-sonda.script.cjs | 64 + .../fixtures/node-minimal/esbuild.script.cjs | 55 + .../mocks/fixtures/node-minimal/index.html | 12 + .../fixtures/node-minimal/package-lock.json | 3654 ++++ .../mocks/fixtures/node-minimal/package.json | 23 + .../fixtures/node-minimal/rsbuild.script.cjs | 37 + .../mocks/fixtures/node-minimal/src/bin.ts | 6 + .../mocks/fixtures/node-minimal/src/index.ts | 6 + .../node-minimal/src/lib/feature-1.ts | 3 + .../node-minimal/src/lib/feature-2.ts | 5 + .../node-minimal/src/lib/styles/theme.css | 9 + .../node-minimal/src/lib/utils/format.ts | 4 + .../node-minimal/src/lib/utils/math.ts | 4 + .../fixtures/node-minimal/src/styles.css | 5 + .../mocks/fixtures/node-minimal/tsconfig.json | 15 + .../fixtures/node-minimal/vite.config.ts | 32 + .../fixtures/node-minimal/vite.script.cjs | 35 + .../fixtures/node-minimal/webpack.script.cjs | 29 + .../fixtures/stats/angular-minimal.stats.json | 77 + .../stats/esbuild-minimal.sonda-report.json | 111 + .../fixtures/stats/esbuild-minimal.stats.json | 315 + packages/plugin-bundle-stats/package.json | 37 + packages/plugin-bundle-stats/project.json | 79 + packages/plugin-bundle-stats/src/index.ts | 15 + .../src/lib/__snapshots__/esbuild.stats.json | 279 + .../src/lib/__snapshots__/rsbuild.stats.json | 1994 +++ .../src/lib/__snapshots__/webpack.stats.json | 1303 ++ .../src/lib/bundle-stats-plugin.ts | 56 + .../plugin-bundle-stats/src/lib/constants.ts | 379 + .../plugin-bundle-stats/src/lib/normalize.ts | 497 + .../src/lib/runner/audits/audit-outputs.ts | 69 + .../runner/audits/audit-outputs.unit.test.ts | 64 + .../runner/audits/details/audit-details.ts | 52 + .../lib/runner/audits/details/formatting.ts | 172 + .../src/lib/runner/audits/details/grouping.ts | 462 + .../audits/details/grouping.unit.test.ts | 41 + .../src/lib/runner/audits/details/issues.ts | 518 + .../runner/audits/details/issues.unit.test.ts | 212 + .../lib/runner/audits/details/path-utils.ts | 47 + .../src/lib/runner/audits/details/table.ts | 291 + .../runner/audits/details/table.unit.test.ts | 470 + .../src/lib/runner/audits/details/tree.ts | 387 + .../runner/audits/details/tree.unit.test.ts | 756 + .../src/lib/runner/audits/details/types.ts | 9 + .../src/lib/runner/audits/scoring.ts | 208 + .../src/lib/runner/audits/selection.ts | 308 + .../lib/runner/audits/selection.unit.test.ts | 427 + .../src/lib/runner/bundle-stats-runner.ts | 384 + .../runner/bundle-stats-runner.unit.test.ts | 552 + .../src/lib/runner/constants.ts | 19 + .../src/lib/runner/types.ts | 92 + .../lib/runner/unify/unified-stats.types.ts | 27 + .../src/lib/runner/unify/unify.esbuild.ts | 140 + .../runner/unify/unify.esbuild.unit.test.ts | 261 + .../src/lib/runner/unify/unify.rsbuild.ts | 236 + .../runner/unify/unify.rsbuild.unit.test.ts | 583 + .../src/lib/runner/unify/unify.sonda.ts | 260 + .../lib/runner/unify/unify.sonda.unit.test.ts | 465 + .../src/lib/runner/unify/unify.vite.ts | 74 + .../src/lib/runner/unify/unify.webpack.ts | 160 + .../runner/unify/unify.webpack.unit.test.ts | 101 + .../src/lib/runner/utils.ts | 65 + .../src/lib/stats-generation.int.test.ts | 189 + packages/plugin-bundle-stats/src/lib/types.ts | 81 + packages/plugin-bundle-stats/tsconfig.json | 23 + .../plugin-bundle-stats/tsconfig.lib.json | 16 + .../plugin-bundle-stats/tsconfig.test.json | 18 + .../plugin-bundle-stats/vitest.int.config.ts | 3 + .../plugin-bundle-stats/vitest.unit.config.ts | 3 + 103 files changed, 47097 insertions(+), 2552 deletions(-) create mode 100644 packages/plugin-bundle-stats/.eslint/eslint-report.json create mode 100644 packages/plugin-bundle-stats/CONTRIBUTING.md create mode 100644 packages/plugin-bundle-stats/README.md create mode 100644 packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts create mode 100644 packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts create mode 100644 packages/plugin-bundle-stats/debug-test.js create mode 100644 packages/plugin-bundle-stats/docs/select.md create mode 100644 packages/plugin-bundle-stats/docs/table.md create mode 100644 packages/plugin-bundle-stats/docs/tree.md create mode 100644 packages/plugin-bundle-stats/eslint.config.js create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.editorconfig create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.gitignore create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/README.md create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/angular.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package-lock.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/public/favicon.ico create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.css create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.html create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.config.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.routes.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/route-1.component.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/index.html create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/main.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/styles.css create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.app.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.spec.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/.sonda/sonda-report.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/README.md create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild-sonda.script.cjs create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild.script.cjs create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/index.html create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package-lock.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/rsbuild.script.cjs create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/bin.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/index.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-1.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-2.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/styles/theme.css create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/format.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/math.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/styles.css create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/tsconfig.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.config.ts create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.script.cjs create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/node-minimal/webpack.script.cjs create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/stats/angular-minimal.stats.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json create mode 100644 packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json create mode 100644 packages/plugin-bundle-stats/package.json create mode 100644 packages/plugin-bundle-stats/project.json create mode 100644 packages/plugin-bundle-stats/src/index.ts create mode 100644 packages/plugin-bundle-stats/src/lib/__snapshots__/esbuild.stats.json create mode 100644 packages/plugin-bundle-stats/src/lib/__snapshots__/rsbuild.stats.json create mode 100644 packages/plugin-bundle-stats/src/lib/__snapshots__/webpack.stats.json create mode 100644 packages/plugin-bundle-stats/src/lib/bundle-stats-plugin.ts create mode 100644 packages/plugin-bundle-stats/src/lib/constants.ts create mode 100644 packages/plugin-bundle-stats/src/lib/normalize.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/audit-details.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/formatting.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/table.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/details/types.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/scoring.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/selection.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/audits/selection.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/constants.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/types.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unified-stats.types.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.vite.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.unit.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/runner/utils.ts create mode 100644 packages/plugin-bundle-stats/src/lib/stats-generation.int.test.ts create mode 100644 packages/plugin-bundle-stats/src/lib/types.ts create mode 100644 packages/plugin-bundle-stats/tsconfig.json create mode 100644 packages/plugin-bundle-stats/tsconfig.lib.json create mode 100644 packages/plugin-bundle-stats/tsconfig.test.json create mode 100644 packages/plugin-bundle-stats/vitest.int.config.ts create mode 100644 packages/plugin-bundle-stats/vitest.unit.config.ts diff --git a/eslint.config.js b/eslint.config.js index 596275f..fb6e536 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -148,7 +148,7 @@ export default tseslint.config( { ignores: [ '**/*.mock.*', - '**/code-pushup.config.ts', + '**/code-pushup*.config.ts', '**/mocks/fixtures/**', '**/__snapshots__/**', '**/dist', diff --git a/package-lock.json b/package-lock.json index 1b26fba..9434128 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,6 @@ "dependencies": { "@code-pushup/cli": "^0.92.1", "@code-pushup/core": "^0.92.1", - "@code-pushup/models": "^0.92.1", "@code-pushup/portal-client": "^0.16.0", "@code-pushup/utils": "^0.92.1", "@poppinss/cliui": "^6.4.1", @@ -117,798 +116,939 @@ "dev": true, "license": "MIT" }, - "node_modules/@ampproject/remapping": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", - "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "node_modules/@algolia/abtesting": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@algolia/abtesting/-/abtesting-1.1.0.tgz", + "integrity": "sha512-sEyWjw28a/9iluA37KLGu8vjxEIlb60uxznfTUmXImy7H5NvbpSO6yYgmgH5KiD7j+zTUUihiST0jEP12IoXow==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.0.0" + "node": ">= 14.0.0" } }, - "node_modules/@asamuzakjp/css-color": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", - "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", - "devOptional": true, + "node_modules/@algolia/client-abtesting": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-abtesting/-/client-abtesting-5.35.0.tgz", + "integrity": "sha512-uUdHxbfHdoppDVflCHMxRlj49/IllPwwQ2cQ8DLC4LXr3kY96AHBpW0dMyi6ygkn2MtFCc6BxXCzr668ZRhLBQ==", + "dev": true, "license": "MIT", "dependencies": { - "@csstools/css-calc": "^2.1.3", - "@csstools/css-color-parser": "^3.0.9", - "@csstools/css-parser-algorithms": "^3.0.4", - "@csstools/css-tokenizer": "^3.0.3", - "lru-cache": "^10.4.3" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "devOptional": true, - "license": "ISC" - }, - "node_modules/@babel/code-frame": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", - "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "node_modules/@algolia/client-analytics": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-analytics/-/client-analytics-5.35.0.tgz", + "integrity": "sha512-SunAgwa9CamLcRCPnPHx1V2uxdQwJGqb1crYrRWktWUdld0+B2KyakNEeVn5lln4VyeNtW17Ia7V7qBWyM/Skw==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.27.1", - "js-tokens": "^4.0.0", - "picocolors": "^1.1.1" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/compat-data": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", - "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", - "devOptional": true, + "node_modules/@algolia/client-common": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.35.0.tgz", + "integrity": "sha512-ipE0IuvHu/bg7TjT2s+187kz/E3h5ssfTtjpg1LbWMgxlgiaZIgTTbyynM7NfpSJSKsgQvCQxWjGUO51WSCu7w==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/core": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", - "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", - "devOptional": true, + "node_modules/@algolia/client-insights": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-insights/-/client-insights-5.35.0.tgz", + "integrity": "sha512-UNbCXcBpqtzUucxExwTSfAe8gknAJ485NfPN6o1ziHm6nnxx97piIbcBQ3edw823Tej2Wxu1C0xBY06KgeZ7gA==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-compilation-targets": "^7.27.2", - "@babel/helper-module-transforms": "^7.28.3", - "@babel/helpers": "^7.28.4", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/traverse": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/remapping": "^2.3.5", - "convert-source-map": "^2.0.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.3", - "semver": "^6.3.1" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" + "node": ">= 14.0.0" } }, - "node_modules/@babel/generator": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", - "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", - "devOptional": true, + "node_modules/@algolia/client-personalization": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-personalization/-/client-personalization-5.35.0.tgz", + "integrity": "sha512-/KWjttZ6UCStt4QnWoDAJ12cKlQ+fkpMtyPmBgSS2WThJQdSV/4UWcqCUqGH7YLbwlj3JjNirCu3Y7uRTClxvA==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.5", - "@babel/types": "^7.28.5", - "@jridgewell/gen-mapping": "^0.3.12", - "@jridgewell/trace-mapping": "^0.3.28", - "jsesc": "^3.0.2" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", - "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", - "devOptional": true, + "node_modules/@algolia/client-query-suggestions": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-query-suggestions/-/client-query-suggestions-5.35.0.tgz", + "integrity": "sha512-8oCuJCFf/71IYyvQQC+iu4kgViTODbXDk3m7yMctEncRSRV+u2RtDVlpGGfPlJQOrAY7OONwJlSHkmbbm2Kp/w==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.25.9" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", - "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", - "devOptional": true, + "node_modules/@algolia/client-search": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.35.0.tgz", + "integrity": "sha512-FfmdHTrXhIduWyyuko1YTcGLuicVbhUyRjO3HbXE4aP655yKZgdTIfMhZ/V5VY9bHuxv/fGEh3Od1Lvv2ODNTg==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.27.2", - "@babel/helper-validator-option": "^7.27.1", - "browserslist": "^4.24.0", - "lru-cache": "^5.1.1", - "semver": "^6.3.1" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", - "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", - "devOptional": true, + "node_modules/@algolia/ingestion": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@algolia/ingestion/-/ingestion-1.35.0.tgz", + "integrity": "sha512-gPzACem9IL1Co8mM1LKMhzn1aSJmp+Vp434An4C0OBY4uEJRcqsLN3uLBlY+bYvFg8C8ImwM9YRiKczJXRk0XA==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/traverse": "^7.25.9", - "semver": "^6.3.1" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" + "node_modules/@algolia/monitoring": { + "version": "1.35.0", + "resolved": "https://registry.npmjs.org/@algolia/monitoring/-/monitoring-1.35.0.tgz", + "integrity": "sha512-w9MGFLB6ashI8BGcQoVt7iLgDIJNCn4OIu0Q0giE3M2ItNrssvb8C0xuwJQyTy1OFZnemG0EB1OvXhIHOvQwWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", - "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", - "devOptional": true, + "node_modules/@algolia/recommend": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/recommend/-/recommend-5.35.0.tgz", + "integrity": "sha512-AhrVgaaXAb8Ue0u2nuRWwugt0dL5UmRgS9LXe0Hhz493a8KFeZVUE56RGIV3hAa6tHzmAV7eIoqcWTQvxzlJeQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "regexpu-core": "^6.2.0", - "semver": "^6.3.1" + "@algolia/client-common": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" + "node_modules/@algolia/requester-browser-xhr": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.35.0.tgz", + "integrity": "sha512-diY415KLJZ6x1Kbwl9u96Jsz0OstE3asjXtJ9pmk1d+5gPuQ5jQyEsgC+WmEXzlec3iuVszm8AzNYYaqw6B+Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-define-polyfill-provider": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", - "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", - "devOptional": true, + "node_modules/@algolia/requester-fetch": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.35.0.tgz", + "integrity": "sha512-uydqnSmpAjrgo8bqhE9N1wgcB98psTRRQXcjc4izwMB7yRl9C8uuAQ/5YqRj04U0mMQ+fdu2fcNF6m9+Z1BzDQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-compilation-targets": "^7.22.6", - "@babel/helper-plugin-utils": "^7.22.5", - "debug": "^4.1.1", - "lodash.debounce": "^4.0.8", - "resolve": "^1.14.2" + "@algolia/client-common": "5.35.0" }, - "peerDependencies": { - "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + "engines": { + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-globals": { - "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", - "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", - "devOptional": true, + "node_modules/@algolia/requester-node-http": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.35.0.tgz", + "integrity": "sha512-RgLX78ojYOrThJHrIiPzT4HW3yfQa0D7K+MQ81rhxqaNyNBu4F1r+72LNHYH/Z+y9I1Mrjrd/c/Ue5zfDgAEjQ==", + "dev": true, "license": "MIT", + "dependencies": { + "@algolia/client-common": "5.35.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">= 14.0.0" } }, - "node_modules/@babel/helper-member-expression-to-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", - "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", - "devOptional": true, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { - "node": ">=6.9.0" + "node": ">=6.0.0" } }, - "node_modules/@babel/helper-module-imports": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", - "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", - "devOptional": true, + "node_modules/@angular-devkit/architect": { + "version": "0.2003.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.2003.13.tgz", + "integrity": "sha512-JyH6Af6PNC1IHJToColFk1RaXDU87mpPjz7M5sWDfn8bC+KBipw6dSdRkCEuw0D9HY1lZkC9EBV9k9GhpvHjCQ==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/traverse": "^7.27.1", - "@babel/types": "^7.27.1" + "@angular-devkit/core": "20.3.13", + "rxjs": "7.8.2" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", - "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", - "devOptional": true, + "node_modules/@angular-devkit/core": { + "version": "20.3.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-20.3.13.tgz", + "integrity": "sha512-/D84T1Caxll3I2sRihPDR9UaWBhF50M+tAX15PdP6uSh/TxwAlLl9p7Rm1bD0mPjPercqaEKA+h9a9qLP16hug==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1", - "@babel/traverse": "^7.28.3" + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.3", + "rxjs": "7.8.2", + "source-map": "0.7.6" }, "engines": { - "node": ">=6.9.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-optimise-call-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", - "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", - "devOptional": true, - "dependencies": { - "@babel/types": "^7.25.9" + "chokidar": "^4.0.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } } }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", - "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", - "devOptional": true, + "node_modules/@angular-devkit/core/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, "license": "MIT", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-remap-async-to-generator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", - "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", - "devOptional": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-wrap-function": "^7.25.9", - "@babel/traverse": "^7.25.9" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@angular-devkit/core/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/core/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/core/node_modules/picomatch": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz", + "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=12" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/@babel/helper-replace-supers": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", - "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", - "devOptional": true, + "node_modules/@angular-devkit/schematics": { + "version": "20.3.13", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-20.3.13.tgz", + "integrity": "sha512-hdMKY4rUTko8xqeWYGnwwDYDomkeOoLsYsP6SdaHWK7hpGvzWsT6Q/aIv8J8NrCYkLu+M+5nLiKOooweUZu3GQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-member-expression-to-functions": "^7.25.9", - "@babel/helper-optimise-call-expression": "^7.25.9", - "@babel/traverse": "^7.26.5" + "@angular-devkit/core": "20.3.13", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "8.2.0", + "rxjs": "7.8.2" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@babel/helper-skip-transparent-expression-wrappers": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", - "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", - "devOptional": true, - "dependencies": { - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" - }, + "node_modules/@angular-devkit/schematics/node_modules/chalk": { + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz", + "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/@babel/helper-string-parser": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", - "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "devOptional": true, + "node_modules/@angular-devkit/schematics/node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/helper-validator-identifier": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", - "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "node_modules/@angular-devkit/schematics/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/schematics/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular-devkit/schematics/node_modules/log-symbols": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-6.0.0.tgz", + "integrity": "sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==", + "dev": true, "license": "MIT", + "dependencies": { + "chalk": "^5.3.0", + "is-unicode-supported": "^1.3.0" + }, "engines": { - "node": ">=6.9.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/helper-validator-option": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", - "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", - "devOptional": true, + "node_modules/@angular-devkit/schematics/node_modules/log-symbols/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", + "dev": true, "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/helper-wrap-function": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", - "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", - "devOptional": true, + "node_modules/@angular-devkit/schematics/node_modules/ora": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/ora/-/ora-8.2.0.tgz", + "integrity": "sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.25.9", - "@babel/traverse": "^7.25.9", - "@babel/types": "^7.25.9" + "chalk": "^5.3.0", + "cli-cursor": "^5.0.0", + "cli-spinners": "^2.9.2", + "is-interactive": "^2.0.0", + "is-unicode-supported": "^2.0.0", + "log-symbols": "^6.0.0", + "stdin-discarder": "^0.2.2", + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/helpers": { - "version": "7.28.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", - "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", - "devOptional": true, + "node_modules/@angular-devkit/schematics/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, "license": "MIT", "dependencies": { - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.4" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/parser": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", - "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@babel/types": "^7.28.5" + "node_modules/@angular/cli": { + "version": "20.3.13", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-20.3.13.tgz", + "integrity": "sha512-G78I/HDJULloS2LSqfUfbmBlhDCbcWujIRWfuMnGsRf82TyGA2OEPe3IA/F8MrJfeOzPQim2fMyn24MqHL40Vg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.2003.13", + "@angular-devkit/core": "20.3.13", + "@angular-devkit/schematics": "20.3.13", + "@inquirer/prompts": "7.8.2", + "@listr2/prompt-adapter-inquirer": "3.0.1", + "@modelcontextprotocol/sdk": "1.24.0", + "@schematics/angular": "20.3.13", + "@yarnpkg/lockfile": "1.1.0", + "algoliasearch": "5.35.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "9.0.1", + "npm-package-arg": "13.0.0", + "pacote": "21.0.0", + "resolve": "1.22.10", + "semver": "7.7.2", + "yargs": "18.0.0", + "zod": "4.1.13" }, "bin": { - "parser": "bin/babel-parser.js" + "ng": "bin/ng.js" }, "engines": { - "node": ">=6.0.0" + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" } }, - "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", - "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", - "devOptional": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, + "node_modules/@angular/cli/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6.9.0" + "node": ">=12" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", - "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", - "devOptional": true, + "node_modules/@angular/cli/node_modules/cliui": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-9.0.1.tgz", + "integrity": "sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==", + "dev": true, + "license": "ISC", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "string-width": "^7.2.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": ">=20" } }, - "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", - "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", - "devOptional": true, + "node_modules/@angular/cli/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular/cli/node_modules/hosted-git-info": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.2.tgz", + "integrity": "sha512-M422h7o/BR3rmCQ8UHi7cyyMqKltdP9Uo+J2fXK+RSAY+wTcKOIRyhTuKv4qn+DJf3g+PL890AzId5KZpX+CBg==", + "dev": true, + "license": "ISC", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "lru-cache": "^11.1.0" }, "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "node": "^20.17.0 || >=22.9.0" } }, - "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", - "devOptional": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9" - }, + "node_modules/@angular/cli/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.13.0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", - "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", - "devOptional": true, + "node_modules/@angular/cli/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular/cli/node_modules/lru-cache": { + "version": "11.2.4", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.2.4.tgz", + "integrity": "sha512-B5Y16Jr9LB9dHVkh6ZevG+vAbOsNOYCX+sXvFWFu7B3Iz5mijW3zdbMyhsh8ANd2mSWBYdJgnqi+mL7/LrOPYg==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, + "node_modules/@angular/cli/node_modules/npm-package-arg": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-13.0.0.tgz", + "integrity": "sha512-+t2etZAGcB7TbbLHfDwooV9ppB2LhhcT6A+L9cahsf9mEUAoQ6CktLEVvEnpD0N5CkX7zJqnPGaFtoQDy9EkHQ==", + "dev": true, + "license": "ISC", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" + "hosted-git-info": "^9.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" }, "engines": { - "node": ">=6.9.0" + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/@angular/cli/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@angular/cli/node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" }, - "peerDependencies": { - "@babel/core": "^7.0.0" + "engines": { + "node": ">=10" } }, - "node_modules/@babel/plugin-proposal-decorators": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", - "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", - "devOptional": true, + "node_modules/@angular/cli/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/plugin-syntax-decorators": "^7.25.9" + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=18" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@babel/plugin-proposal-private-property-in-object": { - "version": "7.21.0-placeholder-for-preset-env.2", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", - "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", - "devOptional": true, + "node_modules/@angular/cli/node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", + "dev": true, + "license": "ISC", "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "node_modules/@angular/cli/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "node_modules/@angular/cli/node_modules/yargs": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-18.0.0.tgz", + "integrity": "sha512-4UEqdc2RYGHZc7Doyqkrqiln3p9X2DZVxaGbwhn2pi7MrRagKaOcIKe8L3OxYcbhXLgLFUS3zAYuQjKBQgmuNg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "cliui": "^9.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "string-width": "^7.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^22.0.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "node_modules/@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "node_modules/@angular/cli/node_modules/yargs-parser": { + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-22.0.0.tgz", + "integrity": "sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==", "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "license": "ISC", + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=23" } }, - "node_modules/@babel/plugin-syntax-class-static-block": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", - "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "node_modules/@angular/cli/node_modules/zod": { + "version": "4.1.13", + "resolved": "https://registry.npmjs.org/zod/-/zod-4.1.13.tgz", + "integrity": "sha512-AvvthqfqrAhNH9dnfmrfKzX5upOdjUVJYFqNSlkmGf64gRaTzlPwz99IHYnVs28qYAybvAlBV+H7pn0saFY4Ig==", "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/@asamuzakjp/css-color": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@asamuzakjp/css-color/-/css-color-3.2.0.tgz", + "integrity": "sha512-K1A6z8tS3XsmCMM86xoWdn7Fkdn9m6RSVtocUrJYIwZnFVkng/PvkEoWtOWmP+Scc6saYWHWZYbndEEXxl24jw==", + "devOptional": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@csstools/css-calc": "^2.1.3", + "@csstools/css-color-parser": "^3.0.9", + "@csstools/css-parser-algorithms": "^3.0.4", + "@csstools/css-tokenizer": "^3.0.3", + "lru-cache": "^10.4.3" } }, - "node_modules/@babel/plugin-syntax-decorators": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", - "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", + "node_modules/@asamuzakjp/css-color/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "devOptional": true, + "license": "ISC" + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-assertions": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", - "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", + "node_modules/@babel/compat-data": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz", + "integrity": "sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==", "devOptional": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", - "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "node_modules/@babel/core": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz", + "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "devOptional": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-module-transforms": "^7.28.3", + "@babel/helpers": "^7.28.4", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/traverse": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/remapping": "^2.3.5", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" } }, - "node_modules/@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", - "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", + "node_modules/@babel/generator": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.5.tgz", + "integrity": "sha512-3EwLFhZ38J4VyIP6WNtt2kUdW9dokXA9Cr4IVIFHuCpZ3H8/YFOl5JjZHisrn1fATPBmKKqXzDFvh9fUwHz6CQ==", "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/parser": "^7.28.5", + "@babel/types": "^7.28.5", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" + "@babel/types": "^7.25.9" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "devOptional": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz", + "integrity": "sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ==", + "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz", + "integrity": "sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong==", + "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.3.tgz", + "integrity": "sha512-HK7Bi+Hj6H+VTHA3ZvBis7V/6hu9QuTrnMXNybfUf2iiuU/N97I8VjB+KbhFF8Rld/Lx5MzoCwPCpPjfK+n8Cg==", + "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" + "@babel/helper-compilation-targets": "^7.22.6", + "@babel/helper-plugin-utils": "^7.22.5", + "debug": "^4.1.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.14.2" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" } }, - "node_modules/@babel/plugin-syntax-private-property-in-object": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", - "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "devOptional": true, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz", + "integrity": "sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ==", + "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-typescript": { + "node_modules/@babel/helper-module-imports": { "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", - "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-syntax-unicode-sets-regex": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", - "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "node_modules/@babel/helper-module-transforms": { + "version": "7.28.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz", + "integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==", "devOptional": true, + "license": "MIT", "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.18.6", - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.28.3" }, "engines": { "node": ">=6.9.0" @@ -917,167 +1057,168 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-arrow-functions": { + "node_modules/@babel/helper-optimise-call-expression": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", - "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz", + "integrity": "sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-generator-functions": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", - "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", "devOptional": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-remap-async-to-generator": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-async-to-generator": { + "node_modules/@babel/helper-remap-async-to-generator": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", - "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz", + "integrity": "sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw==", "devOptional": true, "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-remap-async-to-generator": "^7.25.9" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-wrap-function": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-block-scoped-functions": { + "node_modules/@babel/helper-replace-supers": { "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", - "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.26.5.tgz", + "integrity": "sha512-bJ6iIVdYX1YooY2X7w1q6VITt+LnUILtNk7zT78ykuwStx8BauCzxvFqFaHjOpW1bVnSUM1PN1f0p5P21wHxvg==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-member-expression-to-functions": "^7.25.9", + "@babel/helper-optimise-call-expression": "^7.25.9", + "@babel/traverse": "^7.26.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-block-scoping": { + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", - "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz", + "integrity": "sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/traverse": "^7.25.9", + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-class-properties": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", - "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", "devOptional": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-class-static-block": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", - "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", + "node_modules/@babel/helper-validator-identifier": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", "devOptional": true, - "dependencies": { - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" - }, + "license": "MIT", "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.12.0" } }, - "node_modules/@babel/plugin-transform-classes": { + "node_modules/@babel/helper-wrap-function": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", - "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz", + "integrity": "sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g==", "devOptional": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9", + "@babel/template": "^7.25.9", "@babel/traverse": "^7.25.9", - "globals": "^11.1.0" + "@babel/types": "^7.25.9" }, "engines": { "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.28.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.4.tgz", + "integrity": "sha512-HFN59MmQXGHVyYadKLVumYsA9dBFun/ldYxipEjzA4196jpLZd8UjEEBLkbEkvfYreDqJhZxYAWFPtrfhNpj4w==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.4" }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" + "engines": { + "node": ">=6.9.0" } }, - "node_modules/@babel/plugin-transform-classes/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "node_modules/@babel/parser": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "devOptional": true, "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.5" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, "engines": { - "node": ">=4" + "node": ">=6.0.0" } }, - "node_modules/@babel/plugin-transform-computed-properties": { + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", - "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz", + "integrity": "sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", - "@babel/template": "^7.25.9" + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-destructuring": { + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", - "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz", + "integrity": "sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1086,48 +1227,49 @@ "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-dotall-regex": { + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", - "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz", + "integrity": "sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug==", "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-duplicate-keys": { + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", - "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.13.0" } }, - "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", - "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz", + "integrity": "sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg==", "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1136,13 +1278,15 @@ "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-dynamic-import": { + "node_modules/@babel/plugin-proposal-decorators": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", - "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.25.9.tgz", + "integrity": "sha512-smkNLL/O1ezy9Nhy4CNosc4Va+1wo5w4gzSZeLe6y6dM4mmHfYOCPolXQPHQxonZCF+ZyebxN9vqOolkYrSn5g==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-syntax-decorators": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1151,14 +1295,11 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-exponentiation-operator": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", - "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", "devOptional": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, "engines": { "node": ">=6.9.0" }, @@ -1166,61 +1307,49 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-export-namespace-from": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", - "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-for-of": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", - "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-function-name": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", - "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/traverse": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.12.13" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-json-strings": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", - "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-class-static-block": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz", + "integrity": "sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw==", + "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1229,10 +1358,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-literals": { + "node_modules/@babel/plugin-syntax-decorators": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", - "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.25.9.tgz", + "integrity": "sha512-ryzI0McXUPJnRCvMo4lumIKZUzhYUO/ScI+Mz4YVaTLt04DHNSjEUjKVvbzQjZFLuod/cYEc07mJWhzl6v4DPg==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1244,10 +1373,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-logical-assignment-operators": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", - "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz", + "integrity": "sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1259,10 +1388,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-member-expression-literals": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", - "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1274,30 +1403,38 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-amd": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", - "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" - }, - "engines": { - "node": ">=6.9.0" + "@babel/helper-plugin-utils": "^7.10.4" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-commonjs": { - "version": "7.26.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", - "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-jsx": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.27.1.tgz", + "integrity": "sha512-y8YTNIeKoyhGd9O0Jiyzyyqk8gdjnumGTQPsz0xOZOQ2RmkVJeZ1vmmfIvFEKqucBG6axJGBZDE/7iI5suUI/w==", "devOptional": true, + "license": "MIT", "dependencies": { - "@babel/helper-module-transforms": "^7.26.0", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1306,63 +1443,100 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-systemjs": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", - "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-identifier": "^7.25.9", - "@babel/traverse": "^7.25.9" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-modules-umd": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", - "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, "dependencies": { - "@babel/helper-module-transforms": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.10.4" }, - "engines": { - "node": ">=6.9.0" + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", - "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-private-property-in-object": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz", + "integrity": "sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-new-target": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", - "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", - "devOptional": true, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.14.5" }, "engines": { "node": ">=6.9.0" @@ -1371,13 +1545,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.5.tgz", - "integrity": "sha512-OHqczNm4NTQlW1ghrVY43FPoiRzbmzNVbcgVnMKZN/RQYezHUSdjACjaX50CD3B7UIAjv39+MlsrVDb3v741FA==", + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.27.1.tgz", + "integrity": "sha512-xfYCBMxveHrRMnAWl1ZlPXOZjzkN82THFvLhQhFXFt81Z5HnN+EtUkZhv/zcKpmT3fzmWZB0ywiBrbC3vogbwQ==", "devOptional": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.26.5" + "@babel/helper-plugin-utils": "^7.27.1" }, "engines": { "node": ">=6.9.0" @@ -1386,30 +1561,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-numeric-separator": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", - "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-object-rest-spread": { + "node_modules/@babel/plugin-transform-arrow-functions": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", - "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz", + "integrity": "sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg==", "devOptional": true, "dependencies": { - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1418,14 +1592,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-object-super": { + "node_modules/@babel/plugin-transform-async-generator-functions": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", - "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz", + "integrity": "sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-replace-supers": "^7.25.9" + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1434,13 +1609,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-optional-catch-binding": { + "node_modules/@babel/plugin-transform-async-to-generator": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", - "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1449,14 +1626,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-optional-chaining": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", - "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.26.5.tgz", + "integrity": "sha512-chuTSY+hq09+/f5lMj8ZSYgCFpppV2CbYrhNFJ1BFoXpiWPnnAb7R0MqrafCpN8E1+YRrtM1MXZHJdIx8B6rMQ==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" @@ -1465,10 +1641,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-parameters": { + "node_modules/@babel/plugin-transform-block-scoping": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", - "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz", + "integrity": "sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1480,10 +1656,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-private-methods": { + "node_modules/@babel/plugin-transform-class-properties": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", - "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz", + "integrity": "sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q==", "devOptional": true, "dependencies": { "@babel/helper-create-class-features-plugin": "^7.25.9", @@ -1496,13 +1672,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-private-property-in-object": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", - "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz", + "integrity": "sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ==", "devOptional": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", "@babel/helper-create-class-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, @@ -1510,16 +1685,21 @@ "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.12.0" } }, - "node_modules/@babel/plugin-transform-property-literals": { + "node_modules/@babel/plugin-transform-classes": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", - "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz", + "integrity": "sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9", + "@babel/traverse": "^7.25.9", + "globals": "^11.1.0" }, "engines": { "node": ">=6.9.0" @@ -1528,14 +1708,24 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-regenerator": { + "node_modules/@babel/plugin-transform-classes/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", - "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz", + "integrity": "sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9", - "regenerator-transform": "^0.15.2" + "@babel/template": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1544,28 +1734,28 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-regexp-modifiers": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", - "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz", + "integrity": "sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ==", "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-reserved-words": { + "node_modules/@babel/plugin-transform-dotall-regex": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", - "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz", + "integrity": "sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA==", "devOptional": true, "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -1575,18 +1765,13 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime": { + "node_modules/@babel/plugin-transform-duplicate-keys": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", - "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz", + "integrity": "sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw==", "devOptional": true, "dependencies": { - "@babel/helper-module-imports": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "semver": "^6.3.1" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1595,38 +1780,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/plugin-transform-shorthand-properties": { + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", - "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog==", "devOptional": true, "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0" + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/plugin-transform-spread": { + "node_modules/@babel/plugin-transform-dynamic-import": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", - "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz", + "integrity": "sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1635,10 +1811,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-sticky-regex": { - "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", - "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz", + "integrity": "sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1650,10 +1826,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-template-literals": { + "node_modules/@babel/plugin-transform-export-namespace-from": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", - "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz", + "integrity": "sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1665,13 +1841,14 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-typeof-symbol": { + "node_modules/@babel/plugin-transform-for-of": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", - "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz", + "integrity": "sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.25.9" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1680,17 +1857,15 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-typescript": { - "version": "7.26.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz", - "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==", + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz", + "integrity": "sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA==", "devOptional": true, "dependencies": { - "@babel/helper-annotate-as-pure": "^7.25.9", - "@babel/helper-create-class-features-plugin": "^7.25.9", - "@babel/helper-plugin-utils": "^7.26.5", - "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", - "@babel/plugin-syntax-typescript": "^7.25.9" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1699,10 +1874,10 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-escapes": { + "node_modules/@babel/plugin-transform-json-strings": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", - "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz", + "integrity": "sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw==", "devOptional": true, "dependencies": { "@babel/helper-plugin-utils": "^7.25.9" @@ -1714,13 +1889,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-property-regex": { + "node_modules/@babel/plugin-transform-literals": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", - "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz", + "integrity": "sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ==", "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -1730,13 +1904,12 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-regex": { + "node_modules/@babel/plugin-transform-logical-assignment-operators": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", - "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz", + "integrity": "sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q==", "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { @@ -1746,97 +1919,29 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "node_modules/@babel/plugin-transform-member-expression-literals": { "version": "7.25.9", - "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", - "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz", + "integrity": "sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA==", "devOptional": true, "dependencies": { - "@babel/helper-create-regexp-features-plugin": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", - "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz", + "integrity": "sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw==", "devOptional": true, "dependencies": { - "@babel/compat-data": "^7.26.0", - "@babel/helper-compilation-targets": "^7.25.9", - "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", - "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", - "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", - "@babel/plugin-syntax-import-assertions": "^7.26.0", - "@babel/plugin-syntax-import-attributes": "^7.26.0", - "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", - "@babel/plugin-transform-arrow-functions": "^7.25.9", - "@babel/plugin-transform-async-generator-functions": "^7.25.9", - "@babel/plugin-transform-async-to-generator": "^7.25.9", - "@babel/plugin-transform-block-scoped-functions": "^7.25.9", - "@babel/plugin-transform-block-scoping": "^7.25.9", - "@babel/plugin-transform-class-properties": "^7.25.9", - "@babel/plugin-transform-class-static-block": "^7.26.0", - "@babel/plugin-transform-classes": "^7.25.9", - "@babel/plugin-transform-computed-properties": "^7.25.9", - "@babel/plugin-transform-destructuring": "^7.25.9", - "@babel/plugin-transform-dotall-regex": "^7.25.9", - "@babel/plugin-transform-duplicate-keys": "^7.25.9", - "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-dynamic-import": "^7.25.9", - "@babel/plugin-transform-exponentiation-operator": "^7.25.9", - "@babel/plugin-transform-export-namespace-from": "^7.25.9", - "@babel/plugin-transform-for-of": "^7.25.9", - "@babel/plugin-transform-function-name": "^7.25.9", - "@babel/plugin-transform-json-strings": "^7.25.9", - "@babel/plugin-transform-literals": "^7.25.9", - "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", - "@babel/plugin-transform-member-expression-literals": "^7.25.9", - "@babel/plugin-transform-modules-amd": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.25.9", - "@babel/plugin-transform-modules-systemjs": "^7.25.9", - "@babel/plugin-transform-modules-umd": "^7.25.9", - "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", - "@babel/plugin-transform-new-target": "^7.25.9", - "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", - "@babel/plugin-transform-numeric-separator": "^7.25.9", - "@babel/plugin-transform-object-rest-spread": "^7.25.9", - "@babel/plugin-transform-object-super": "^7.25.9", - "@babel/plugin-transform-optional-catch-binding": "^7.25.9", - "@babel/plugin-transform-optional-chaining": "^7.25.9", - "@babel/plugin-transform-parameters": "^7.25.9", - "@babel/plugin-transform-private-methods": "^7.25.9", - "@babel/plugin-transform-private-property-in-object": "^7.25.9", - "@babel/plugin-transform-property-literals": "^7.25.9", - "@babel/plugin-transform-regenerator": "^7.25.9", - "@babel/plugin-transform-regexp-modifiers": "^7.26.0", - "@babel/plugin-transform-reserved-words": "^7.25.9", - "@babel/plugin-transform-shorthand-properties": "^7.25.9", - "@babel/plugin-transform-spread": "^7.25.9", - "@babel/plugin-transform-sticky-regex": "^7.25.9", - "@babel/plugin-transform-template-literals": "^7.25.9", - "@babel/plugin-transform-typeof-symbol": "^7.25.9", - "@babel/plugin-transform-unicode-escapes": "^7.25.9", - "@babel/plugin-transform-unicode-property-regex": "^7.25.9", - "@babel/plugin-transform-unicode-regex": "^7.25.9", - "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", - "@babel/preset-modules": "0.1.6-no-external-plugins", - "babel-plugin-polyfill-corejs2": "^0.4.10", - "babel-plugin-polyfill-corejs3": "^0.10.6", - "babel-plugin-polyfill-regenerator": "^0.6.1", - "core-js-compat": "^3.38.1", - "semver": "^6.3.1" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1845,40 +1950,32 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-env/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/preset-modules": { - "version": "0.1.6-no-external-plugins", - "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", - "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.26.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz", + "integrity": "sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ==", "devOptional": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.0.0", - "@babel/types": "^7.4.4", - "esutils": "^2.0.2" + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/preset-typescript": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", - "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz", + "integrity": "sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA==", "devOptional": true, "dependencies": { + "@babel/helper-module-transforms": "^7.25.9", "@babel/helper-plugin-utils": "^7.25.9", - "@babel/helper-validator-option": "^7.25.9", - "@babel/plugin-syntax-jsx": "^7.25.9", - "@babel/plugin-transform-modules-commonjs": "^7.25.9", - "@babel/plugin-transform-typescript": "^7.25.9" + "@babel/helper-validator-identifier": "^7.25.9", + "@babel/traverse": "^7.25.9" }, "engines": { "node": ">=6.9.0" @@ -1887,184 +1984,751 @@ "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/runtime": { - "version": "7.26.0", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", - "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz", + "integrity": "sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw==", "devOptional": true, "dependencies": { - "regenerator-runtime": "^0.14.0" + "@babel/helper-module-transforms": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/template": { - "version": "7.27.2", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", - "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz", + "integrity": "sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA==", "devOptional": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/parser": "^7.27.2", - "@babel/types": "^7.27.1" + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" } }, - "node_modules/@babel/traverse": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", - "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz", + "integrity": "sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ==", "devOptional": true, - "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.27.1", - "@babel/generator": "^7.28.5", - "@babel/helper-globals": "^7.28.0", - "@babel/parser": "^7.28.5", - "@babel/template": "^7.27.2", - "@babel/types": "^7.28.5", - "debug": "^4.3.1" + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@babel/types": { - "version": "7.28.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", - "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.26.5.tgz", + "integrity": "sha512-OHqczNm4NTQlW1ghrVY43FPoiRzbmzNVbcgVnMKZN/RQYezHUSdjACjaX50CD3B7UIAjv39+MlsrVDb3v741FA==", "devOptional": true, - "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.28.5" + "@babel/helper-plugin-utils": "^7.26.5" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "node_modules/@borewit/text-codec": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", - "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", - "dev": true, - "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/Borewit" + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz", + "integrity": "sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cacheable/memory": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.6.tgz", - "integrity": "sha512-7e8SScMocHxcAb8YhtkbMhGG+EKLRIficb1F5sjvhSYsWTZGxvg4KIDp8kgxnV2PUJ3ddPe6J9QESjKvBWRDkg==", - "license": "MIT", + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz", + "integrity": "sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg==", + "devOptional": true, "dependencies": { - "@cacheable/utils": "^2.3.2", - "@keyv/bigmap": "^1.3.0", - "hookified": "^1.13.0", - "keyv": "^5.5.4" + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.0.tgz", - "integrity": "sha512-KT01GjzV6AQD5+IYrcpoYLkCu1Jod3nau1Z7EsEuViO3TZGRacSbO9MfHmbJ1WaOXFtWLxPVj169cn2WNKPkIg==", - "license": "MIT", + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz", + "integrity": "sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A==", + "devOptional": true, "dependencies": { - "hashery": "^1.2.0", - "hookified": "^1.13.0" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-replace-supers": "^7.25.9" }, "engines": { - "node": ">= 18" + "node": ">=6.9.0" }, "peerDependencies": { - "keyv": "^5.5.4" + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cacheable/memory/node_modules/keyv": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", - "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", - "license": "MIT", + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz", + "integrity": "sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g==", + "devOptional": true, "dependencies": { - "@keyv/serialize": "^1.1.1" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cacheable/utils": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.2.tgz", - "integrity": "sha512-8kGE2P+HjfY8FglaOiW+y8qxcaQAfAhVML+i66XJR3YX5FtyDqn6Txctr3K2FrbxLKixRRYYBWMbuGciOhYNDg==", - "license": "MIT", + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz", + "integrity": "sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A==", + "devOptional": true, "dependencies": { - "hashery": "^1.2.0", - "keyv": "^5.5.4" + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@cacheable/utils/node_modules/keyv": { - "version": "5.5.5", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", - "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", - "license": "MIT", + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz", + "integrity": "sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g==", + "devOptional": true, "dependencies": { - "@keyv/serialize": "^1.1.1" + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@code-pushup/cli": { - "version": "0.92.1", - "resolved": "https://registry.npmjs.org/@code-pushup/cli/-/cli-0.92.1.tgz", - "integrity": "sha512-r4HmP4hGKFNUNXwSD6SqMfWdtBEJBckKIKaxbDUWWE1emwD+9LUkDopfogo2F672YwvEUOCdnreLyHRjVznhYw==", - "license": "MIT", + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz", + "integrity": "sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw==", + "devOptional": true, "dependencies": { - "@code-pushup/core": "0.92.1", - "@code-pushup/models": "0.92.1", - "@code-pushup/utils": "0.92.1", - "ansis": "^3.3.0", - "simple-git": "^3.20.0", - "yargs": "^17.7.2" - }, - "bin": { - "code-pushup": "src/index.js" + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" }, "engines": { - "node": ">=20" + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@code-pushup/core": { - "version": "0.92.1", - "resolved": "https://registry.npmjs.org/@code-pushup/core/-/core-0.92.1.tgz", - "integrity": "sha512-r6JtGj8iceFFQnZZbwOhLXOX/7rhQu2oNTg6dfXkpGjsArH1bLZtJcQBUTJ3rqimVIb5OKt/X5hn6PjiMagpbA==", - "license": "MIT", + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz", + "integrity": "sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw==", + "devOptional": true, "dependencies": { - "@code-pushup/models": "0.92.1", - "@code-pushup/utils": "0.92.1", - "ansis": "^3.3.0" + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" }, "peerDependencies": { - "@code-pushup/portal-client": "^0.16.0" + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz", + "integrity": "sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" }, - "peerDependenciesMeta": { - "@code-pushup/portal-client": { - "optional": true - } + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" } }, - "node_modules/@code-pushup/eslint-config": { - "version": "0.14.8", - "resolved": "https://registry.npmjs.org/@code-pushup/eslint-config/-/eslint-config-0.14.8.tgz", - "integrity": "sha512-vV7giWopcb04d7YEugqqdhNUyzC8zdGeRBo8W5rRXLyOA1SH7cWZtYuzOmZg/i8Bxx4MFANW8agiw3aGSqikfg==", - "dev": true, - "license": "MIT", + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz", + "integrity": "sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "regenerator-transform": "^0.15.2" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz", + "integrity": "sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw==", + "devOptional": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz", + "integrity": "sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.25.9.tgz", + "integrity": "sha512-nZp7GlEl+yULJrClz0SwHPqir3lc0zsPrDHQUcxGspSL7AKrexNSEfTbfqnDNJUO13bgKyfuOLMF8Xqtu8j3YQ==", + "devOptional": true, + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz", + "integrity": "sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz", + "integrity": "sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz", + "integrity": "sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz", + "integrity": "sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz", + "integrity": "sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typescript": { + "version": "7.26.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.5.tgz", + "integrity": "sha512-GJhPO0y8SD5EYVCy2Zr+9dSZcEgaSmq5BLR0Oc25TOEhC+ba49vUAGZFjy8v79z9E1mdldq4x9d1xgh4L1d5dQ==", + "devOptional": true, + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.25.9", + "@babel/helper-create-class-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-skip-transparent-expression-wrappers": "^7.25.9", + "@babel/plugin-syntax-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz", + "integrity": "sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz", + "integrity": "sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg==", + "devOptional": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz", + "integrity": "sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA==", + "devOptional": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz", + "integrity": "sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ==", + "devOptional": true, + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.0.tgz", + "integrity": "sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw==", + "devOptional": true, + "dependencies": { + "@babel/compat-data": "^7.26.0", + "@babel/helper-compilation-targets": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.25.9", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.25.9", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.25.9", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.25.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.25.9", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.25.9", + "@babel/plugin-transform-typeof-symbol": "^7.25.9", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.10.6", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.38.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "devOptional": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/preset-typescript": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz", + "integrity": "sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==", + "devOptional": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-syntax-jsx": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.25.9", + "@babel/plugin-transform-typescript": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.0.tgz", + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "devOptional": true, + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.5.tgz", + "integrity": "sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.5", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.5", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.5", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.28.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@borewit/text-codec": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@borewit/text-codec/-/text-codec-0.1.1.tgz", + "integrity": "sha512-5L/uBxmjaCIX5h8Z+uu+kA9BQLkc/Wl06UGR5ajNRxu+/XjonB5i8JpgFMrPj3LXTCPA0pv8yxUvbUi+QthGGA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/@cacheable/memory": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@cacheable/memory/-/memory-2.0.6.tgz", + "integrity": "sha512-7e8SScMocHxcAb8YhtkbMhGG+EKLRIficb1F5sjvhSYsWTZGxvg4KIDp8kgxnV2PUJ3ddPe6J9QESjKvBWRDkg==", + "license": "MIT", + "dependencies": { + "@cacheable/utils": "^2.3.2", + "@keyv/bigmap": "^1.3.0", + "hookified": "^1.13.0", + "keyv": "^5.5.4" + } + }, + "node_modules/@cacheable/memory/node_modules/@keyv/bigmap": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@keyv/bigmap/-/bigmap-1.3.0.tgz", + "integrity": "sha512-KT01GjzV6AQD5+IYrcpoYLkCu1Jod3nau1Z7EsEuViO3TZGRacSbO9MfHmbJ1WaOXFtWLxPVj169cn2WNKPkIg==", + "license": "MIT", + "dependencies": { + "hashery": "^1.2.0", + "hookified": "^1.13.0" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "keyv": "^5.5.4" + } + }, + "node_modules/@cacheable/memory/node_modules/keyv": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", + "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@cacheable/utils": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@cacheable/utils/-/utils-2.3.2.tgz", + "integrity": "sha512-8kGE2P+HjfY8FglaOiW+y8qxcaQAfAhVML+i66XJR3YX5FtyDqn6Txctr3K2FrbxLKixRRYYBWMbuGciOhYNDg==", + "license": "MIT", + "dependencies": { + "hashery": "^1.2.0", + "keyv": "^5.5.4" + } + }, + "node_modules/@cacheable/utils/node_modules/keyv": { + "version": "5.5.5", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-5.5.5.tgz", + "integrity": "sha512-FA5LmZVF1VziNc0bIdCSA1IoSVnDCqE8HJIZZv2/W8YmoAM50+tnUgJR/gQZwEeIMleuIOnRnHA/UaZRNeV4iQ==", + "license": "MIT", + "dependencies": { + "@keyv/serialize": "^1.1.1" + } + }, + "node_modules/@code-pushup/bundle-stats-plugin": { + "resolved": "packages/plugin-bundle-stats", + "link": true + }, + "node_modules/@code-pushup/cli": { + "version": "0.92.1", + "resolved": "https://registry.npmjs.org/@code-pushup/cli/-/cli-0.92.1.tgz", + "integrity": "sha512-r4HmP4hGKFNUNXwSD6SqMfWdtBEJBckKIKaxbDUWWE1emwD+9LUkDopfogo2F672YwvEUOCdnreLyHRjVznhYw==", + "license": "MIT", + "dependencies": { + "@code-pushup/core": "0.92.1", + "@code-pushup/models": "0.92.1", + "@code-pushup/utils": "0.92.1", + "ansis": "^3.3.0", + "simple-git": "^3.20.0", + "yargs": "^17.7.2" + }, + "bin": { + "code-pushup": "src/index.js" + }, + "engines": { + "node": ">=20" + } + }, + "node_modules/@code-pushup/core": { + "version": "0.92.1", + "resolved": "https://registry.npmjs.org/@code-pushup/core/-/core-0.92.1.tgz", + "integrity": "sha512-r6JtGj8iceFFQnZZbwOhLXOX/7rhQu2oNTg6dfXkpGjsArH1bLZtJcQBUTJ3rqimVIb5OKt/X5hn6PjiMagpbA==", + "license": "MIT", + "dependencies": { + "@code-pushup/models": "0.92.1", + "@code-pushup/utils": "0.92.1", + "ansis": "^3.3.0" + }, + "peerDependencies": { + "@code-pushup/portal-client": "^0.16.0" + }, + "peerDependenciesMeta": { + "@code-pushup/portal-client": { + "optional": true + } + } + }, + "node_modules/@code-pushup/eslint-config": { + "version": "0.14.8", + "resolved": "https://registry.npmjs.org/@code-pushup/eslint-config/-/eslint-config-0.14.8.tgz", + "integrity": "sha512-vV7giWopcb04d7YEugqqdhNUyzC8zdGeRBo8W5rRXLyOA1SH7cWZtYuzOmZg/i8Bxx4MFANW8agiw3aGSqikfg==", + "dev": true, + "license": "MIT", "peerDependencies": { "@eslint/js": "^9.0.0", "@graphql-eslint/eslint-plugin": "^3.0.0", @@ -2522,791 +3186,1236 @@ "node": ">= 6" } }, - "node_modules/@cypress/request/node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", - "dev": true, - "license": "BSD-3-Clause", - "optional": true, - "peer": true, + "node_modules/@dual-bundle/import-meta-resolve": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz", + "integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/JounQin" + } + }, + "node_modules/@emnapi/core": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", + "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", + "devOptional": true, + "license": "MIT", "dependencies": { - "side-channel": "^1.1.0" - }, + "@emnapi/wasi-threads": "1.1.0", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", + "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", + "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", + "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "cpu": [ + "ppc64" + ], + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", + "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", + "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", + "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", + "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", + "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", + "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", + "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", + "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", + "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", + "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", + "cpu": [ + "ia32" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", + "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", + "cpu": [ + "loong64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", + "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", + "cpu": [ + "mips64el" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@dual-bundle/import-meta-resolve": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.2.1.tgz", - "integrity": "sha512-id+7YRUgoUX6CgV0DtuhirQWodeeA7Lf4i2x71JS/vtA5pRb/hIGWlw+G6MeXvsM+MXrz0VAydTGElX1rAfgPg==", + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", + "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", + "cpu": [ + "ppc64" + ], "license": "MIT", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/JounQin" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@emnapi/core": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.7.1.tgz", - "integrity": "sha512-o1uhUASyo921r2XtHYOHy7gdkGLge8ghBEQHMWmyJFoXlpU58kIrhhN3w26lpQb6dspetweapMn2CSNwQ8I4wg==", - "devOptional": true, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", + "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", + "cpu": [ + "riscv64" + ], "license": "MIT", - "dependencies": { - "@emnapi/wasi-threads": "1.1.0", - "tslib": "^2.4.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@emnapi/runtime": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.7.1.tgz", - "integrity": "sha512-PVtJr5CmLwYAU9PZDMITZoR5iAOShYREoR45EyyLrbntV50mdePTgUn4AmOw90Ifcj+x2kRjdzr1HP3RrNiHGA==", - "devOptional": true, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", + "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", + "cpu": [ + "s390x" + ], "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@emnapi/wasi-threads": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.1.0.tgz", - "integrity": "sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==", - "devOptional": true, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.12", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", + "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", + "cpu": [ + "x64" + ], "license": "MIT", - "dependencies": { - "tslib": "^2.4.0" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" } }, - "node_modules/@esbuild/aix-ppc64": { + "node_modules/@esbuild/netbsd-arm64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.12.tgz", - "integrity": "sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", + "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", "cpu": [ - "ppc64" + "arm64" ], "license": "MIT", "optional": true, "os": [ - "aix" + "netbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-arm": { + "node_modules/@esbuild/netbsd-x64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.12.tgz", - "integrity": "sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", + "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", "cpu": [ - "arm" + "x64" ], "license": "MIT", "optional": true, "os": [ - "android" + "netbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-arm64": { + "node_modules/@esbuild/openbsd-arm64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.12.tgz", - "integrity": "sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", + "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "android" + "openbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/android-x64": { + "node_modules/@esbuild/openbsd-x64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.12.tgz", - "integrity": "sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", + "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "android" + "openbsd" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/darwin-arm64": { + "node_modules/@esbuild/openharmony-arm64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.12.tgz", - "integrity": "sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", + "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "darwin" + "openharmony" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/darwin-x64": { + "node_modules/@esbuild/sunos-x64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.12.tgz", - "integrity": "sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", + "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", "cpu": [ "x64" ], "license": "MIT", "optional": true, "os": [ - "darwin" + "sunos" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/freebsd-arm64": { + "node_modules/@esbuild/win32-arm64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.12.tgz", - "integrity": "sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", + "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", "cpu": [ "arm64" ], "license": "MIT", "optional": true, "os": [ - "freebsd" + "win32" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/freebsd-x64": { + "node_modules/@esbuild/win32-ia32": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.12.tgz", - "integrity": "sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", + "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", "cpu": [ - "x64" + "ia32" ], "license": "MIT", "optional": true, "os": [ - "freebsd" + "win32" ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/linux-arm": { + "node_modules/@esbuild/win32-x64": { "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.12.tgz", - "integrity": "sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", + "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", "cpu": [ - "arm" + "x64" ], "license": "MIT", "optional": true, "os": [ - "linux" + "win32" ], "engines": { - "node": ">=18" + "node": ">=18" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", + "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "eslint-visitor-keys": "^3.4.3" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.12.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", + "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "dev": true, + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + } + }, + "node_modules/@eslint/config-array": { + "version": "0.21.1", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", + "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/object-schema": "^2.1.7", + "debug": "^4.3.1", + "minimatch": "^3.1.2" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/config-array/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/config-helpers": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + } + }, + "node_modules/@eslint/core": { + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@types/json-schema": "^7.0.15" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.12.tgz", - "integrity": "sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==", - "cpu": [ - "arm64" - ], + "node_modules/@eslint/eslintrc": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", + "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.1", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.12.tgz", - "integrity": "sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==", - "cpu": [ - "ia32" - ], + "node_modules/@eslint/eslintrc/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", + "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.12.tgz", - "integrity": "sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==", - "cpu": [ - "loong64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@eslint/eslintrc/node_modules/espree": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", + "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.15.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^4.2.1" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.12.tgz", - "integrity": "sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==", - "cpu": [ - "mips64el" - ], + "node_modules/@eslint/eslintrc/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.12.tgz", - "integrity": "sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==", - "cpu": [ - "ppc64" - ], + "node_modules/@eslint/eslintrc/node_modules/js-yaml": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", + "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, "engines": { - "node": ">=18" + "node": "*" } }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.12.tgz", - "integrity": "sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==", - "cpu": [ - "riscv64" - ], + "node_modules/@eslint/js": { + "version": "9.39.1", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", + "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "linux" - ], "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" } }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.12.tgz", - "integrity": "sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==", - "cpu": [ - "s390x" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@eslint/object-schema": { + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/linux-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.12.tgz", - "integrity": "sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], + "node_modules/@eslint/plugin-kit": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0", + "levn": "^0.4.1" + }, "engines": { - "node": ">=18" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.12.tgz", - "integrity": "sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==", - "cpu": [ - "arm64" - ], + "node_modules/@fastify/busboy": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", + "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], "engines": { - "node": ">=18" + "node": ">=14" } }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.12.tgz", - "integrity": "sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==", - "cpu": [ - "x64" - ], + "node_modules/@graphql-typed-document-node/core": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", + "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" + "peerDependencies": { + "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" } }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.12.tgz", - "integrity": "sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "node_modules/@humanfs/core": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", + "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18.0" } }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.12.tgz", - "integrity": "sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], + "node_modules/@humanfs/node": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", + "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@humanfs/core": "^0.19.1", + "@humanwhocodes/retry": "^0.4.0" + }, "engines": { - "node": ">=18" + "node": ">=18.18.0" } }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.12.tgz", - "integrity": "sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==", - "cpu": [ - "arm64" - ], - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], + "node_modules/@humanwhocodes/module-importer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", + "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, "engines": { - "node": ">=18" + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.12.tgz", - "integrity": "sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], + "node_modules/@humanwhocodes/retry": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", + "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=18" + "node": ">=18.18" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.12.tgz", - "integrity": "sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==", - "cpu": [ - "arm64" - ], + "node_modules/@inquirer/ansi": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], "engines": { "node": ">=18" } }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.12.tgz", - "integrity": "sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==", - "cpu": [ - "ia32" - ], + "node_modules/@inquirer/checkbox": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@esbuild/win32-x64": { - "version": "0.25.12", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.12.tgz", - "integrity": "sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==", - "cpu": [ - "x64" - ], + "node_modules/@inquirer/confirm": { + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", + "dev": true, "license": "MIT", - "optional": true, - "os": [ - "win32" - ], + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" + }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint-community/eslint-utils": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", - "integrity": "sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==", + "node_modules/@inquirer/core": { + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "dev": true, "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^3.4.3" + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" + "node": ">=18" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "node_modules/@inquirer/core/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/@inquirer/core/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.0.0 || ^14.0.0 || >=16.0.0" + "node": ">=8" } }, - "node_modules/@eslint/config-array": { - "version": "0.21.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.1.tgz", - "integrity": "sha512-aw1gNayWpdI/jSYVgzN5pL0cfzU02GT3NBpeT/DXbx1/1x7ZKxFPd9bwrzygx/qiwIQiJ1sw/zD8qY/kRvlGHA==", + "node_modules/@inquirer/core/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@eslint/object-schema": "^2.1.7", - "debug": "^4.3.1", - "minimatch": "^3.1.2" - }, + "license": "ISC", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@inquirer/core/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@inquirer/core/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "ansi-regex": "^5.0.1" }, "engines": { - "node": "*" + "node": ">=8" } }, - "node_modules/@eslint/config-helpers": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", - "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", + "node_modules/@inquirer/core/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@eslint/core": "^0.17.0" + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=8" } }, - "node_modules/@eslint/core": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", - "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", + "node_modules/@inquirer/editor": { + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@types/json-schema": "^7.0.15" + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.3.tgz", - "integrity": "sha512-Kr+LPIUVKz2qkx1HAMH8q1q6azbqBAsXJUxBl/ODDuVPX45Z9DfwB8tPjTi6nNZ8BuM3nbJxC5zCAg5elnBUTQ==", + "node_modules/@inquirer/expand": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^10.0.1", - "globals": "^14.0.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.1", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true, - "license": "Python-2.0" - }, - "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "node_modules/@inquirer/external-editor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "dev": true, "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz", - "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==", - "dev": true, - "license": "Apache-2.0", + "chardet": "^2.1.1", + "iconv-lite": "^0.7.0" + }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" }, - "funding": { - "url": "https://opencollective.com/eslint" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", + "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", "dependencies": { - "acorn": "^8.15.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^4.2.1" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=0.10.0" }, "funding": { - "url": "https://opencollective.com/eslint" + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@eslint/eslintrc/node_modules/globals": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", - "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", + "node_modules/@inquirer/figures": { + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "dev": true, "license": "MIT", "engines": { "node": ">=18" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz", - "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==", + "node_modules/@inquirer/input": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "dev": true, "license": "MIT", "dependencies": { - "argparse": "^2.0.1" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, - "bin": { - "js-yaml": "bin/js-yaml.js" + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/@inquirer/number": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { - "node": "*" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/js": { - "version": "9.39.1", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.1.tgz", - "integrity": "sha512-S26Stp4zCy88tH94QbBv3XCuzRQiZ9yXofEILmglYTh/Ug/a9/umqvgFtYBAo3Lp0nsI/5/qH1CCrbdK3AP1Tw==", + "node_modules/@inquirer/password": { + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "dev": true, "license": "MIT", - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "dependencies": { + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, - "funding": { - "url": "https://eslint.org/donate" - } - }, - "node_modules/@eslint/object-schema": { - "version": "2.1.7", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", - "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", - "dev": true, - "license": "Apache-2.0", "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@eslint/plugin-kit": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", - "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", + "node_modules/@inquirer/prompts": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.8.2.tgz", + "integrity": "sha512-nqhDw2ZcAUrKNPwhjinJny903bRhI0rQhiDz1LksjeRxqa36i3l75+4iXbOy0rlDpLJGxqtgoPavQjmmyS5UJw==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@eslint/core": "^0.17.0", - "levn": "^0.4.1" + "@inquirer/checkbox": "^4.2.1", + "@inquirer/confirm": "^5.1.14", + "@inquirer/editor": "^4.2.17", + "@inquirer/expand": "^4.0.17", + "@inquirer/input": "^4.2.1", + "@inquirer/number": "^3.0.17", + "@inquirer/password": "^4.0.17", + "@inquirer/rawlist": "^4.1.5", + "@inquirer/search": "^3.1.0", + "@inquirer/select": "^4.3.1" }, "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@fastify/busboy": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@fastify/busboy/-/busboy-2.1.1.tgz", - "integrity": "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA==", + "node_modules/@inquirer/rawlist": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "dev": true, "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, "engines": { - "node": ">=14" - } - }, - "node_modules/@graphql-typed-document-node/core": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@graphql-typed-document-node/core/-/core-3.2.0.tgz", - "integrity": "sha512-mB9oAsNCm9aM3/SOv4YtBMqZbYj10R7dkq8byBqxGY/ncFwhf2oQzMV+LCRlWoDSEBJ3COiR1yeDvMtsoOsuFQ==", - "license": "MIT", + "node": ">=18" + }, "peerDependencies": { - "graphql": "^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0" + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "node_modules/@inquirer/search": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" + }, "engines": { - "node": ">=18.18.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@humanfs/node": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz", - "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==", + "node_modules/@inquirer/select": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.4.0" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { - "node": ">=18.18.0" + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "node_modules/@inquirer/type": { + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12.22" + "node": ">=18" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } } }, - "node_modules/@humanwhocodes/retry": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz", - "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==", + "node_modules/@isaacs/balanced-match": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", + "integrity": "sha512-yzMTt9lEb8Gv7zRioUilSglI0c0smZ9k5D65677DLWLtWJaXIS3CqcGyUFByYKlnUj6TkjLVs54fBl6+TiGQDQ==", "dev": true, - "license": "Apache-2.0", + "license": "MIT", "engines": { - "node": ">=18.18" + "node": "20 || >=22" + } + }, + "node_modules/@isaacs/brace-expansion": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@isaacs/brace-expansion/-/brace-expansion-5.0.0.tgz", + "integrity": "sha512-ZT55BDLV0yv0RBm2czMiZ+SqCGO7AvmOM3G/w2xhVPH+te0aKgFjmBvGlL1dH+ql2tgGO3MVrbb3jCKyvpgnxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@isaacs/balanced-match": "^4.0.1" }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "engines": { + "node": "20 || >=22" } }, "node_modules/@isaacs/cliui": { @@ -3323,7 +4432,20 @@ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" }, "engines": { - "node": ">=12" + "node": ">=12" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" } }, "node_modules/@istanbuljs/load-nyc-config": { @@ -3832,82 +4954,342 @@ }, "node_modules/@jest/core/node_modules/jest-each": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.0.5.tgz", - "integrity": "sha512-dKjRsx1uZ96TVyejD3/aAWcNKy6ajMaN531CwWIsrazIqIoXI9TnnpPlkrEYku/8rkS3dh2rbH+kMOyiEIv0xQ==", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.0.5.tgz", + "integrity": "sha512-dKjRsx1uZ96TVyejD3/aAWcNKy6ajMaN531CwWIsrazIqIoXI9TnnpPlkrEYku/8rkS3dh2rbH+kMOyiEIv0xQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.0.1", + "@jest/types": "30.0.5", + "chalk": "^4.1.2", + "jest-util": "30.0.5", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-environment-node": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.0.5.tgz", + "integrity": "sha512-ppYizXdLMSvciGsRsMEnv/5EFpvOdXBaXRBzFUDPWrsfmog4kYrOGWXarLllz6AXan6ZAA/kYokgDWuos1IKDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.0.5", + "@jest/fake-timers": "30.0.5", + "@jest/types": "30.0.5", + "@types/node": "*", + "jest-mock": "30.0.5", + "jest-util": "30.0.5", + "jest-validate": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-haste-map": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.0.5.tgz", + "integrity": "sha512-dkmlWNlsTSR0nH3nRfW5BKbqHefLZv0/6LCccG0xFCTWcJu8TuEwG+5Cm75iBfjVoockmO6J35o5gxtFSn5xeg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "anymatch": "^3.1.3", + "fb-watchman": "^2.0.2", + "graceful-fs": "^4.2.11", + "jest-regex-util": "30.0.1", + "jest-util": "30.0.5", + "jest-worker": "30.0.5", + "micromatch": "^4.0.8", + "walker": "^1.0.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.3" + } + }, + "node_modules/@jest/core/node_modules/jest-matcher-utils": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.0.5.tgz", + "integrity": "sha512-uQgGWt7GOrRLP1P7IwNWwK1WAQbq+m//ZY0yXygyfWp0rJlksMSLQAA4wYQC3b6wl3zfnchyTx+k3HZ5aPtCbQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.0.1", + "chalk": "^4.1.2", + "jest-diff": "30.0.5", + "pretty-format": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-message-util": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.0.5.tgz", + "integrity": "sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.0.5", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.0.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-mock": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", + "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "@types/node": "*", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-resolve": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.0.5.tgz", + "integrity": "sha512-d+DjBQ1tIhdz91B79mywH5yYu76bZuE96sSbxj8MkjWVx5WNdt1deEFRONVL4UkKLSrAbMkdhb24XN691yDRHg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.0.5", + "jest-pnp-resolver": "^1.2.3", + "jest-util": "30.0.5", + "jest-validate": "30.0.5", + "slash": "^3.0.0", + "unrs-resolver": "^1.7.11" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/jest-worker": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.0.5.tgz", + "integrity": "sha512-ojRXsWzEP16NdUuBw/4H/zkZdHOa7MMYCk4E430l+8fELeLg/mqmMlRhjL7UNZvQrDmnovWZV4DxX03fZF48fQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@ungap/structured-clone": "^1.3.0", + "jest-util": "30.0.5", + "merge-stream": "^2.0.0", + "supports-color": "^8.1.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/core/node_modules/pretty-format": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/@jest/diff-sequences": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", + "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "devOptional": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", + "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "30.2.0", + "@jest/types": "30.2.0", + "@types/node": "*", + "jest-mock": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/environment-jsdom-abstract": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.0.5.tgz", + "integrity": "sha512-gpWwiVxZunkoglP8DCnT3As9x5O8H6gveAOpvaJd2ATAoSh7ZSSCWbr9LQtUMvr8WD3VjG9YnDhsmkCK5WN1rQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "30.0.5", + "@jest/fake-timers": "30.0.5", + "@jest/types": "30.0.5", + "@types/jsdom": "^21.1.7", + "@types/node": "*", + "jest-mock": "30.0.5", + "jest-util": "30.0.5" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "canvas": "^3.0.0", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/environment": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.0.5.tgz", + "integrity": "sha512-aRX7WoaWx1oaOkDQvCWImVQ8XNtdv5sEWgk4gxR6NXb7WBUnL5sRak4WRzIQRZ1VTWPvV4VI4mgGjNL9TeKMYA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.0.1", + "@jest/fake-timers": "30.0.5", "@jest/types": "30.0.5", - "chalk": "^4.1.2", - "jest-util": "30.0.5", - "pretty-format": "30.0.5" + "@types/node": "*", + "jest-mock": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-environment-node": { + "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.0.5.tgz", - "integrity": "sha512-ppYizXdLMSvciGsRsMEnv/5EFpvOdXBaXRBzFUDPWrsfmog4kYrOGWXarLllz6AXan6ZAA/kYokgDWuos1IKDA==", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.0.5.tgz", + "integrity": "sha512-ZO5DHfNV+kgEAeP3gK3XlpJLL4U3Sz6ebl/n68Uwt64qFFs5bv4bfEEjyRGK5uM0C90ewooNgFuKMdkbEoMEXw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.0.5", - "@jest/fake-timers": "30.0.5", "@jest/types": "30.0.5", + "@sinonjs/fake-timers": "^13.0.0", "@types/node": "*", + "jest-message-util": "30.0.5", "jest-mock": "30.0.5", - "jest-util": "30.0.5", - "jest-validate": "30.0.5" + "jest-util": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-haste-map": { + "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/schemas": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.0.5.tgz", - "integrity": "sha512-dkmlWNlsTSR0nH3nRfW5BKbqHefLZv0/6LCccG0xFCTWcJu8TuEwG+5Cm75iBfjVoockmO6J35o5gxtFSn5xeg==", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", - "@types/node": "*", - "anymatch": "^3.1.3", - "fb-watchman": "^2.0.2", - "graceful-fs": "^4.2.11", - "jest-regex-util": "30.0.1", - "jest-util": "30.0.5", - "jest-worker": "30.0.5", - "micromatch": "^4.0.8", - "walker": "^1.0.8" + "@sinclair/typebox": "^0.34.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.3" } }, - "node_modules/@jest/core/node_modules/jest-matcher-utils": { + "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/types": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.0.5.tgz", - "integrity": "sha512-uQgGWt7GOrRLP1P7IwNWwK1WAQbq+m//ZY0yXygyfWp0rJlksMSLQAA4wYQC3b6wl3zfnchyTx+k3HZ5aPtCbQ==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", + "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.0.1", - "chalk": "^4.1.2", - "jest-diff": "30.0.5", - "pretty-format": "30.0.5" + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", + "@types/node": "*", + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-message-util": { + "node_modules/@jest/environment-jsdom-abstract/node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/environment-jsdom-abstract/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/environment-jsdom-abstract/node_modules/jest-message-util": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.0.5.tgz", "integrity": "sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==", @@ -3928,7 +5310,7 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-mock": { + "node_modules/@jest/environment-jsdom-abstract/node_modules/jest-mock": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", @@ -3943,63 +5325,152 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-resolve": { + "node_modules/@jest/environment-jsdom-abstract/node_modules/pretty-format": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.0.5.tgz", - "integrity": "sha512-d+DjBQ1tIhdz91B79mywH5yYu76bZuE96sSbxj8MkjWVx5WNdt1deEFRONVL4UkKLSrAbMkdhb24XN691yDRHg==", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", "dev": true, "license": "MIT", "dependencies": { - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.0.5", - "jest-pnp-resolver": "^1.2.3", - "jest-util": "30.0.5", - "jest-validate": "30.0.5", - "slash": "^3.0.0", - "unrs-resolver": "^1.7.11" + "@jest/schemas": "30.0.5", + "ansi-styles": "^5.2.0", + "react-is": "^18.3.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/jest-worker": { + "node_modules/@jest/expect": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", + "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.2.0", + "jest-snapshot": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", + "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/get-type": "30.1.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect/node_modules/@jest/schemas": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.0.5.tgz", - "integrity": "sha512-ojRXsWzEP16NdUuBw/4H/zkZdHOa7MMYCk4E430l+8fELeLg/mqmMlRhjL7UNZvQrDmnovWZV4DxX03fZF48fQ==", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", "dependencies": { - "@types/node": "*", - "@ungap/structured-clone": "^1.3.0", - "jest-util": "30.0.5", - "merge-stream": "^2.0.0", - "supports-color": "^8.1.1" + "@sinclair/typebox": "^0.34.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/@jest/expect/node_modules/@jest/snapshot-utils": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", + "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" + "@jest/types": "30.2.0", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect/node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/expect/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/core/node_modules/pretty-format": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", - "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", + "node_modules/@jest/expect/node_modules/jest-snapshot": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", + "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@babel/generator": "^7.27.5", + "@babel/plugin-syntax-jsx": "^7.27.1", + "@babel/plugin-syntax-typescript": "^7.27.1", + "@babel/types": "^7.27.3", + "@jest/expect-utils": "30.2.0", + "@jest/get-type": "30.1.0", + "@jest/snapshot-utils": "30.2.0", + "@jest/transform": "30.2.0", + "@jest/types": "30.2.0", + "babel-preset-current-node-syntax": "^1.2.0", + "chalk": "^4.1.2", + "expect": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-diff": "30.2.0", + "jest-matcher-utils": "30.2.0", + "jest-message-util": "30.2.0", + "jest-util": "30.2.0", + "pretty-format": "30.2.0", + "semver": "^7.7.2", + "synckit": "^0.11.8" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect/node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/expect/node_modules/pretty-format": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", + "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", "dev": true, "license": "MIT", "dependencies": { @@ -4011,93 +5482,112 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/core/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "node_modules/@jest/fake-timers": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", + "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "30.2.0", + "@sinonjs/fake-timers": "^13.0.0", + "@types/node": "*", + "jest-message-util": "30.2.0", + "jest-mock": "30.2.0", + "jest-util": "30.2.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/fake-timers/node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", "dev": true, "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/diff-sequences": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.0.1.tgz", - "integrity": "sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==", + "node_modules/@jest/get-type": { + "version": "30.1.0", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", + "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", "devOptional": true, "license": "MIT", "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.2.0.tgz", - "integrity": "sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==", + "node_modules/@jest/globals": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.0.5.tgz", + "integrity": "sha512-7oEJT19WW4oe6HR7oLRvHxwlJk2gev0U9px3ufs8sX9PoD1Eza68KF0/tlN7X0dq/WVsBScXQGgCldA1V9Y/jA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.2.0", - "@jest/types": "30.2.0", - "@types/node": "*", - "jest-mock": "30.2.0" + "@jest/environment": "30.0.5", + "@jest/expect": "30.0.5", + "@jest/types": "30.0.5", + "jest-mock": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract": { + "node_modules/@jest/globals/node_modules/@jest/environment": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/environment-jsdom-abstract/-/environment-jsdom-abstract-30.0.5.tgz", - "integrity": "sha512-gpWwiVxZunkoglP8DCnT3As9x5O8H6gveAOpvaJd2ATAoSh7ZSSCWbr9LQtUMvr8WD3VjG9YnDhsmkCK5WN1rQ==", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.0.5.tgz", + "integrity": "sha512-aRX7WoaWx1oaOkDQvCWImVQ8XNtdv5sEWgk4gxR6NXb7WBUnL5sRak4WRzIQRZ1VTWPvV4VI4mgGjNL9TeKMYA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.0.5", "@jest/fake-timers": "30.0.5", "@jest/types": "30.0.5", - "@types/jsdom": "^21.1.7", "@types/node": "*", - "jest-mock": "30.0.5", - "jest-util": "30.0.5" + "jest-mock": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@jest/expect": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.0.5.tgz", + "integrity": "sha512-6udac8KKrtTtC+AXZ2iUN/R7dp7Ydry+Fo6FPFnDG54wjVMnb6vW/XNlf7Xj8UDjAE3aAVAsR4KFyKk3TCXmTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "expect": "30.0.5", + "jest-snapshot": "30.0.5" }, - "peerDependencies": { - "canvas": "^3.0.0", - "jsdom": "*" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/environment": { + "node_modules/@jest/globals/node_modules/@jest/expect-utils": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.0.5.tgz", - "integrity": "sha512-aRX7WoaWx1oaOkDQvCWImVQ8XNtdv5sEWgk4gxR6NXb7WBUnL5sRak4WRzIQRZ1VTWPvV4VI4mgGjNL9TeKMYA==", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.0.5.tgz", + "integrity": "sha512-F3lmTT7CXWYywoVUGTCmom0vXq3HTTkaZyTAzIy+bXSBizB7o5qzlC9VCtq0arOa8GqmNsbg/cE9C6HLn7Szew==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.0.5", - "@jest/types": "30.0.5", - "@types/node": "*", - "jest-mock": "30.0.5" + "@jest/get-type": "30.0.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/fake-timers": { + "node_modules/@jest/globals/node_modules/@jest/fake-timers": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.0.5.tgz", "integrity": "sha512-ZO5DHfNV+kgEAeP3gK3XlpJLL4U3Sz6ebl/n68Uwt64qFFs5bv4bfEEjyRGK5uM0C90ewooNgFuKMdkbEoMEXw==", @@ -4115,7 +5605,17 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/schemas": { + "node_modules/@jest/globals/node_modules/@jest/get-type": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.0.1.tgz", + "integrity": "sha512-AyYdemXCptSRFirI5EPazNxyPwAL0jXt3zceFjaj8NFiKP9pOi0bfXonf6qkf82z2t3QWPeLCWWw4stPBzctLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/globals/node_modules/@jest/schemas": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", @@ -4128,7 +5628,7 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/@jest/types": { + "node_modules/@jest/globals/node_modules/@jest/types": { "version": "30.0.5", "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", @@ -4147,14 +5647,14 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/@sinclair/typebox": { + "node_modules/@jest/globals/node_modules/@sinclair/typebox": { "version": "0.34.41", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", "dev": true, "license": "MIT" }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/ansi-styles": { + "node_modules/@jest/globals/node_modules/ansi-styles": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", @@ -4167,188 +5667,96 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/jest-message-util": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.0.5.tgz", - "integrity": "sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.0.5", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.0.5", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/jest-mock": { + "node_modules/@jest/globals/node_modules/expect": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", - "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", + "resolved": "https://registry.npmjs.org/expect/-/expect-30.0.5.tgz", + "integrity": "sha512-P0te2pt+hHI5qLJkIR+iMvS+lYUZml8rKKsohVHAGY+uClp9XVbdyYNJOIjSRpHVp8s8YqxJCiHUkSYZGr8rtQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", - "@types/node": "*", + "@jest/expect-utils": "30.0.5", + "@jest/get-type": "30.0.1", + "jest-matcher-utils": "30.0.5", + "jest-message-util": "30.0.5", + "jest-mock": "30.0.5", "jest-util": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/environment-jsdom-abstract/node_modules/pretty-format": { + "node_modules/@jest/globals/node_modules/jest-diff": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", - "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.2.0.tgz", - "integrity": "sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==", - "dev": true, - "license": "MIT", - "dependencies": { - "expect": "30.2.0", - "jest-snapshot": "30.2.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.2.0.tgz", - "integrity": "sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.0.5.tgz", + "integrity": "sha512-1UIqE9PoEKaHcIKvq2vbibrCog4Y8G0zmOxgQUVEiTqwR5hJVMCoDsN1vFvI5JvwD37hjueZ1C4l2FyGnfpE0A==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.1.0" + "@jest/diff-sequences": "30.0.1", + "@jest/get-type": "30.0.1", + "chalk": "^4.1.2", + "pretty-format": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/expect/node_modules/@jest/schemas": { + "node_modules/@jest/globals/node_modules/jest-matcher-utils": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" - } - }, - "node_modules/@jest/expect/node_modules/@jest/snapshot-utils": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.2.0.tgz", - "integrity": "sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.0.5.tgz", + "integrity": "sha512-uQgGWt7GOrRLP1P7IwNWwK1WAQbq+m//ZY0yXygyfWp0rJlksMSLQAA4wYQC3b6wl3zfnchyTx+k3HZ5aPtCbQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/get-type": "30.0.1", "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" + "jest-diff": "30.0.5", + "pretty-format": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/expect/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/expect/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/expect/node_modules/jest-snapshot": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.2.0.tgz", - "integrity": "sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==", + "node_modules/@jest/globals/node_modules/jest-message-util": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.0.5.tgz", + "integrity": "sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@babel/generator": "^7.27.5", - "@babel/plugin-syntax-jsx": "^7.27.1", - "@babel/plugin-syntax-typescript": "^7.27.1", - "@babel/types": "^7.27.3", - "@jest/expect-utils": "30.2.0", - "@jest/get-type": "30.1.0", - "@jest/snapshot-utils": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "babel-preset-current-node-syntax": "^1.2.0", - "chalk": "^4.1.2", - "expect": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-diff": "30.2.0", - "jest-matcher-utils": "30.2.0", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "pretty-format": "30.2.0", - "semver": "^7.7.2", - "synckit": "^0.11.8" + "@babel/code-frame": "^7.27.1", + "@jest/types": "30.0.5", + "@types/stack-utils": "^2.0.3", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "micromatch": "^4.0.8", + "pretty-format": "30.0.5", + "slash": "^3.0.0", + "stack-utils": "^2.0.6" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/expect/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "node_modules/@jest/globals/node_modules/jest-mock": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", + "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", + "@jest/types": "30.0.5", "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "jest-util": "30.0.5" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/expect/node_modules/pretty-format": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.2.0.tgz", - "integrity": "sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==", + "node_modules/@jest/globals/node_modules/pretty-format": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", + "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", "dev": true, "license": "MIT", "dependencies": { @@ -4360,25 +5768,85 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/fake-timers": { + "node_modules/@jest/pattern": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", + "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "jest-regex-util": "30.0.1" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/reporters": { "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.2.0.tgz", - "integrity": "sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", + "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", "dev": true, "license": "MIT", "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "30.2.0", + "@jest/test-result": "30.2.0", + "@jest/transform": "30.2.0", "@jest/types": "30.2.0", - "@sinonjs/fake-timers": "^13.0.0", + "@jridgewell/trace-mapping": "^0.3.25", "@types/node": "*", + "chalk": "^4.1.2", + "collect-v8-coverage": "^1.0.2", + "exit-x": "^0.2.2", + "glob": "^10.3.10", + "graceful-fs": "^4.2.11", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^6.0.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^5.0.0", + "istanbul-reports": "^3.1.3", "jest-message-util": "30.2.0", - "jest-mock": "30.2.0", - "jest-util": "30.2.0" + "jest-util": "30.2.0", + "jest-worker": "30.2.0", + "slash": "^3.0.0", + "string-length": "^4.0.2", + "v8-to-istanbul": "^9.0.1" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } } }, - "node_modules/@jest/fake-timers/node_modules/jest-util": { + "node_modules/@jest/reporters/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/reporters/node_modules/jest-util": { "version": "30.2.0", "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", @@ -4396,120 +5864,184 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/get-type": { - "version": "30.1.0", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.1.0.tgz", - "integrity": "sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==", - "devOptional": true, + "node_modules/@jest/reporters/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/schemas": { + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "dependencies": { + "@sinclair/typebox": "^0.27.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/@jest/snapshot-utils": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.0.5.tgz", + "integrity": "sha512-XcCQ5qWHLvi29UUrowgDFvV4t7ETxX91CbDczMnoqXPOIcZOxyNdSjm6kV5XMc8+HkxfRegU/MUmnTbJRzGrUQ==", + "dev": true, "license": "MIT", + "dependencies": { + "@jest/types": "30.0.5", + "chalk": "^4.1.2", + "graceful-fs": "^4.2.11", + "natural-compare": "^1.4.0" + }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals": { + "node_modules/@jest/snapshot-utils/node_modules/@jest/schemas": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.0.5.tgz", - "integrity": "sha512-7oEJT19WW4oe6HR7oLRvHxwlJk2gev0U9px3ufs8sX9PoD1Eza68KF0/tlN7X0dq/WVsBScXQGgCldA1V9Y/jA==", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/environment": "30.0.5", - "@jest/expect": "30.0.5", - "@jest/types": "30.0.5", - "jest-mock": "30.0.5" + "@sinclair/typebox": "^0.34.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/environment": { + "node_modules/@jest/snapshot-utils/node_modules/@jest/types": { "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.0.5.tgz", - "integrity": "sha512-aRX7WoaWx1oaOkDQvCWImVQ8XNtdv5sEWgk4gxR6NXb7WBUnL5sRak4WRzIQRZ1VTWPvV4VI4mgGjNL9TeKMYA==", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", + "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/fake-timers": "30.0.5", - "@jest/types": "30.0.5", + "@jest/pattern": "30.0.1", + "@jest/schemas": "30.0.5", + "@types/istanbul-lib-coverage": "^2.0.6", + "@types/istanbul-reports": "^3.0.4", "@types/node": "*", - "jest-mock": "30.0.5" + "@types/yargs": "^17.0.33", + "chalk": "^4.1.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/expect": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.0.5.tgz", - "integrity": "sha512-6udac8KKrtTtC+AXZ2iUN/R7dp7Ydry+Fo6FPFnDG54wjVMnb6vW/XNlf7Xj8UDjAE3aAVAsR4KFyKk3TCXmTA==", + "node_modules/@jest/snapshot-utils/node_modules/@sinclair/typebox": { + "version": "0.34.41", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", + "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jest/source-map": { + "version": "30.0.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", + "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", "dev": true, "license": "MIT", "dependencies": { - "expect": "30.0.5", - "jest-snapshot": "30.0.5" + "@jridgewell/trace-mapping": "^0.3.25", + "callsites": "^3.1.0", + "graceful-fs": "^4.2.11" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/expect-utils": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.0.5.tgz", - "integrity": "sha512-F3lmTT7CXWYywoVUGTCmom0vXq3HTTkaZyTAzIy+bXSBizB7o5qzlC9VCtq0arOa8GqmNsbg/cE9C6HLn7Szew==", + "node_modules/@jest/test-result": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", + "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.0.1" + "@jest/console": "30.2.0", + "@jest/types": "30.2.0", + "@types/istanbul-lib-coverage": "^2.0.6", + "collect-v8-coverage": "^1.0.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/fake-timers": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.0.5.tgz", - "integrity": "sha512-ZO5DHfNV+kgEAeP3gK3XlpJLL4U3Sz6ebl/n68Uwt64qFFs5bv4bfEEjyRGK5uM0C90ewooNgFuKMdkbEoMEXw==", + "node_modules/@jest/test-sequencer": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", + "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.0.5", - "@sinonjs/fake-timers": "^13.0.0", - "@types/node": "*", - "jest-message-util": "30.0.5", - "jest-mock": "30.0.5", - "jest-util": "30.0.5" + "@jest/test-result": "30.2.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "slash": "^3.0.0" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/get-type": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/get-type/-/get-type-30.0.1.tgz", - "integrity": "sha512-AyYdemXCptSRFirI5EPazNxyPwAL0jXt3zceFjaj8NFiKP9pOi0bfXonf6qkf82z2t3QWPeLCWWw4stPBzctLw==", + "node_modules/@jest/transform": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", + "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", "dev": true, "license": "MIT", + "dependencies": { + "@babel/core": "^7.27.4", + "@jest/types": "30.2.0", + "@jridgewell/trace-mapping": "^0.3.25", + "babel-plugin-istanbul": "^7.0.1", + "chalk": "^4.1.2", + "convert-source-map": "^2.0.0", + "fast-json-stable-stringify": "^2.1.0", + "graceful-fs": "^4.2.11", + "jest-haste-map": "30.2.0", + "jest-regex-util": "30.0.1", + "jest-util": "30.2.0", + "micromatch": "^4.0.8", + "pirates": "^4.0.7", + "slash": "^3.0.0", + "write-file-atomic": "^5.0.1" + }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/@jest/transform/node_modules/jest-util": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", + "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "@jest/types": "30.2.0", + "@types/node": "*", + "chalk": "^4.1.2", + "ci-info": "^4.2.0", + "graceful-fs": "^4.2.11", + "picomatch": "^4.0.2" }, "engines": { "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@jest/types": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", - "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", + "node_modules/@jest/types": { + "version": "30.2.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", + "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", "dev": true, "license": "MIT", "dependencies": { @@ -4525,569 +6057,561 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, - "node_modules/@jest/globals/node_modules/@sinclair/typebox": { + "node_modules/@jest/types/node_modules/@jest/schemas": { + "version": "30.0.5", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", + "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sinclair/typebox": "^0.34.0" + }, + "engines": { + "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + } + }, + "node_modules/@jest/types/node_modules/@sinclair/typebox": { "version": "0.34.41", "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", "dev": true, "license": "MIT" }, - "node_modules/@jest/globals/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", + "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", + "devOptional": true, "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" } }, - "node_modules/@jest/globals/node_modules/expect": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.0.5.tgz", - "integrity": "sha512-P0te2pt+hHI5qLJkIR+iMvS+lYUZml8rKKsohVHAGY+uClp9XVbdyYNJOIjSRpHVp8s8YqxJCiHUkSYZGr8rtQ==", - "dev": true, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "devOptional": true, "license": "MIT", "dependencies": { - "@jest/expect-utils": "30.0.5", - "@jest/get-type": "30.0.1", - "jest-matcher-utils": "30.0.5", - "jest-message-util": "30.0.5", - "jest-mock": "30.0.5", - "jest-util": "30.0.5" - }, + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "devOptional": true, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=6.0.0" } }, - "node_modules/@jest/globals/node_modules/jest-diff": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.0.5.tgz", - "integrity": "sha512-1UIqE9PoEKaHcIKvq2vbibrCog4Y8G0zmOxgQUVEiTqwR5hJVMCoDsN1vFvI5JvwD37hjueZ1C4l2FyGnfpE0A==", - "dev": true, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", + "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", + "devOptional": true, "license": "MIT", "dependencies": { - "@jest/diff-sequences": "30.0.1", - "@jest/get-type": "30.0.1", - "chalk": "^4.1.2", - "pretty-format": "30.0.5" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" } }, - "node_modules/@jest/globals/node_modules/jest-matcher-utils": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.0.5.tgz", - "integrity": "sha512-uQgGWt7GOrRLP1P7IwNWwK1WAQbq+m//ZY0yXygyfWp0rJlksMSLQAA4wYQC3b6wl3zfnchyTx+k3HZ5aPtCbQ==", + "node_modules/@jsdevtools/ez-spawn": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", + "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/get-type": "30.0.1", - "chalk": "^4.1.2", - "jest-diff": "30.0.5", - "pretty-format": "30.0.5" + "call-me-maybe": "^1.0.1", + "cross-spawn": "^7.0.3", + "string-argv": "^0.3.1", + "type-detect": "^4.0.8" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=10" } }, - "node_modules/@jest/globals/node_modules/jest-message-util": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.0.5.tgz", - "integrity": "sha512-NAiDOhsK3V7RU0Aa/HnrQo+E4JlbarbmI3q6Pi4KcxicdtjV82gcIUrejOtczChtVQR4kddu1E1EJlW6EN9IyA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.27.1", - "@jest/types": "30.0.5", - "@types/stack-utils": "^2.0.3", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "micromatch": "^4.0.8", - "pretty-format": "30.0.5", - "slash": "^3.0.0", - "stack-utils": "^2.0.6" - }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@jest/globals/node_modules/jest-mock": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.0.5.tgz", - "integrity": "sha512-Od7TyasAAQX/6S+QCbN6vZoWOMwlTtzzGuxJku1GhGanAjz9y+QsQkpScDmETvdc9aSXyJ/Op4rhpMYBWW91wQ==", - "dev": true, - "license": "MIT", + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", + "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", "dependencies": { - "@jest/types": "30.0.5", - "@types/node": "*", - "jest-util": "30.0.5" + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@jest/globals/node_modules/pretty-format": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.0.5.tgz", - "integrity": "sha512-D1tKtYvByrBkFLe2wHJl2bwMJIiT8rW+XA+TiataH79/FszLQMrpGEvzUVkzPau7OCO0Qnrhpe87PqtOAIB8Yw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jest/schemas": "30.0.5", - "ansi-styles": "^5.2.0", - "react-is": "^18.3.1" - }, + "node_modules/@jsonjoy.com/util": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", + "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" } }, - "node_modules/@jest/pattern": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.0.1.tgz", - "integrity": "sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==", - "dev": true, - "license": "MIT", + "node_modules/@keyv/serialize": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", + "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", + "license": "MIT" + }, + "node_modules/@kwsites/file-exists": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", + "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", "dependencies": { - "@types/node": "*", - "jest-regex-util": "30.0.1" - }, - "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "debug": "^4.1.1" } }, - "node_modules/@jest/reporters": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.2.0.tgz", - "integrity": "sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==", + "node_modules/@kwsites/promise-deferred": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", + "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-3.0.1.tgz", + "integrity": "sha512-3XFmGwm3u6ioREG+ynAQB7FoxfajgQnMhIu8wC5eo/Lsih4aKDg0VuIMGaOsYn7hJSJagSeaD4K8yfpkEoDEmA==", "dev": true, - "license": "MIT", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "30.2.0", - "@jest/test-result": "30.2.0", - "@jest/transform": "30.2.0", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "@types/node": "*", - "chalk": "^4.1.2", - "collect-v8-coverage": "^1.0.2", - "exit-x": "^0.2.2", - "glob": "^10.3.10", - "graceful-fs": "^4.2.11", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^6.0.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^5.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "30.2.0", - "jest-util": "30.2.0", - "jest-worker": "30.2.0", - "slash": "^3.0.0", - "string-length": "^4.0.2", - "v8-to-istanbul": "^9.0.1" + "license": "MIT", + "dependencies": { + "@inquirer/type": "^3.0.7" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=20.0.0" }, "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } + "@inquirer/prompts": ">= 3 < 8", + "listr2": "9.0.1" } }, - "node_modules/@jest/reporters/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.24.0.tgz", + "integrity": "sha512-D8h5KXY2vHFW8zTuxn2vuZGN0HGrQ5No6LkHwlEA9trVgNdPL3TF1dSqKA7Dny6BbBYKSW/rOBDXdC8KJAjUCg==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.0.1", + "express-rate-limit": "^7.5.0", + "jose": "^6.1.1", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" }, - "bin": { - "glob": "dist/esm/bin.mjs" + "engines": { + "node": ">=18" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } } }, - "node_modules/@jest/reporters/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/accepts": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", + "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "mime-types": "^3.0.0", + "negotiator": "^1.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.6" } }, - "node_modules/@jest/reporters/node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "node_modules/@modelcontextprotocol/sdk/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "dev": true, - "license": "ISC", + "license": "MIT", "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=16 || 14 >=14.17" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { - "url": "https://github.com/sponsors/isaacs" + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@jest/schemas": { - "version": "29.6.3", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", - "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/body-parser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", + "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "dev": true, + "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.27.8" + "bytes": "^3.1.2", + "content-type": "^1.0.5", + "debug": "^4.4.3", + "http-errors": "^2.0.0", + "iconv-lite": "^0.7.0", + "on-finished": "^2.4.1", + "qs": "^6.14.0", + "raw-body": "^3.0.1", + "type-is": "^2.0.1" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/snapshot-utils": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.0.5.tgz", - "integrity": "sha512-XcCQ5qWHLvi29UUrowgDFvV4t7ETxX91CbDczMnoqXPOIcZOxyNdSjm6kV5XMc8+HkxfRegU/MUmnTbJRzGrUQ==", + "node_modules/@modelcontextprotocol/sdk/node_modules/content-disposition": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/types": "30.0.5", - "chalk": "^4.1.2", - "graceful-fs": "^4.2.11", - "natural-compare": "^1.4.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/snapshot-utils/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/cookie-signature": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", + "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", "dev": true, "license": "MIT", - "dependencies": { - "@sinclair/typebox": "^0.34.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=6.6.0" } }, - "node_modules/@jest/snapshot-utils/node_modules/@jest/types": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.0.5.tgz", - "integrity": "sha512-aREYa3aku9SSnea4aX6bhKn4bgv3AXkgijoQgbYV3yvbiGt6z+MQ85+6mIhx9DsKW2BuB/cLR/A+tcMThx+KLQ==", + "node_modules/@modelcontextprotocol/sdk/node_modules/express": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "dev": true, "license": "MIT", "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" + "accepts": "^2.0.0", + "body-parser": "^2.2.1", + "content-disposition": "^1.0.0", + "content-type": "^1.0.5", + "cookie": "^0.7.1", + "cookie-signature": "^1.2.1", + "debug": "^4.4.0", + "depd": "^2.0.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "finalhandler": "^2.1.0", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "merge-descriptors": "^2.0.0", + "mime-types": "^3.0.0", + "on-finished": "^2.4.1", + "once": "^1.4.0", + "parseurl": "^1.3.3", + "proxy-addr": "^2.0.7", + "qs": "^6.14.0", + "range-parser": "^1.2.1", + "router": "^2.2.0", + "send": "^1.1.0", + "serve-static": "^2.2.0", + "statuses": "^2.0.1", + "type-is": "^2.0.1", + "vary": "^1.1.2" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/snapshot-utils/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jest/source-map": { - "version": "30.0.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-30.0.1.tgz", - "integrity": "sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==", + "node_modules/@modelcontextprotocol/sdk/node_modules/express-rate-limit": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-7.5.1.tgz", + "integrity": "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw==", "dev": true, "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.25", - "callsites": "^3.1.0", - "graceful-fs": "^4.2.11" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/express-rate-limit" + }, + "peerDependencies": { + "express": ">= 4.11" } }, - "node_modules/@jest/test-result": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.2.0.tgz", - "integrity": "sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==", + "node_modules/@modelcontextprotocol/sdk/node_modules/finalhandler": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "dev": true, "license": "MIT", "dependencies": { - "@jest/console": "30.2.0", - "@jest/types": "30.2.0", - "@types/istanbul-lib-coverage": "^2.0.6", - "collect-v8-coverage": "^1.0.2" + "debug": "^4.4.0", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "on-finished": "^2.4.1", + "parseurl": "^1.3.3", + "statuses": "^2.0.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/test-sequencer": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.2.0.tgz", - "integrity": "sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==", + "node_modules/@modelcontextprotocol/sdk/node_modules/fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", + "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/test-result": "30.2.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "slash": "^3.0.0" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.8" } }, - "node_modules/@jest/transform": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.2.0.tgz", - "integrity": "sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/http-errors": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/core": "^7.27.4", - "@jest/types": "30.2.0", - "@jridgewell/trace-mapping": "^0.3.25", - "babel-plugin-istanbul": "^7.0.1", - "chalk": "^4.1.2", - "convert-source-map": "^2.0.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.11", - "jest-haste-map": "30.2.0", - "jest-regex-util": "30.0.1", - "jest-util": "30.2.0", - "micromatch": "^4.0.8", - "pirates": "^4.0.7", - "slash": "^3.0.0", - "write-file-atomic": "^5.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/transform/node_modules/jest-util": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.2.0.tgz", - "integrity": "sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/iconv-lite": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", + "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", "dev": true, "license": "MIT", "dependencies": { - "@jest/types": "30.2.0", - "@types/node": "*", - "chalk": "^4.1.2", - "ci-info": "^4.2.0", - "graceful-fs": "^4.2.11", - "picomatch": "^4.0.2" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/types": { - "version": "30.2.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz", - "integrity": "sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==", + "node_modules/@modelcontextprotocol/sdk/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/media-typer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz", + "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==", "dev": true, "license": "MIT", - "dependencies": { - "@jest/pattern": "30.0.1", - "@jest/schemas": "30.0.5", - "@types/istanbul-lib-coverage": "^2.0.6", - "@types/istanbul-reports": "^3.0.4", - "@types/node": "*", - "@types/yargs": "^17.0.33", - "chalk": "^4.1.2" - }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">= 0.8" } }, - "node_modules/@jest/types/node_modules/@jest/schemas": { - "version": "30.0.5", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz", - "integrity": "sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/merge-descriptors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", + "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@modelcontextprotocol/sdk/node_modules/mime-types": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "dev": true, "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.34.0" + "mime-db": "^1.54.0" }, "engines": { - "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, - "node_modules/@jest/types/node_modules/@sinclair/typebox": { - "version": "0.34.41", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.41.tgz", - "integrity": "sha512-6gS8pZzSXdyRHTIqoqSVknxolr1kzfy4/CeDnrzsVz8TTIWUbOBr6gnzOmTYJ3eXQNh4IYHIGi5aIL7sOZ2G/g==", + "node_modules/@modelcontextprotocol/sdk/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.13", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz", - "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==", - "devOptional": true, "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0", - "@jridgewell/trace-mapping": "^0.3.24" + "engines": { + "node": ">= 0.6" } }, - "node_modules/@jridgewell/remapping": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", - "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", - "devOptional": true, + "node_modules/@modelcontextprotocol/sdk/node_modules/raw-body": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", + "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": "^0.3.5", - "@jridgewell/trace-mapping": "^0.3.24" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "devOptional": true, + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.7.0", + "unpipe": "~1.0.0" + }, "engines": { - "node": ">=6.0.0" + "node": ">= 0.10" } }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz", - "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.31", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", - "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", - "devOptional": true, + "node_modules/@modelcontextprotocol/sdk/node_modules/send": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", + "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/resolve-uri": "^3.1.0", - "@jridgewell/sourcemap-codec": "^1.4.14" + "debug": "^4.3.5", + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "etag": "^1.8.1", + "fresh": "^2.0.0", + "http-errors": "^2.0.0", + "mime-types": "^3.0.1", + "ms": "^2.1.3", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "statuses": "^2.0.1" + }, + "engines": { + "node": ">= 18" } }, - "node_modules/@jsdevtools/ez-spawn": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@jsdevtools/ez-spawn/-/ez-spawn-3.0.4.tgz", - "integrity": "sha512-f5DRIOZf7wxogefH03RjMPMdBF7ADTWUMoOs9kaJo06EfwF+aFhMZMDZxHg/Xe12hptN9xoZjGso2fdjapBRIA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/serve-static": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", + "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", "dev": true, "license": "MIT", "dependencies": { - "call-me-maybe": "^1.0.1", - "cross-spawn": "^7.0.3", - "string-argv": "^0.3.1", - "type-detect": "^4.0.8" + "encodeurl": "^2.0.0", + "escape-html": "^1.0.3", + "parseurl": "^1.3.3", + "send": "^1.2.0" }, "engines": { - "node": ">=10" + "node": ">= 18" } }, - "node_modules/@jsonjoy.com/base64": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", - "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "node_modules/@modelcontextprotocol/sdk/node_modules/statuses": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" + "node": ">= 0.8" } }, - "node_modules/@jsonjoy.com/json-pack": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.1.1.tgz", - "integrity": "sha512-osjeBqMJ2lb/j/M8NCPjs1ylqWIcTRTycIhVB5pt6LgzgeRSb0YRZ7j9RfA8wIUrsr/medIuhVyonXRZWLyfdw==", + "node_modules/@modelcontextprotocol/sdk/node_modules/type-is": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz", + "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==", + "dev": true, + "license": "MIT", "dependencies": { - "@jsonjoy.com/base64": "^1.1.1", - "@jsonjoy.com/util": "^1.1.2", - "hyperdyperid": "^1.2.0", - "thingies": "^1.20.0" - }, - "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" + "content-type": "^1.0.5", + "media-typer": "^1.1.0", + "mime-types": "^3.0.0" }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@jsonjoy.com/util": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.5.0.tgz", - "integrity": "sha512-ojoNsrIuPI9g6o8UxhraZQSyF2ByJanAY4cTFbc8Mf2AXEF4aQRGY1dJxyJpuyav8r9FGflEt/Ff3u5Nt6YMPA==", "engines": { - "node": ">=10.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/streamich" - }, - "peerDependencies": { - "tslib": "2" - } - }, - "node_modules/@keyv/serialize": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@keyv/serialize/-/serialize-1.1.1.tgz", - "integrity": "sha512-dXn3FZhPv0US+7dtJsIi2R+c7qWYiReoEh5zUntWCf4oSpMNib8FDhSoed6m3QyZdx5hK7iLFkYk3rNxwt8vTA==", - "license": "MIT" - }, - "node_modules/@kwsites/file-exists": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz", - "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==", - "dependencies": { - "debug": "^4.1.1" + "node": ">= 0.6" } }, - "node_modules/@kwsites/promise-deferred": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz", - "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==" - }, "node_modules/@napi-rs/nice": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.1.tgz", @@ -5120,92 +6644,204 @@ "@napi-rs/nice-win32-x64-msvc": "1.0.1" } }, - "node_modules/@napi-rs/nice-android-arm-eabi": { + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", + "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", + "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", + "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", + "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", + "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", + "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", + "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.1.tgz", - "integrity": "sha512-5qpvOu5IGwDo7MEKVqqyAxF90I6aLj4n07OzpARdgDRfz8UbBztTByBp0RC59r3J1Ij8uzYi6jI7r5Lws7nn6w==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", + "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", "cpu": [ - "arm" + "arm64" ], "dev": true, "optional": true, "os": [ - "android" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-android-arm64": { + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.1.tgz", - "integrity": "sha512-GqvXL0P8fZ+mQqG1g0o4AO9hJjQaeYG84FRfZaYjyJtZZZcMjXW5TwkL8Y8UApheJgyE13TQ4YNUssQaTgTyvA==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", + "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", "cpu": [ - "arm64" + "ppc64" ], "dev": true, "optional": true, "os": [ - "android" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-darwin-arm64": { + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.1.tgz", - "integrity": "sha512-91k3HEqUl2fsrz/sKkuEkscj6EAj3/eZNCLqzD2AA0TtVbkQi8nqxZCZDMkfklULmxLkMxuUdKe7RvG/T6s2AA==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", + "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", "cpu": [ - "arm64" + "riscv64" ], "dev": true, "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-darwin-x64": { + "node_modules/@napi-rs/nice-linux-s390x-gnu": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.1.tgz", - "integrity": "sha512-jXnMleYSIR/+TAN/p5u+NkCA7yidgswx5ftqzXdD5wgy/hNR92oerTXHc0jrlBisbd7DpzoaGY4cFD7Sm5GlgQ==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", + "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", "cpu": [ - "x64" + "s390x" ], "dev": true, "optional": true, "os": [ - "darwin" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-freebsd-x64": { + "node_modules/@napi-rs/nice-linux-x64-gnu": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.1.tgz", - "integrity": "sha512-j+iJ/ezONXRQsVIB/FJfwjeQXX7A2tf3gEXs4WUGFrJjpe/z2KB7sOv6zpkm08PofF36C9S7wTNuzHZ/Iiccfw==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", + "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", "cpu": [ "x64" ], "dev": true, "optional": true, "os": [ - "freebsd" + "linux" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "node_modules/@napi-rs/nice-linux-x64-musl": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.1.tgz", - "integrity": "sha512-G8RgJ8FYXYkkSGQwywAUh84m946UTn6l03/vmEXBYNJxQJcD+I3B3k5jmjFG/OPiU8DfvxutOP8bi+F89MCV7Q==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", + "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", "cpu": [ - "arm" + "x64" ], "dev": true, "optional": true, @@ -5216,218 +6852,442 @@ "node": ">= 10" } }, - "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "node_modules/@napi-rs/nice-win32-arm64-msvc": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.1.tgz", - "integrity": "sha512-IMDak59/W5JSab1oZvmNbrms3mHqcreaCeClUjwlwDr0m3BoR09ZiN8cKFBzuSlXgRdZ4PNqCYNeGQv7YMTjuA==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", + "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", "cpu": [ "arm64" ], "dev": true, "optional": true, "os": [ - "linux" + "win32" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-linux-arm64-musl": { + "node_modules/@napi-rs/nice-win32-ia32-msvc": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.1.tgz", - "integrity": "sha512-wG8fa2VKuWM4CfjOjjRX9YLIbysSVV1S3Kgm2Fnc67ap/soHBeYZa6AGMeR5BJAylYRjnoVOzV19Cmkco3QEPw==", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", + "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", "cpu": [ - "arm64" + "ia32" ], "dev": true, "optional": true, "os": [ - "linux" + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", + "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" ], "engines": { "node": ">= 10" } }, - "node_modules/@napi-rs/nice-linux-ppc64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.1.tgz", - "integrity": "sha512-lxQ9WrBf0IlNTCA9oS2jg/iAjQyTI6JHzABV664LLrLA/SIdD+I1i3Mjf7TsnoUbgopBcCuDztVLfJ0q9ubf6Q==", - "cpu": [ - "ppc64" - ], + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", + "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==", + "devOptional": true, + "license": "MIT", + "dependencies": { + "@emnapi/core": "^1.1.0", + "@emnapi/runtime": "^1.1.0", + "@tybys/wasm-util": "^0.9.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nolyfill/is-core-module": { + "version": "1.0.39", + "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", + "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.4.0" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz", + "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz", + "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, "engines": { - "node": ">= 10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@napi-rs/nice-linux-riscv64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.1.tgz", - "integrity": "sha512-3xs69dO8WSWBb13KBVex+yvxmUeEsdWexxibqskzoKaWx9AIqkMbWmE2npkazJoopPKX2ULKd8Fm9veEn0g4Ig==", - "cpu": [ - "riscv64" - ], + "node_modules/@npmcli/package-json/node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "MIT", "engines": { - "node": ">= 10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@napi-rs/nice-linux-s390x-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.1.tgz", - "integrity": "sha512-lMFI3i9rlW7hgToyAzTaEybQYGbQHDrpRkg+1gJWEpH0PLAQoZ8jiY0IzakLfNWnVda1eTYYlxxFYzW8Rqczkg==", - "cpu": [ - "s390x" - ], + "node_modules/@npmcli/package-json/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10" - } + "license": "ISC" }, - "node_modules/@napi-rs/nice-linux-x64-gnu": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.1.tgz", - "integrity": "sha512-XQAJs7DRN2GpLN6Fb+ZdGFeYZDdGl2Fn3TmFlqEL5JorgWKrQGRUrpGKbgZ25UeZPILuTKJ+OowG2avN8mThBA==", - "cpu": [ - "x64" - ], + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, "engines": { - "node": ">= 10" + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/@napi-rs/nice-linux-x64-musl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.1.tgz", - "integrity": "sha512-/rodHpRSgiI9o1faq9SZOp/o2QkKQg7T+DK0R5AkbnI/YxvAIEHf2cngjYzLMQSQgUhxym+LFr+UGZx4vK4QdQ==", - "cpu": [ - "x64" - ], + "node_modules/@npmcli/package-json/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", "dev": true, - "optional": true, - "os": [ - "linux" - ], + "license": "ISC", "engines": { - "node": ">= 10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@napi-rs/nice-win32-arm64-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.1.tgz", - "integrity": "sha512-rEcz9vZymaCB3OqEXoHnp9YViLct8ugF+6uO5McifTedjq4QMQs3DHz35xBEGhH3gJWEsXMUbzazkz5KNM5YUg==", - "cpu": [ - "arm64" - ], + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.3.tgz", + "integrity": "sha512-Yb00SWaL4F8w+K8YGhQ55+xE4RUNdMHV43WZGsiTM92gS+lC0mGsn7I4hLug7pbao035S6bj3Y3w0cUNGLfmkg==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, "engines": { - "node": ">= 10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@napi-rs/nice-win32-ia32-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.1.tgz", - "integrity": "sha512-t7eBAyPUrWL8su3gDxw9xxxqNwZzAqKo0Szv3IjVQd1GpXXVkb6vBBQUuxfIYaXMzZLwlxRQ7uzM2vdUE9ULGw==", - "cpu": [ - "ia32" - ], + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "license": "ISC", "engines": { - "node": ">= 10" + "node": ">=16" } }, - "node_modules/@napi-rs/nice-win32-x64-msvc": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.1.tgz", - "integrity": "sha512-JlF+uDcatt3St2ntBG8H02F1mM45i5SF9W+bIKiReVE6wiy3o16oBP/yxt+RZ+N6LbCImJXJ6bXNO2kn9AXicg==", - "cpu": [ - "x64" - ], + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, - "optional": true, - "os": [ - "win32" - ], + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, "engines": { - "node": ">= 10" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.4.tgz", - "integrity": "sha512-9zESzOO5aDByvhIAsOy9TbpZ0Ur2AJbUI7UT73kcUTS2mxAMHOBaa1st/jAymNoCtvrit99kkzT1FZuXVcgfIQ==", - "devOptional": true, - "license": "MIT", - "dependencies": { - "@emnapi/core": "^1.1.0", - "@emnapi/runtime": "^1.1.0", - "@tybys/wasm-util": "^0.9.0" + "node_modules/@npmcli/redact": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz", + "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "node_modules/@npmcli/run-script": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz", + "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==", + "dev": true, + "license": "ISC", "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" }, "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 8" + "node": ">=16" } }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, + "node_modules/@npmcli/run-script/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 8" + "node": "^18.17.0 || >=20.5.0" } }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", "dev": true, - "license": "MIT", + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, "engines": { - "node": ">=12.4.0" + "node": "^18.17.0 || >=20.5.0" } }, "node_modules/@nx/devkit": { @@ -9188,39 +11048,153 @@ "win32" ] }, - "node_modules/@rollup/rollup-win32-x64-gnu": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", - "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.53.3.tgz", + "integrity": "sha512-J9QDiOIZlZLdcot5NXEepDkstocktoVjkaKUtqzgzpt2yWjGlbYiKyp05rWwk4nypbYUNoFAztEgixoLaSETkg==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.53.3", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", + "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rtsao/scc": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", + "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/@schematics/angular": { + "version": "20.3.13", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-20.3.13.tgz", + "integrity": "sha512-ETJ1budKmrkdxojo5QP6TPr6zQZYGxtWWf8NrX1cBIS851zPCmFkKyhSFLZsoksariYF/LP8ljvm8tlcIzt/XA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "20.3.13", + "@angular-devkit/schematics": "20.3.13", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^20.19.0 || ^22.12.0 || >=24.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@schematics/angular/node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@sigstore/bundle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", + "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz", + "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz", + "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.53.3", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.53.3.tgz", - "integrity": "sha512-UhTd8u31dXadv0MopwGgNOBpUVROFKWVQgAg5N1ESyCz8AuBcMqm4AuTjrwgQKGDfoFuz02EuMRHQIw/frmYKQ==", - "cpu": [ - "x64" - ], - "license": "MIT", - "optional": true, - "os": [ - "win32" - ] + "node_modules/@sigstore/sign/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, - "node_modules/@rtsao/scc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@rtsao/scc/-/scc-1.1.0.tgz", - "integrity": "sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==", + "node_modules/@sigstore/tuf": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz", + "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==", "dev": true, - "license": "MIT", - "peer": true + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz", + "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } }, "node_modules/@sinclair/typebox": { "version": "0.27.8", @@ -9672,6 +11646,46 @@ "integrity": "sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA==", "dev": true }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/@tybys/wasm-util": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", @@ -11608,6 +13622,16 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "devOptional": true }, + "node_modules/abbrev": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/abort-controller": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", @@ -11731,6 +13755,74 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/algoliasearch": { + "version": "5.35.0", + "resolved": "https://registry.npmjs.org/algoliasearch/-/algoliasearch-5.35.0.tgz", + "integrity": "sha512-Y+moNhsqgLmvJdgTsO4GZNgsaDWv8AOGAaPeIeHKlDn/XunoAqYbA+XNpBd1dW8GOXAUDyxC9Rxc7AV4kpFcIg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@algolia/abtesting": "1.1.0", + "@algolia/client-abtesting": "5.35.0", + "@algolia/client-analytics": "5.35.0", + "@algolia/client-common": "5.35.0", + "@algolia/client-insights": "5.35.0", + "@algolia/client-personalization": "5.35.0", + "@algolia/client-query-suggestions": "5.35.0", + "@algolia/client-search": "5.35.0", + "@algolia/ingestion": "1.35.0", + "@algolia/monitoring": "1.35.0", + "@algolia/recommend": "5.35.0", + "@algolia/requester-browser-xhr": "5.35.0", + "@algolia/requester-fetch": "5.35.0", + "@algolia/requester-node-http": "5.35.0" + }, + "engines": { + "node": ">= 14.0.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -12461,8 +14553,7 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "devOptional": true + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" }, "node_modules/bare-events": { "version": "2.8.2", @@ -12686,7 +14777,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "devOptional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -12858,8 +14948,6 @@ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -12872,6 +14960,124 @@ "node": ">=8" } }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", + "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/p-map": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.4.tgz", + "integrity": "sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", + "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/cacheable": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cacheable/-/cacheable-2.3.0.tgz", @@ -13112,6 +15318,13 @@ "node": ">=10" } }, + "node_modules/chardet": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.1.tgz", + "integrity": "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ==", + "dev": true, + "license": "MIT" + }, "node_modules/check-error": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.3.tgz", @@ -13123,6 +15336,16 @@ "node": "*" } }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, "node_modules/ci-info": { "version": "4.3.1", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.3.1.tgz", @@ -13303,6 +15526,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, "node_modules/clipanion": { "version": "4.0.0-rc.4", "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-4.0.0-rc.4.tgz", @@ -13582,8 +15815,6 @@ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -13600,8 +15831,6 @@ "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -13655,8 +15884,6 @@ "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "object-assign": "^4", "vary": "^1" @@ -14071,8 +16298,6 @@ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -14318,9 +16543,7 @@ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/ejs": { "version": "3.1.10", @@ -14369,12 +16592,20 @@ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -14455,6 +16686,13 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", @@ -14667,9 +16905,7 @@ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", "dev": true, - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -15423,8 +17659,6 @@ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -15469,6 +17703,29 @@ "bare-events": "^2.7.0" } }, + "node_modules/eventsource": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-3.0.7.tgz", + "integrity": "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventsource-parser": "^3.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/eventsource-parser": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", @@ -15555,6 +17812,13 @@ "node": "^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0" } }, + "node_modules/exponential-backoff": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.3.tgz", + "integrity": "sha512-ZgEeZXj30q+I0EN+CbSSpIyPaJ5HVQD18Z1m+u1FXbAeT94mr1zw50q4q6jiiC447Nl/YTcIYSAftiGqetwXCA==", + "dev": true, + "license": "Apache-2.0" + }, "node_modules/express": { "version": "4.21.2", "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", @@ -16185,8 +18449,6 @@ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -16218,6 +18480,19 @@ "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", "devOptional": true }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", @@ -17105,6 +19380,35 @@ "node": ">= 4" } }, + "node_modules/ignore-walk": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-8.0.0.tgz", + "integrity": "sha512-FCeMZT4NiRQGh+YkeKMtWrOmBgWjHjMJ26WQWrRQyoyzqevdaGSakUaJW5xQYmjLlUVk2qUnCjYVBax9EKKg8A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^10.0.3" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz", + "integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/brace-expansion": "^5.0.0" + }, + "engines": { + "node": "20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -17213,14 +19517,22 @@ "node": ">= 0.4" } }, + "node_modules/ip-address": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.1.0.tgz", + "integrity": "sha512-XXADHxXmvT9+CRxhXg56LJovE+bmWnEWB78LB83VZTprKTmaC5QfruXocxzTZ2Kl0DNwKuBdlIhjL8LeY8Sf8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.10" } @@ -21595,6 +23907,16 @@ "jiti": "lib/jiti-cli.mjs" } }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", @@ -21787,9 +24109,7 @@ "engines": [ "node >= 0.2.0" ], - "license": "MIT", - "optional": true, - "peer": true + "license": "MIT" }, "node_modules/JSONStream": { "version": "1.3.5", @@ -22052,6 +24372,87 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/listr2": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.1.tgz", + "integrity": "sha512-SL0JY3DaxylDuo/MecFeiC+7pedM0zia33zl0vcjgwcq1q1FWWF1To9EIauPbl8GbMCU0R2e0uJ8bZunhYKD2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/emoji-regex": { + "version": "10.6.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz", + "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz", + "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/load-tsconfig": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/load-tsconfig/-/load-tsconfig-0.2.5.tgz", @@ -22406,6 +24807,49 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/make-fetch-happen/node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/make-fetch-happen/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/makeerror": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", @@ -22622,7 +25066,6 @@ "version": "9.0.3", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", - "devOptional": true, "dependencies": { "brace-expansion": "^2.0.1" }, @@ -22651,6 +25094,149 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", + "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.1.0.tgz", + "integrity": "sha512-KZxYo1BUkWD2TVFLr0MQoM8vUUigWD3LlD83a/75BqC+4qE0Hb1Vo5v1FgcfaNXvfXzr+5EhQ6ing/CaBijTlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, "node_modules/mkdirp": { "version": "0.5.6", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", @@ -22688,6 +25274,16 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -22789,6 +25385,104 @@ "webidl-conversions": "^3.0.0" } }, + "node_modules/node-gyp": { + "version": "11.5.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.5.0.tgz", + "integrity": "sha512-ra7Kvlhxn5V9Slyus0ygMa2h+UqExPqUIkfk7Pc8QTLT956JLSy51uWFwHtIYy0vI8cB4BDhc/S03+880My/LQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.5.2", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.5.2.tgz", + "integrity": "sha512-7NyxrTE4Anh8km8iEy7o0QYPs+0JKBTj5ZaqHg6B39erLg0qYXN3BijtShwbsNSvQ+LN75+KV+C4QR/f6Gwnpg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.1.0", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -22808,6 +25502,22 @@ "devOptional": true, "license": "MIT" }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -22816,6 +25526,42 @@ "node": ">=0.10.0" } }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.2.tgz", + "integrity": "sha512-z9HJBCYw9Zr8BqXcllKIs5nI+QggAImbBdHphOzVYrz2CB4iQ6FzWyKmlqDZua+51nAu7FcemlbTc9VgQN5XDQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm-package-arg": { "version": "11.0.1", "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-11.0.1.tgz", @@ -22832,6 +25578,178 @@ "node": "^16.14.0 || >=18.0.0" } }, + "node_modules/npm-packlist": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-10.0.3.tgz", + "integrity": "sha512-zPukTwJMOu5X5uvm0fztwS5Zxyvmk38H/LfidkOMt3gbZVCyro2cD/ETzwzVPcWZA3JOyPznfUN/nkyFiyUbxg==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^8.0.0", + "proc-log": "^6.0.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-packlist/node_modules/proc-log": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-6.1.0.tgz", + "integrity": "sha512-iG+GYldRf2BQ0UDUAd6JQ/RwzaQy6mXmsk/IzlYyal4A4SNFw54MeH4/tLkF4I5WoWG9SQwuqWzS99jaFQHBuQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/npm-pick-manifest/node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest/node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/npm-registry-fetch/node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch/node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -23115,8 +26033,6 @@ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -23241,8 +26157,6 @@ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -23492,6 +26406,94 @@ "dev": true, "license": "BlueOak-1.0.0" }, + "node_modules/pacote": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-21.0.0.tgz", + "integrity": "sha512-lcqexq73AMv6QNLo7SOpz0JJoaGdS3rBFgF122NZVl1bApo2mfu+XzUBU/X/XsiJu+iUmKpekRayqQYAs+PhkA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^10.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/pacote/node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/pacote/node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/pacote/node_modules/validate-npm-package-name": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.2.tgz", + "integrity": "sha512-IUoow1YUtvoBBC06dXs8bR8B9vuA3aJfmQNKMoaPG/OFsPmoQvw8xh+6Ye25Gx9DQhoEom3Pcu9MKHerm/NpUQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/pako": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", @@ -23569,8 +26571,6 @@ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -23874,6 +26874,16 @@ "@napi-rs/nice": "^1.0.1" } }, + "node_modules/pkce-challenge": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.20.0" + } + }, "node_modules/pkg-dir": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", @@ -24181,8 +27191,22 @@ "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==", "dev": true, "license": "MIT", - "optional": true, - "peer": true + "optional": true, + "peer": true + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -24190,8 +27214,6 @@ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -24273,12 +27295,13 @@ } }, "node_modules/qs": { - "version": "6.13.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.1.tgz", - "integrity": "sha512-EJPeIn0CYrGu+hli1xilKAPXODtJ12T0sP63Ijx2/khC2JtuaN3JyNIpvmnkmaEtha9ocbG4A4cMcr+TvqvwQg==", + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "side-channel": "^1.1.0" }, "engines": { "node": ">=0.6" @@ -24393,8 +27416,6 @@ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.6" } @@ -24733,6 +27754,16 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -24742,6 +27773,13 @@ "node": ">=0.10.0" } }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, "node_modules/rollup": { "version": "4.53.3", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.53.3.tgz", @@ -24783,6 +27821,41 @@ "fsevents": "~2.3.2" } }, + "node_modules/router": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", + "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.4.0", + "depd": "^2.0.0", + "is-promise": "^4.0.0", + "parseurl": "^1.3.3", + "path-to-regexp": "^8.0.0" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/router/node_modules/is-promise": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", + "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/router/node_modules/path-to-regexp": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", + "dev": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, "node_modules/rrweb-cssom": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.8.0.tgz", @@ -24812,6 +27885,16 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -25126,9 +28209,7 @@ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", "dev": true, - "license": "ISC", - "optional": true, - "peer": true + "license": "ISC" }, "node_modules/shebang-command": { "version": "2.0.0", @@ -25232,6 +28313,24 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "devOptional": true }, + "node_modules/sigstore": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz", + "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/simple-git": { "version": "3.27.0", "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.27.0.tgz", @@ -25294,6 +28393,17 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, "node_modules/smol-toml": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.3.1.tgz", @@ -25305,6 +28415,36 @@ "url": "https://github.com/sponsors/cyyynthia" } }, + "node_modules/socks": { + "version": "2.8.7", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.7.tgz", + "integrity": "sha512-HLpt+uLy/pxB+bum/9DzAgiKS8CX1EvbWxI4zlmgGCExImLdiad2iCwXT5Z4c9c3Eq8rP2318mPW2c+QbtjK8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^10.0.1", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/sonic-boom": { "version": "3.8.1", "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.8.1.tgz", @@ -25344,12 +28484,13 @@ } }, "node_modules/source-map": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", - "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "version": "0.7.6", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", + "integrity": "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ==", "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">= 8" + "node": ">= 12" } }, "node_modules/source-map-js": { @@ -25379,6 +28520,42 @@ "node": ">=0.10.0" } }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.22", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.22.tgz", + "integrity": "sha512-4PRT4nh1EImPbt2jASOKHX7PB7I+e4IWNLvkKFDxNhJlfjbYlleYQh285Z/3mPTHSAK/AvdMmw5BNNuYH8ShgQ==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/split-on-first": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/split-on-first/-/split-on-first-3.0.0.tgz", @@ -25438,6 +28615,19 @@ "node": ">=0.10.0" } }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/stable-hash": { "version": "0.0.5", "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", @@ -26264,6 +29454,24 @@ "node": ">=6" } }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/tar-stream": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", @@ -26280,6 +29488,89 @@ "node": ">=6" } }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/terminal-size": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/terminal-size/-/terminal-size-4.0.0.tgz", @@ -26531,8 +29822,6 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">=0.6" } @@ -26809,6 +30098,21 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==" }, + "node_modules/tuf-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.1.0.tgz", + "integrity": "sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.4.1", + "make-fetch-happen": "^14.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/tunnel": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", @@ -27157,6 +30461,32 @@ "node": ">= 0.8.0" } }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/universal-user-agent": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-6.0.1.tgz", @@ -27179,8 +30509,6 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -27317,6 +30645,17 @@ "node": ">=10.12.0" } }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, "node_modules/validate-npm-package-name": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", @@ -27345,8 +30684,6 @@ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", "dev": true, "license": "MIT", - "optional": true, - "peer": true, "engines": { "node": ">= 0.8" } @@ -29387,6 +32724,19 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/zod": { "version": "3.25.76", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", @@ -29409,6 +32759,16 @@ "node": ">=20" } }, + "node_modules/zod-to-json-schema": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.0.tgz", + "integrity": "sha512-HvWtU2UG41LALjajJrML6uQejQhNJx+JBO9IflpSja4R03iNWfKXrj6W2h7ljuLyc1nKS+9yDyL/9tD1U/yBnQ==", + "dev": true, + "license": "ISC", + "peerDependencies": { + "zod": "^3.25 || ^4" + } + }, "node_modules/zod-validation-error": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/zod-validation-error/-/zod-validation-error-3.4.0.tgz", @@ -29420,6 +32780,35 @@ "zod": "^3.18.0" } }, + "packages/plugin-bundle-stats": { + "name": "@code-pushup/bundle-stats-plugin", + "version": "0.69.2", + "license": "MIT", + "dependencies": { + "@code-pushup/models": "0.92.1", + "@code-pushup/utils": "0.92.1", + "minimatch": "9.0.3", + "tslib": "^2.3.0" + }, + "devDependencies": { + "@angular/cli": "^20.0.3", + "typescript": "5.4" + } + }, + "packages/plugin-bundle-stats/node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, "packages/plugin-knip": { "name": "@code-pushup/knip-plugin", "version": "0.0.0", diff --git a/package.json b/package.json index f6fb86c..5d3dc49 100644 --- a/package.json +++ b/package.json @@ -57,7 +57,6 @@ "dependencies": { "@code-pushup/cli": "^0.92.1", "@code-pushup/core": "^0.92.1", - "@code-pushup/models": "^0.92.1", "@code-pushup/portal-client": "^0.16.0", "@code-pushup/utils": "^0.92.1", "@poppinss/cliui": "^6.4.1", diff --git a/packages/plugin-bundle-stats/.eslint/eslint-report.json b/packages/plugin-bundle-stats/.eslint/eslint-report.json new file mode 100644 index 0000000..d8eccac --- /dev/null +++ b/packages/plugin-bundle-stats/.eslint/eslint-report.json @@ -0,0 +1,5272 @@ +[ + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.large-angular.config.ts", + "messages": [ + { + "ruleId": null, + "nodeType": null, + "fatal": true, + "severity": 2, + "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.large-angular.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 1, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import bundleStatsPlugin from './src/index.js';\nimport { GroupingRule } from './src/lib/runner/types.js';\nimport { BundleStatsAuditOptions } from './src/lib/types.js';\n\ntype PatternList = string[];\n\nconst allFilesGroups: GroupingRule[] = [\n {\n title: 'Internal Packages',\n includeInputs: ['**/packages/**'],\n icon: '🟣',\n numSegments: 1,\n },\n {\n title: 'External Dependencies',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n numSegments: 1,\n },\n];\n\nconst allFilesAudit: BundleStatsAuditOptions = {\n slug: 'all-files',\n title: '🗂️ All Files',\n description: `\nAnalyzes **complete bundle composition**, identifies **architectural patterns**, tracks **package distribution**, and reveals **size contributors** across all bundle artifacts.`,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*'],\n excludeOutputs: ['**/*.map', '**/*.d.ts'],\n },\n insightsTable: {\n mode: 'all',\n groups: allFilesGroups,\n },\n dependencyTree: { enabled: false },\n};\n\nconst initialBundleSizeTableGroups: GroupingRule[] = [\n {\n title: 'Blacklisted/Deprecated',\n icon: '🚫',\n includeInputs: [\n '**/node_modules/lodash/**',\n '**/node_modules/zone.js/**',\n '**/node_modules/smoothscroll-polyfill/**',\n '**/node_modules/web-animations-js/**',\n '**/node_modules/decimal.js/**',\n '**/node_modules/@storybook/**',\n '**/node_modules/jest/**',\n '**/packages/themepark/**',\n ],\n },\n {\n title: 'Lazy-loaded',\n icon: '⏳',\n includeInputs: [\n '**/node_modules/socket.io-client/**',\n '**/node_modules/launchdarkly-js-client-sdk/**',\n '**/node_modules/@microsoft/**',\n '**/node_modules/ngx-scrollbar/**',\n '**/node_modules/howler/**',\n '**/node_modules/hls.js/**',\n '**/node_modules/lottie-web/**',\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/ua-parser-js/**',\n ],\n },\n {\n title: 'Angular',\n includeInputs: [\n '**/node_modules/*angular*/**',\n '**/node_modules/@ng*/**',\n '**/node_modules/@ngx-*/**',\n '**/node_modules/ngx-*/**',\n '**/node_modules/ng-*/**',\n ],\n icon: '🅰️',\n numSegments: 2,\n },\n {\n title: 'Third-party',\n icon: '📚',\n includeInputs: [\n '**/node_modules/react/**',\n '**/node_modules/lodash-es/**',\n '**/node_modules/rxjs/**',\n '**/node_modules/moment/**',\n '**/node_modules/dayjs/**',\n ],\n numSegments: 2,\n },\n {\n title: 'Product',\n icon: '🎮',\n includeInputs: [\n '**/packages/payments/**',\n '**/packages/casino/**',\n '**/packages/bingo/**',\n '**/packages/sports/**',\n '**/packages/poker/**',\n '**/packages/lottery/**',\n '**/packages/horseracing/**',\n '**/packages/oxygen/**',\n '**/packages/myaccount/**',\n '**/packages/promo/**',\n '**/packages/mokabingo/**',\n ],\n numSegments: 2,\n },\n {\n title: 'Internal utils',\n icon: '🔧',\n includeInputs: [\n '**/packages/design-system/**',\n '**/packages/utils/**',\n '**/packages/shared/**',\n '**/packages/common/**',\n ],\n },\n {\n title: 'Node modules',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n];\n\nconst initialBundleSizeTreeGroups: GroupingRule[] = [\n {\n includeInputs: ['**/node_modules/*angular*/**'],\n icon: '🅰️',\n numSegments: 2,\n },\n {\n title: 'Design System',\n includeInputs: ['**/packages/design-system/**'],\n icon: '🟣',\n },\n {\n title: 'Deprecated Theme',\n includeInputs: ['**/packages/themepark/**'],\n icon: '🚫',\n },\n {\n includeInputs: ['**/packages/**'],\n icon: '🟣',\n numSegments: 2,\n },\n {\n title: 'Payments',\n includeInputs: ['**/packages/payments/**'],\n icon: '💳',\n },\n {\n title: 'Casino',\n includeInputs: ['**/packages/casino/**'],\n icon: '🎰',\n },\n {\n title: 'Bingo',\n includeInputs: ['**/packages/bingo/**'],\n icon: '🎯',\n },\n {\n title: 'Sports',\n includeInputs: ['**/packages/sports/**'],\n icon: '⚽',\n },\n {\n title: 'Poker',\n includeInputs: ['**/packages/poker/**'],\n icon: '🃏',\n },\n {\n title: 'Lottery',\n includeInputs: ['**/packages/lottery/**'],\n icon: '🎲',\n },\n {\n title: 'Horse Racing',\n includeInputs: ['**/packages/horseracing/**'],\n icon: '🐎',\n },\n {\n title: 'Oxygen',\n includeInputs: ['**/packages/oxygen/**'],\n icon: '🫧',\n },\n {\n title: 'My Account',\n includeInputs: ['**/packages/myaccount/**'],\n icon: '👤',\n },\n {\n title: 'Promotions',\n includeInputs: ['**/packages/promo/**'],\n icon: '🎁',\n },\n {\n title: 'Moka Bingo',\n includeInputs: ['**/packages/mokabingo/**'],\n icon: '🎯',\n },\n {\n title: 'React',\n includeInputs: ['**/node_modules/react/**'],\n icon: '⚛️',\n },\n {\n title: 'Lodash ES',\n includeInputs: ['**/node_modules/lodash-es/**'],\n icon: '🔧',\n },\n {\n title: 'Node Modules',\n includeInputs: ['**/node_modules/**'],\n numSegments: 2,\n },\n];\n\nconst initialBundleSizeAudit: BundleStatsAuditOptions = {\n slug: 'initial-bundle-size',\n title: '🔥 Initial Bundle Size',\n description: `\nMonitors **critical loading performance**, enforces **size budgets**, detects **bloat sources**, and prevents **slow startup times** in main application bundles.`,\n selection: {\n mode: 'withStartupDeps',\n includeOutputs: ['**/main*.js', '**/polyfill*.js', '**/styles*.css'],\n excludeOutputs: ['**/*.map', '**/*.d.ts'],\n },\n scoring: {\n totalSize: 1_000_000,\n penalty: {\n artefactSize: [100, 100_000],\n },\n },\n insightsTable: {\n mode: 'all',\n groups: initialBundleSizeTableGroups,\n },\n dependencyTree: {\n groups: initialBundleSizeTreeGroups,\n },\n};\n\nconst blacklist = [\n // IMMEDIATE PRIORITY - Dead dependency, can be removed immediately\n {\n pattern: '**/node_modules/angular2-toaster/**',\n hint: '`angular2-toaster` is deprecated and unused. Please remove from package.json - already replaced by `ds-toast`.',\n },\n\n // HIGH PRIORITY - Full DS alternative available\n {\n pattern: '**/node_modules/ngx-float-ui/**',\n hint: '`ngx-float-ui` is being replaced by `ds-tooltip` for consistency and reduced dependencies. The DS tooltip supports 4 positions and 3 arrow positions with advanced overlay integration.',\n },\n\n // MEDIUM PRIORITY - DS alternatives available but need extensions\n {\n pattern: '**/node_modules/@angular-slider/ngx-slider/**',\n hint: '`@angular-slider/ngx-slider` adds significant bundle size. `ds-range-selector` is available but needs custom case extensions from HoneyBadgers team. For new code only: use `ds-range-selector`.',\n },\n\n {\n pattern: '**/node_modules/ngx-slider-v2/**',\n hint: '`ngx-slider-v2` bundle impact unknown and appears less maintained than @angular-slider/ngx-slider. `ds-range-selector` available but needs custom case extensions. For new code only: use `ds-range-selector`.',\n },\n\n {\n pattern: '**/node_modules/ngx-toastr/**',\n hint: '`ngx-toastr` adds significant bundle size. Consider `ds-toast` for new components. Service pattern migration pending - missing show/hide programmatic API. Contact HoneyBadgers team for service API.',\n },\n\n // LOW PRIORITY - Strategic migration candidates\n {\n pattern: '**/node_modules/@angular/material/dialog/**',\n hint: 'Consider `ds-modal` or `ds-dialog` for new components. Existing usage can remain until strategic migration phase due to complexity.',\n },\n\n {\n pattern: '**/node_modules/@angular/material/slider/**',\n hint: '`ds-range-selector` available but needs validation for Material slider compatibility and feature coverage. For new code only: use `ds-range-selector`.',\n },\n\n {\n pattern: '**/node_modules/@angular/material/bottom-sheet/**',\n hint: 'Consider `ds-modal` with bottom positioning for new components. Existing bottom-sheet usage can remain until strategic migration.',\n },\n];\n\nconst blacklistedFilesGroups: GroupingRule[] = [\n {\n title: 'Legacy/Deprecated',\n icon: '🕸️',\n includeInputs: [\n '**/node_modules/core-js/**',\n '**/node_modules/zone.js/**',\n '**/node_modules/smoothscroll-polyfill/**',\n '**/node_modules/web-animations-js/**',\n '**/node_modules/decimal.js/**',\n '**/node_modules/@storybook/**',\n '**/node_modules/jest/**',\n ],\n },\n {\n title: 'Blacklisted',\n icon: '🚫',\n includeInputs: [\n '**/node_modules/lodash/**',\n // New blacklisted dependencies with DS alternatives\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular-slider/ngx-slider/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular/material/dialog/**',\n '**/node_modules/@angular/material/slider/**',\n '**/node_modules/@angular/material/bottom-sheet/**',\n ],\n },\n];\n\nconst angularSpecificTableGroups: GroupingRule[] = [\n {\n includeInputs: [\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/angular2-toaster/**',\n ],\n icon: '🚨',\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular-slider/**',\n ],\n icon: '🚫',\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@ng-bootstrap/**',\n '**/node_modules/ng-circle-progress/**',\n ],\n icon: '🕸️',\n numSegments: 2,\n },\n {\n includeInputs: ['**/node_modules/ngx-float-ui/**'],\n icon: '⚠️',\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@angular/core/**',\n '**/node_modules/@angular/common/**',\n '**/node_modules/@angular/platform-browser/**',\n '**/node_modules/@angular/platform-browser-dynamic/**',\n '**/node_modules/@angular/forms/**',\n '**/node_modules/@angular/router/**',\n '**/node_modules/@angular/animations/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@angular/material/**',\n '**/node_modules/@angular/cdk/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@ngrx/**',\n '**/node_modules/@rx-angular/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/ngx-daterangepicker-material/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-scrollbar/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@ngx-translate/**',\n '**/node_modules/ng-dynamic-component/**',\n '**/node_modules/ng-in-viewport/**',\n '**/node_modules/ng-lazyload-image/**',\n '**/node_modules/angularx-qrcode/**',\n '**/node_modules/ngx-lottie/**',\n '**/node_modules/ngx-popperjs/**',\n '**/node_modules/@ngu/**',\n ],\n numSegments: 2,\n },\n {\n title: 'Other Angular Packages',\n includeInputs: [\n '**/node_modules/angular*/**',\n '**/node_modules/ng-*/**',\n '**/node_modules/ngx-*/**',\n '**/node_modules/@ng*/**',\n '**/node_modules/*angular*/**',\n ],\n },\n];\n\nconst angularSpecificTreeGroups: GroupingRule[] = angularSpecificTableGroups;\n\nconst angularSpecificAudit: BundleStatsAuditOptions = {\n slug: 'angular-ecosystem',\n title: '🅰️ Angular Ecosystem',\n description: `\n**Security-first Angular analysis**: Identifies **security vulnerabilities**, **blacklisted packages**, **deprecated dependencies**, and **oversized components** to ensure a secure and optimized Angular application.`,\n selection: {\n mode: 'matchingOnly',\n includeInputs: [\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular-slider/**',\n '**/node_modules/@ng-bootstrap/**',\n '**/node_modules/ng-circle-progress/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular/core/**',\n '**/node_modules/@angular/common/**',\n '**/node_modules/@angular/platform-browser/**',\n '**/node_modules/@angular/platform-browser-dynamic/**',\n '**/node_modules/@angular/forms/**',\n '**/node_modules/@angular/router/**',\n '**/node_modules/@angular/animations/**',\n '**/node_modules/@angular/material/**',\n '**/node_modules/@angular/cdk/**',\n '**/node_modules/@ngrx/**',\n '**/node_modules/@rx-angular/**',\n '**/node_modules/ngx-daterangepicker-material/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-scrollbar/**',\n '**/node_modules/@ngx-translate/**',\n '**/node_modules/ng-dynamic-component/**',\n '**/node_modules/ng-in-viewport/**',\n '**/node_modules/angularx-qrcode/**',\n '**/node_modules/ngx-lottie/**',\n '**/node_modules/ngx-popperjs/**',\n '**/node_modules/sports-animations/**',\n ],\n excludeInputs: ['**/*.map', '**/*.d.ts'],\n },\n insightsTable: {\n mode: 'onlyMatching',\n groups: angularSpecificTableGroups,\n },\n dependencyTree: {\n mode: 'onlyMatching',\n groups: angularSpecificTreeGroups,\n },\n};\n\nconst dependencyAuditBlacklistedGroup: GroupingRule = {\n icon: '🚫',\n includeInputs: [\n '**/node_modules/react/**',\n '**/node_modules/react-dom/**',\n '**/node_modules/lodash/**',\n '**/node_modules/underscore/**',\n '**/node_modules/@babel/**',\n '**/node_modules/moment/**',\n '**/node_modules/ng-lazyload-image/**',\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular-slider/ngx-slider/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular/material/dialog/**',\n '**/node_modules/@angular/material/slider/**',\n '**/node_modules/@angular/material/bottom-sheet/**',\n ],\n numSegments: 2,\n};\n\nconst dependencyAuditLegacyGroup: GroupingRule = {\n icon: '🕸️',\n includeInputs: [\n '**/node_modules/core-js/**',\n '**/node_modules/zone.js/**',\n '**/node_modules/smoothscroll-polyfill/**',\n '**/node_modules/decimal.js/**',\n ],\n numSegments: 2,\n};\n\nconst dependencyAuditAcceptedGroup: GroupingRule = {\n title: 'Accepted Dependencies',\n icon: '✅',\n includeInputs: [\n '**/node_modules/@module-federation/**',\n '**/node_modules/launchdarkly-js-client-sdk/**',\n '**/node_modules/socket.io-client/**',\n '**/node_modules/@microsoft/**',\n '**/node_modules/qrcode/**',\n '**/node_modules/dompurify/**',\n '**/node_modules/hammerjs/**',\n '**/node_modules/js-sha512/**',\n '**/node_modules/ua-parser-js/**',\n '**/node_modules/pixi-multistyle-text/**',\n '**/node_modules/howler/**',\n '**/node_modules/tslib/**',\n '**/node_modules/@incodetech/**',\n '**/node_modules/@emotion/**',\n '**/node_modules/scheduler/**',\n '**/node_modules/@jumio/**',\n '**/node_modules/moment-timezone/**',\n '**/node_modules/@pixi/**',\n '**/node_modules/gsap/**',\n '**/node_modules/qs/**',\n '**/node_modules/url/**',\n '**/node_modules/object-inspect/**',\n '**/node_modules/get-intrinsic/**',\n '**/node_modules/fontfaceobserver/**',\n '**/node_modules/earcut/**',\n '**/node_modules/pixi.js/**',\n '**/node_modules/sports-animations/**',\n '**/node_modules/konva/**',\n '**/node_modules/live-sports-visualization/**',\n '**/node_modules/@img-arena/**',\n '**/node_modules/@seontechnologies/**',\n '**/node_modules/jspdf/**',\n '**/node_modules/fflate/**',\n '**/node_modules/braintree-web/**',\n '**/node_modules/lodash-es/**',\n '**/node_modules/@floating-ui/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@rtms/**',\n '**/node_modules/@push-based/**',\n '**/node_modules/rxjs/**',\n '**/node_modules/bwin-tweenmax/**',\n '**/node_modules/swiper/**',\n '**/node_modules/bwin-winwheel/**',\n '**/node_modules/canvg/**',\n '**/node_modules/svg-pathdata/**',\n '**/node_modules/rgbcolor/**',\n '**/node_modules/stackblur-canvas/**',\n '**/node_modules/xml2js/**',\n '**/node_modules/buffer/**',\n '**/node_modules/sax/**',\n '**/node_modules/events/**',\n '**/node_modules/string_decoder/**',\n '**/node_modules/stream/**',\n '**/node_modules/primeng/**',\n '**/node_modules/ngx-daterangepicker-material/**',\n '**/node_modules/jspdf-autotable/**',\n '**/node_modules/dayjs/**',\n '**/node_modules/dexie/**',\n '**/node_modules/ng-lazyload-image/**',\n '**/node_modules/@opentelemetry/**',\n '**/node_modules/html2canvas/**',\n '**/node_modules/fastdom/**',\n '**/node_modules/base64-js/**',\n '**/node_modules/component-emitter/**',\n '**/node_modules/dijkstrajs/**',\n '**/node_modules/parseuri/**',\n '**/node_modules/has-symbols/**',\n '**/node_modules/function-bind/**',\n '**/node_modules/object-assign/**',\n '**/node_modules/raf/**',\n '**/node_modules/blob/**',\n '**/node_modules/ieee754/**',\n '**/node_modules/has-binary2/**',\n '**/node_modules/side-channel-weakmap/**',\n '**/node_modules/js-levenshtein/**',\n '**/node_modules/safe-buffer/**',\n '**/node_modules/detect-it/**',\n '**/node_modules/side-channel-list/**',\n '**/node_modules/timers/**',\n '**/node_modules/backo2/**',\n '**/node_modules/side-channel-map/**',\n '**/node_modules/encode-utf8/**',\n '**/node_modules/math-intrinsics/**',\n '**/node_modules/call-bind-apply-helpers/**',\n '**/node_modules/performance-now/**',\n '**/node_modules/custom-event-js/**',\n '**/node_modules/subsink/**',\n '**/node_modules/safe-buffer/**',\n '**/node_modules/detect-it/**',\n '**/node_modules/side-channel-list/**',\n '**/node_modules/timers/**',\n '**/node_modules/backo2/**',\n '**/node_modules/side-channel-map/**',\n '**/node_modules/encode-utf8/**',\n '**/node_modules/math-intrinsics/**',\n '**/node_modules/call-bind-apply-helpers/**',\n '**/node_modules/performance-now/**',\n '**/node_modules/custom-event-js/**',\n '**/node_modules/subsink/**',\n '**/node_modules/get-proto/**',\n '**/node_modules/yeast/**',\n '**/node_modules/es-errors/**',\n '**/node_modules/dunder-proto/**',\n '**/node_modules/side-channel/**',\n '**/node_modules/parseqs/**',\n '**/node_modules/mitt/**',\n '**/node_modules/arraybuffer.slice/**',\n '**/node_modules/component-bind/**',\n '**/node_modules/after/**',\n '**/node_modules/call-bound/**',\n '**/node_modules/gopd/**',\n '**/node_modules/socket.io-client/**',\n '**/node_modules/indexof/**',\n '**/node_modules/hasown/**',\n '**/node_modules/component-inherit/**',\n '**/node_modules/es-define-property/**',\n '**/node_modules/has-cors/**',\n '**/node_modules/to-array/**',\n '**/node_modules/es-object-atoms/**',\n '**/node_modules/xhr2/**',\n '**/node_modules/fast-json-patch/**',\n '**/node_modules/canvas-confetti/**',\n '**/node_modules/cssfilter/**',\n '**/node_modules/xss/**',\n '**/node_modules/cds-client/**',\n '**/node_modules/immer/**',\n '**/node_modules/resize-observer-polyfill/**',\n '**/node_modules/fontfaceobserver-es/**',\n '**/node_modules/@cloudflare/**',\n '**/node_modules/css-element-queries/**',\n '**/node_modules/blueimp-md5/**',\n '**/node_modules/isomorphic-rslog/**',\n '**/node_modules/@swimlane/**',\n '**/node_modules/lottie-web/**',\n '**/node_modules/ngx-scrollbar/**',\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/@ngrx/**',\n '**/node_modules/@ng-bootstrap/**',\n '**/node_modules/@rx-angular/**',\n '**/node_modules/@ngu/**',\n '**/node_modules/@angular/**',\n '**/node_modules/ng-circle-progress/**',\n '**/node_modules/ngx-popperjs/**',\n '**/node_modules/ng-dynamic-component/**',\n '**/node_modules/ng-in-viewport/**',\n '**/node_modules/angularx-qrcode/**',\n '**/node_modules/ngx-lottie/**',\n '**/node_modules/socket.io-client/**',\n ],\n numSegments: 1,\n};\n\nconst dependencyAuditNewGroup: GroupingRule = {\n icon: '🆕',\n includeInputs: '**/node_modules/**',\n excludeInputs: [\n ...dependencyAuditAcceptedGroup.includeInputs,\n ...dependencyAuditBlacklistedGroup.includeInputs,\n ...dependencyAuditLegacyGroup.includeInputs,\n ],\n numSegments: 2,\n};\n\nconst dependencyAuditTableGroups: GroupingRule[] = [\n dependencyAuditBlacklistedGroup,\n dependencyAuditLegacyGroup,\n dependencyAuditAcceptedGroup,\n dependencyAuditNewGroup,\n];\n\nconst dependencyAuditTreeGroups: GroupingRule[] = [\n dependencyAuditBlacklistedGroup,\n dependencyAuditLegacyGroup,\n dependencyAuditNewGroup,\n];\n\nconst dependencyAudit: BundleStatsAuditOptions = {\n slug: 'node-modules',\n title: '📦 Dependency Tracking',\n description: `\nDetects *newly added packages*, catches **forbidden dependencies**, monitors **3rd party costs**, and prevents **bundle bloat** from unreviewed dependencies.`,\n selection: {\n mode: 'matchingOnly',\n includeInputs: ['**/node_modules/**'],\n },\n insightsTable: {\n mode: 'onlyMatching',\n groups: dependencyAuditTableGroups,\n pruning: {\n // minSize: 2000,\n },\n },\n dependencyTree: {\n mode: 'onlyMatching',\n groups: [\n dependencyAuditBlacklistedGroup,\n dependencyAuditLegacyGroup,\n dependencyAuditNewGroup,\n ],\n pruning: {\n maxChildren: 150,\n },\n },\n};\n\nconst blacklistedFilesAudit: BundleStatsAuditOptions = {\n slug: 'blacklisted',\n title: '🚫 Blacklisted Files',\n description: `\nMonitors **blacklisted dependencies** and **deprecated packages** that are present in the bundle. This helps identify potential security risks and compliance issues.`,\n selection: {\n mode: 'matchingOnly',\n includeInputs: [\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular-slider/ngx-slider/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular/material/dialog/**',\n '**/node_modules/@angular/material/slider/**',\n '**/node_modules/@angular/material/bottom-sheet/**',\n ],\n },\n insightsTable: {\n mode: 'onlyMatching',\n groups: blacklistedFilesGroups,\n },\n dependencyTree: {\n mode: 'onlyMatching',\n groups: blacklistedFilesGroups,\n },\n};\n\nconst config = {\n plugins: [\n await bundleStatsPlugin({\n bundler: 'esbuild',\n artifactsPaths:\n './packages/plugin-bundle-stats/mocks/fixtures/stats/angular-large.stats.json',\n audits: [\n allFilesAudit,\n blacklistedFilesAudit,\n angularSpecificAudit,\n dependencyAudit,\n initialBundleSizeAudit,\n ],\n }),\n ],\n};\n\nexport default config;\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts", + "messages": [ + { + "ruleId": null, + "nodeType": null, + "fatal": true, + "severity": 2, + "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 1, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { CoreConfig } from '../models/src/index.js';\nimport bundleStatsPlugin from './src';\n\nconst config: CoreConfig = {\n plugins: [\n await bundleStatsPlugin({\n artifactsPaths:\n 'packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json',\n bundler: 'sonda',\n audits: [\n {\n slug: 'bundle-size',\n title: 'Bundle Size Analysis',\n description: 'Analyzes bundle size using Sonda report',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*.js'],\n },\n scoring: {\n totalSize: 100_000,\n },\n },\n ],\n }),\n ],\n categories: [\n {\n slug: 'performance',\n title: '⚡ Performance',\n description: 'Bundle performance analysis using Sonda',\n refs: [\n {\n type: 'audit',\n plugin: 'bundle-stats',\n slug: 'bundle-size',\n weight: 1,\n },\n ],\n },\n ],\n};\n\nexport default (async () => {\n return config;\n})();\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts", + "messages": [ + { + "ruleId": null, + "nodeType": null, + "fatal": true, + "severity": 2, + "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 1, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { CoreConfig } from '../models/src/index.js';\nimport bundleStatsPlugin from './src';\nimport { MinMax } from './src/lib/runner/types';\nimport { BundleStatsAuditOptions } from './src/lib/types';\n\n/**\n * Execute code-pushup over Nx:\n * nx code-pushup:minimal plugin-bundle-stats\n */\n\n// ===== Selection Constants =====\nconst SELECTION_ALL_OUTPUTS = {\n includeOutputs: ['**/*'],\n};\n\nconst SELECTION_OUTPUTS_INDEX_FILE = ['**/index.ts'];\n\nconst SELECTION_ONE_FILE = {\n mode: 'bundle' as const,\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n};\n// ===== Scoring Constants =====\n\nconst THRESHOLD_ALWAYS_PASS_MAX = 100_000; // 100KB - much higher than actual bundle size\nconst THRESHOLD_ALWAYS_FAIL_MAX = 1;\nconst THRESHOLD_ALWAYS_FAIL_MIN = 1;\nconst THRESHOLD_ALWAYS_PASS_MIN = 0;\nconst THRESHOLD_ALWAYS_PASS_RANGE: MinMax = [\n THRESHOLD_ALWAYS_PASS_MIN,\n THRESHOLD_ALWAYS_PASS_MAX,\n];\n\nconst DISABLED = {\n enabled: false,\n totalSize: THRESHOLD_ALWAYS_PASS_MAX,\n};\n\nconst BASE_AUDIT_ALL_FILES = {\n selection: {\n mode: 'bundle' as const,\n includeOutputs: ['**/*.js'],\n },\n};\n\nconst BASE_AUDIT_ALL_FILES_SCORING_DISABLED = {\n selection: {\n mode: 'bundle' as const,\n includeOutputs: ['**/*.js'],\n },\n scoring: DISABLED,\n};\n\n// ===== Audit Groups =====\n\n// ===== Audits =====\n\n// ===== Selection Audits =====\nconst SELECTION_AUDIT_ICON = '🎯';\nconst SELECTION_AUDIT_PREFIX = 'selection';\n\n/**\n * Stats Data\n *\n * esbuild-minimal.stats.json\n * └── outputs\n * ├── dist/index.js // entryPoint: ../shared-source/src/index.ts (595 B)\n * │ ├── inputs\n * │ │ └── ../shared-source/src/index.ts (386 B)\n * │ └── imports\n * │ ├── dist/chunks/chunk-PKX4VJZC.js // import-statement\n * │ ├── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * │ └── dist/chunks/feature-2-SERQNJVR.js // dynamic-import\n * ├── dist/bin.js // entryPoint: ../shared-source/src/bin.ts (549 B)\n * │ ├── inputs\n * │ │ └── ../shared-source/src/bin.ts (373 B)\n * │ └── imports\n * │ ├── dist/chunks/chunk-PKX4VJZC.js // import-statement\n * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * ├── dist/chunks/chunk-PKX4VJZC.js // Main shared chunk (51.35 kB)\n * │ ├── inputs (13 files: node_modules + source)\n * │ │ ├── ../../../../../node_modules/balanced-match/index.js (1.51 kB)\n * │ │ ├── ../../../../../node_modules/brace-expansion/index.js (4.67 kB)\n * │ │ ├── ../../../../../node_modules/minimatch/dist/esm/*.js (6 files, ~42 kB total)\n * │ │ ├── ../shared-source/node_modules/my-lib/index.js (93 B)\n * │ │ ├── ../shared-source/src/lib/utils/format.ts (269 B)\n * │ │ ├── ../shared-source/src/lib/feature-1.ts (269 B)\n * │ │ ├── ../shared-source/src/lib/utils/math.ts (145 B)\n * │ │ └── ../shared-source/src/lib/utils/string.ts (54 B)\n * │ └── imports\n * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * ├── dist/chunks/feature-2-SERQNJVR.js // entryPoint: ../shared-source/src/lib/feature-2.ts (130 B)\n * │ ├── inputs\n * │ │ └── ../shared-source/src/lib/feature-2.ts (38 B)\n * │ └── imports\n * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * └── dist/chunks/chunk-SK6HMZ5B.js // ESM runtime helpers (1.33 kB)\n * ├── inputs: (empty - runtime code)\n * └── imports: (none)\n */\n\nconst SELECTION_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Selection - Mode Audits =====\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-bundle`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - Bundle`,\n description:\n 'Demonstrates bundle mode - standard selection with static imports.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n dependencyTree: {\n pruning: {\n minSize: 1000,\n },\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-matching-only`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - Matching Only`,\n description:\n 'Demonstrates matchingOnly mode - input filtering with size recalculation.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'matchingOnly',\n includeInputs: ['**/utils/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-startup`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - withStartupDeps`,\n description:\n 'Demonstrates withStartupDeps mode - includes static import dependencies.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'withStartupDeps',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-with-all-deps`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - withAllDeps`,\n description:\n 'Demonstrates withAllDeps mode - comprehensive tracking (static + dynamic).',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'withAllDeps',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n },\n\n // ===== Selection - Pattern Audits =====\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-output-include`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Output Include`,\n description: 'Demonstrates including only main chunk files.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-output-include-exclude`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Output Include and Exclude`,\n description:\n 'Demonstrates including and excluding chunk files to focus on entry points.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*.js'],\n excludeOutputs: ['**/chunks/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-input-include`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Input Include`,\n description: 'Demonstrates including only source lib files.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-PKX4VJZC.js'],\n includeInputs: ['**/src/lib/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-input-include-exclude`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Input Include and Exclude`,\n description:\n 'Demonstrates including source lib files but excluding node_modules.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeInputs: ['**/src/lib/**'],\n excludeInputs: ['**/node_modules/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-combined`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Combined`,\n description:\n 'Demonstrates combining multiple chunk types with pattern matching.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js', '**/chunks/feature-*.js'],\n },\n },\n];\n\nconst SCORING_AUDIT_ICON = '📏';\nconst SCORING_AUDIT_PREFIX = 'scoring';\n\nconst SCORING_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Scoring - General Audits =====\n {\n title: `${SCORING_AUDIT_ICON} - Scoring - General - Disabled`,\n description: 'Demonstrates disabled scoring.',\n slug: `${SCORING_AUDIT_PREFIX}-general-disabled`,\n ...BASE_AUDIT_ALL_FILES,\n scoring: {\n enabled: false,\n },\n },\n\n // ===== Scoring - Total Size Audits =====\n {\n slug: `${SCORING_AUDIT_PREFIX}-total-size-pass`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Pass`,\n description:\n 'Demonstrates threshold passing when total size is within range limits.',\n ...BASE_AUDIT_ALL_FILES,\n scoring: { totalSize: THRESHOLD_ALWAYS_PASS_MAX },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-total-size-too-big`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Too Big`,\n description:\n 'Demonstrates threshold failure when total size exceeds simple number limit.',\n ...BASE_AUDIT_ALL_FILES,\n scoring: { totalSize: THRESHOLD_ALWAYS_FAIL_MAX },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-total-size-too-small`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Too Small`,\n description:\n 'Demonstrates threshold warning when total size is below minimum in range.',\n ...BASE_AUDIT_ALL_FILES,\n scoring: {\n totalSize: [THRESHOLD_ALWAYS_FAIL_MIN, THRESHOLD_ALWAYS_PASS_MAX],\n },\n },\n];\n\n// ===== Scoring with Penalty Audits =====\n\nconst SCORING_PENALTY_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Scoring - Penalty - Artefact Size =====\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-pass`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Pass`,\n description:\n 'Demonstrates penalty passing when all files are within size limits.',\n selection: SELECTION_ONE_FILE,\n scoring: {\n penalty: {\n artefactSize: THRESHOLD_ALWAYS_PASS_MAX,\n },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-pass-range`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Pass Range`,\n description: 'Demonstrates penalty passing with min/max range constraints.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: {\n artefactSize: [THRESHOLD_ALWAYS_PASS_MIN, THRESHOLD_ALWAYS_PASS_MAX],\n },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-too-big`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Too Big`,\n description: 'Demonstrates penalty failure when files exceed maximum size.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: { artefactSize: THRESHOLD_ALWAYS_FAIL_MAX },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-too-small`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Too Small`,\n description:\n 'Demonstrates penalty warning when files are below minimum size.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n totalSize: THRESHOLD_ALWAYS_PASS_MAX,\n penalty: {\n artefactSize: [THRESHOLD_ALWAYS_FAIL_MIN, THRESHOLD_ALWAYS_PASS_MAX],\n },\n },\n },\n\n // ===== Scoring - Penalty - Blacklist =====\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-blacklist-pass`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Blacklist Pass`,\n description:\n 'Demonstrates penalty passing when no blacklisted patterns match.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: { blacklist: ['**/non-existent-pattern/**'] },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-blacklist-fail`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Blacklist Fail`,\n description:\n 'Demonstrates penalty failure when blacklisted patterns are found.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: { blacklist: ['**/*'] },\n },\n },\n\n {\n slug: `${SCORING_AUDIT_PREFIX}-mixed-options`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Mixed Options`,\n description: 'Demonstrates mixed scoring options.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n totalSize: 1_000_000,\n penalty: {\n artefactSize: 2_000_000,\n blacklist: ['**/src/lib/utils/math.ts'],\n },\n },\n },\n];\n\n// ===== Issues Audits =====\nconst ISSUES_AUDIT_PREFIX = 'issues';\nconst ISSUES_AUDIT_ICON = '🚨';\n\n// ===== Insights Audits =====\nconst INSIGHT_AUDIT_PREFIX = 'insights';\nconst INSIGHT_AUDIT_ICON = '📊';\n\nconst INSIGHT_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Insights - General Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-general-disabled`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - General - Disabled`,\n description: 'Demonstrates disabled insights table.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: false,\n },\n\n // ===== Insights - View Mode Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-view-mode-only-matching`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - View Mode - Only Matching`,\n description:\n 'Demonstrates onlyMatching mode - shows only files matching selection.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n mode: 'onlyMatching',\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-view-mode-all`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - View Mode - All`,\n description:\n 'Demonstrates all mode - shows all files regardless of selection.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n mode: 'all',\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n ],\n },\n },\n\n // ===== Insights - Pruning Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-pruning-max-children`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Pruning - Max Children`,\n description:\n 'Demonstrates maxChildren pruning - limits table entries shown.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'All Files',\n includeInputs: ['**/*'],\n icon: '📄',\n },\n ],\n pruning: { maxChildren: 3 },\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-pruning-min-size`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Pruning - Min Size`,\n description: 'Demonstrates minSize pruning - filters out small files.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Large Files Only',\n includeInputs: ['**/*'],\n icon: '📄',\n },\n ],\n pruning: { minSize: 1000 },\n },\n },\n\n // ===== Insights - Table Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-table-grouping`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Table - Grouping`,\n description: 'Demonstrates how the bundle is grouped.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Math Utilities',\n includeInputs: ['**/math.ts'],\n icon: '🔧',\n },\n {\n title: 'Formatting Utilities',\n includeInputs: ['**/format.ts'],\n icon: '🔧',\n },\n {\n title: 'Feature 2',\n includeInputs: ['**/*feature-2*'],\n icon: '🧩',\n },\n {\n title: 'Entrypoints',\n includeInputs: ['src/index.ts', 'src/bin.ts'],\n icon: '🏁',\n },\n {\n title: 'Shared Chunks',\n includeInputs: ['dist/chunks/chunk-*.js'],\n icon: '🤝',\n },\n {\n title: 'Node Modules',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n {\n title: 'Distributables',\n includeInputs: ['dist/index.js', 'dist/bin.js'],\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-table-rest-group`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Table - Rest Group`,\n description:\n 'Demonstrates how all non-matching assets are grouped into the \"Rest\" row.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Feature 1',\n includeInputs: ['**/*feature-1*'],\n icon: '🧩',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-groups-pattern-only`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Pattern Only`,\n description:\n 'Demonstrates groups with include patterns only (no title or icon).',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n { includeInputs: ['**/src/**'] },\n { includeInputs: ['**/dist/**'] },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-groups-title-icon`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Title Icon`,\n description: 'Demonstrates groups with title and icon.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n {\n title: 'Node Modules',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-groups-path-segments`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Path Segments`,\n description:\n 'Demonstrates grouping by number of path segments (numSegments).',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n includeInputs: ['**/node_modules/**', '**/node_modules/@*/**'],\n numSegments: 1,\n },\n ],\n },\n },\n];\n\n// ===== Tree Audits =====\nconst TREE_AUDIT_PREFIX = 'tree';\nconst TREE_AUDIT_ICON = '🌳';\n\nconst TREE_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Tree - Disables =====\n {\n slug: `${TREE_AUDIT_PREFIX}-disables`,\n title: `${TREE_AUDIT_ICON} - Tree - Disables`,\n description:\n 'Shows how to explicitly disable dependency trees using enabled: false. You should see audit results but no ASCII tree structure, even when global dependencyTree config exists.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { enabled: false },\n },\n\n // ===== Tree - Mode =====\n {\n slug: `${TREE_AUDIT_PREFIX}-mode-all`,\n title: `${TREE_AUDIT_ICON} - Tree - Mode - All`,\n description:\n 'Demonstrates mode: \"all\" - shows complete file tree regardless of selection filters. Compare with onlyMatching to see the difference in which files appear in the tree.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*'],\n },\n scoring: DISABLED,\n dependencyTree: {\n mode: 'all',\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-mode-onlymatching`,\n title: `${TREE_AUDIT_ICON} - Tree - Mode - OnlyMatching`,\n description:\n 'Demonstrates mode: \"onlyMatching\" (default) - tree only shows files that match the selection criteria. Files outside selection are hidden from tree display.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { mode: 'onlyMatching' },\n },\n\n // ===== Tree - Groups =====\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-include`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Include`,\n description:\n 'Demonstrates groups.include patterns organizing files by type. Shows how dependencies (📦) are grouped with clear visual separation. Uses selection filtering to focus only on node_modules files for a clean demonstration.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n mode: 'onlyMatching',\n pruning: {\n maxDepth: 3,\n },\n groups: [\n {\n includeInputs: ['**/node_modules/**'],\n title: 'Dependencies',\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-exclude`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Exclude`,\n description:\n 'Demonstrates the recommended approach: using selection excludeInputs to filter out node_modules files, combined with mode: \"onlyMatching\". While grouping can organize remaining files, selection filtering is the primary and most reliable way to exclude unwanted files from both table and tree displays.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n mode: 'onlyMatching',\n groups: [\n {\n includeInputs: ['**/index.js'],\n excludeInputs: ['**/node_modules/**'],\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-include-exclude`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Include & Exclude`,\n description:\n 'Shows combining include and exclude patterns for precise filtering. First group shows src files but excludes test files, second shows lib files but excludes test directories.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n includeInputs: ['**/src/**'],\n excludeInputs: ['**/node_modules/**'],\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-title`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Title`,\n description:\n 'Demonstrates groups.title property for custom section headers. Look for \"Source Files\" and \"Dependencies\" labels that replace default path-based grouping names.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n },\n {\n title: 'Dependencies',\n includeInputs: ['**/node_modules/**'],\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-icon`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Icon`,\n description:\n 'Shows groups.icon property adding visual indicators to grouped sections. Look for 📄 icon next to source files and 📦 icon next to dependencies in the tree display.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n {\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-numsegments`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - NumSegments`,\n description:\n 'Demonstrates groups.numSegments for path-based grouping. Node modules are grouped by their top-level package name (1 segment), flattening deep nested structures like @scope/package.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n includeInputs: ['**/node_modules/**', '**/node_modules/@*/**'],\n numSegments: 1,\n },\n ],\n },\n },\n\n // ===== Tree - Pruning =====\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-maxchildren`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - MaxChildren`,\n description:\n 'Shows pruning.maxChildren: 2 limiting displayed children per node. Large directories will show only first 2 entries plus \"...X more items\" to prevent overwhelming output.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { maxChildren: 2 } },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-maxdepth`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - MaxDepth`,\n description:\n 'Demonstrates pruning.maxDepth: 1 limiting tree depth to prevent deep nesting. Only shows immediate children, deeper levels are truncated with continuation indicators.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { maxDepth: 1 } },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-minsize`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - MinSize`,\n description:\n 'Shows pruning.minSize: 1000 filtering out files smaller than 1KB. Small utility files and helpers are hidden, displaying only substantial files that impact bundle size.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { minSize: 1000 } },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-pathlength`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - PathLength`,\n description:\n 'Demonstrates pruning.pathLength: 30 truncating long file paths for readability. Paths longer than 30 characters show as \"...filename.js\" to keep tree display compact.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { pathLength: 30 } },\n },\n];\n\nconst config: CoreConfig = {\n plugins: [\n await bundleStatsPlugin({\n artifactsPaths:\n 'packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json',\n bundler: 'esbuild',\n audits: [\n ...SCORING_AUDITS,\n ...SCORING_PENALTY_AUDITS,\n ...SELECTION_AUDITS,\n ...INSIGHT_AUDITS,\n ...TREE_AUDITS,\n ],\n groups: [\n {\n slug: 'selection-group',\n title: '🎯 Selection',\n description:\n 'Demonstrates different selection modes and pattern matching for bundle analysis.',\n refs: SELECTION_AUDITS.filter(audit => audit.slug).map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n {\n slug: 'scoring-group',\n title: '📏 Scoring',\n description:\n 'Shows scoring mechanisms including thresholds, penalties, and size constraints.',\n refs: [...SCORING_AUDITS, ...SCORING_PENALTY_AUDITS]\n .filter(audit => audit.slug)\n .map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n {\n slug: 'insights-group',\n title: '📊 Insights Table',\n description:\n 'Configures insights tables with grouping, pruning, and visualization options.',\n refs: INSIGHT_AUDITS.filter(audit => audit.slug).map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n {\n slug: 'tree-group',\n title: '🌳 Dependency Tree',\n description:\n 'Demonstrates dependency tree configurations with grouping and pruning strategies.',\n refs: TREE_AUDITS.filter(audit => audit.slug).map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n ],\n }),\n ],\n categories: [\n {\n slug: 'performance',\n title: '⚡ Performance',\n description:\n 'Comprehensive bundle performance analysis including selection, scoring, insights, and dependency trees.',\n refs: [\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'selection-group',\n weight: 1,\n },\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'scoring-group',\n weight: 1,\n },\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'insights-group',\n weight: 1,\n },\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'tree-group',\n weight: 1,\n },\n ],\n },\n ],\n};\n\nexport default (async () => {\n return config;\n})();\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/package.json", + "messages": [ + { + "ruleId": "@nx/dependency-checks", + "severity": 2, + "message": "The \"vite\" package is not used by \"plugin-bundle-stats\" project.", + "line": 29, + "column": 5, + "nodeType": "JSONProperty", + "messageId": "obsoleteDependency", + "endLine": 29, + "endColumn": 20, + "fix": { + "range": [872, 893], + "text": "" + } + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 1, + "fixableWarningCount": 0, + "source": "{\n \"name\": \"@code-pushup/bundle-stats-plugin\",\n \"version\": \"0.69.2\",\n \"license\": \"MIT\",\n \"description\": \"Code PushUp plugin for incrementally adopting strict compilation flags in TypeScript projects\",\n \"homepage\": \"https://github.com/code-pushup/cli/tree/main/packages/plugin-bundle-stats#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/code-pushup/cli/issues?q=is%3Aissue%20state%3Aopen%20type%3ABug%20label%3A\\\"🧩%20bundle-stats-plugin\\\"\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/code-pushup/cli.git\",\n \"directory\": \"packages/plugin-bundle-stats\"\n },\n \"keywords\": [\n \"CLI\",\n \"Code PushUp\",\n \"plugin\",\n \"typescript\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"type\": \"module\",\n \"dependencies\": {\n \"@code-pushup/models\": \"0.92.1\",\n \"@code-pushup/utils\": \"0.92.1\",\n \"minimatch\": \"^10.0.1\",\n \"vite\": \"6.3.5\"\n },\n \"peerDependencies\": {},\n \"scripts\": {},\n \"devDependencies\": {\n \"@angular/cli\": \"^20.0.3\",\n \"typescript\": \"5.4\"\n }\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/index.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/bundle-stats-plugin.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/constants.ts", + "messages": [ + { + "ruleId": "max-lines", + "severity": 1, + "message": "File has too many lines (364). Maximum allowed is 300.", + "line": 306, + "column": 1, + "nodeType": null, + "messageId": "exceed", + "endLine": 380, + "endColumn": 1 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 4.", + "line": 373, + "column": 13, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 373, + "endColumn": 14 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 2, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { PruningConfig } from './runner/audits/details/tree.js';\nimport type { GroupingRule } from './runner/types.js';\n\n/**\n * Default grouping rules for bundle stats analysis.\n * These rules help categorize and organize bundle assets by common patterns.\n */\nexport const DEFAULT_GROUPING: GroupingRule[] = [\n {\n title: '@angular/*',\n includeInputs: ['**/node_modules/@angular/**'],\n icon: '🅰️',\n },\n {\n title: 'react',\n includeInputs: ['**/node_modules/react/**', '**/node_modules/react-dom/**'],\n icon: '⚛️',\n },\n {\n title: 'preact',\n includeInputs: ['**/node_modules/preact/**', '**/node_modules/preact-*/**'],\n icon: '🪐',\n },\n {\n title: 'vue',\n includeInputs: ['**/node_modules/vue/**', '**/node_modules/@vue/**'],\n icon: '💚',\n },\n {\n title: 'solid',\n includeInputs: [\n '**/node_modules/solid-js/**',\n '**/node_modules/solid-*/**',\n ],\n icon: '🟢',\n },\n {\n title: 'lit',\n includeInputs: ['**/node_modules/lit/**', '**/node_modules/lit-html/**'],\n icon: '💡',\n },\n {\n title: 'svelte',\n includeInputs: [\n '**/node_modules/svelte/**',\n '**/node_modules/@sveltejs/**',\n ],\n icon: '🧡',\n },\n {\n title: 'ember',\n includeInputs: [\n '**/node_modules/ember-source/**',\n '**/node_modules/ember-cli/**',\n ],\n icon: '🔥',\n },\n {\n title: 'backbone',\n includeInputs: ['**/node_modules/backbone/**'],\n icon: '🦴',\n },\n {\n title: 'alpine',\n includeInputs: ['**/node_modules/alpinejs/**'],\n icon: '🏔️',\n },\n {\n title: 'next.js',\n includeInputs: ['**/node_modules/next/**'],\n icon: '▲',\n },\n {\n title: 'nuxt',\n includeInputs: ['**/node_modules/nuxt/**', '**/node_modules/@nuxt/**'],\n icon: '💚',\n },\n {\n title: 'sveltekit',\n includeInputs: ['**/node_modules/@sveltejs/kit/**'],\n icon: '🏗️',\n },\n {\n title: 'remix',\n includeInputs: [\n '**/node_modules/remix/**',\n '**/node_modules/@remix-run/**',\n ],\n icon: '🌀',\n },\n {\n title: 'gatsby',\n includeInputs: ['**/node_modules/gatsby/**'],\n icon: '🚀',\n },\n {\n title: 'eleventy',\n includeInputs: ['**/node_modules/eleventy/**', '**/node_modules/@11ty/**'],\n icon: '1️⃣1️⃣',\n },\n {\n title: 'astro',\n includeInputs: ['**/node_modules/astro/**'],\n icon: '🌌',\n },\n {\n title: '@mui/*',\n includeInputs: ['**/node_modules/@mui/**'],\n icon: '🖼️',\n },\n {\n title: 'antd',\n includeInputs: [\n '**/node_modules/antd/**',\n '**/node_modules/@ant-design/**',\n ],\n icon: '🐜',\n },\n {\n title: 'chakra-ui',\n includeInputs: ['**/node_modules/@chakra-ui/**'],\n icon: '🧘',\n },\n {\n title: 'tailwindcss',\n includeInputs: ['**/node_modules/tailwindcss/**'],\n icon: '🌬️',\n },\n {\n title: 'bootstrap',\n includeInputs: ['**/node_modules/bootstrap/**'],\n icon: '👢',\n },\n {\n title: 'bulma',\n includeInputs: ['**/node_modules/bulma/**'],\n icon: '🍹',\n },\n {\n title: 'redux',\n includeInputs: ['**/node_modules/redux/**', '**/node_modules/@reduxjs/**'],\n icon: '🛠️',\n },\n {\n title: 'mobx',\n includeInputs: ['**/node_modules/mobx/**'],\n icon: '🧪',\n },\n {\n title: 'zustand',\n includeInputs: ['**/node_modules/zustand/**'],\n icon: '🧊',\n },\n {\n title: 'recoil',\n includeInputs: ['**/node_modules/recoil/**'],\n icon: '🎱',\n },\n {\n title: 'rxjs',\n includeInputs: ['**/node_modules/rxjs/**'],\n icon: '🔄',\n },\n {\n title: 'xstate',\n includeInputs: ['**/node_modules/xstate/**'],\n icon: '⚙️',\n },\n {\n title: 'react-router',\n includeInputs: [\n '**/node_modules/react-router/**',\n '**/node_modules/react-router-dom/**',\n ],\n icon: '🗺️',\n },\n {\n title: 'vue-router',\n includeInputs: ['**/node_modules/vue-router/**'],\n icon: '🗺️',\n },\n {\n title: 'webpack',\n includeInputs: ['**/node_modules/webpack/**'],\n icon: '📦',\n },\n {\n title: 'rollup',\n includeInputs: ['**/node_modules/rollup/**'],\n icon: '🔄',\n },\n {\n title: 'vite',\n includeInputs: ['**/node_modules/vite/**'],\n icon: '⚡️',\n },\n {\n title: 'parcel',\n includeInputs: [\n '**/node_modules/parcel/**',\n '**/node_modules/parcel-bundler/**',\n ],\n icon: '🎁',\n },\n {\n title: 'esbuild',\n includeInputs: ['**/node_modules/esbuild/**'],\n icon: '🏗️',\n },\n {\n title: 'snowpack',\n includeInputs: ['**/node_modules/snowpack/**'],\n icon: '❄️',\n },\n {\n title: 'jest',\n includeInputs: ['**/node_modules/jest/**'],\n icon: '🎯',\n },\n {\n title: 'mocha',\n includeInputs: ['**/node_modules/mocha/**'],\n icon: '☕️',\n },\n {\n title: 'chai',\n includeInputs: ['**/node_modules/chai/**'],\n icon: '🍵',\n },\n {\n title: 'cypress',\n includeInputs: ['**/node_modules/cypress/**'],\n icon: '🌪️',\n },\n {\n title: 'playwright',\n includeInputs: ['**/node_modules/playwright/**'],\n icon: '🎭',\n },\n {\n title: 'ava',\n includeInputs: ['**/node_modules/ava/**'],\n icon: '🐦',\n },\n {\n title: 'express',\n includeInputs: ['**/node_modules/express/**'],\n icon: '🚆',\n },\n {\n title: 'koa',\n includeInputs: ['**/node_modules/koa/**'],\n icon: '🍵',\n },\n {\n title: 'hapi',\n includeInputs: ['**/node_modules/@hapi/hapi/**'],\n icon: '🎉',\n },\n {\n title: 'fastify',\n includeInputs: ['**/node_modules/fastify/**'],\n icon: '🚀',\n },\n {\n title: '@nestjs/*',\n includeInputs: ['**/node_modules/@nestjs/**'],\n icon: '🔱',\n },\n {\n title: 'sails',\n includeInputs: ['**/node_modules/sails/**'],\n icon: '⛵️',\n },\n {\n title: 'loopback',\n includeInputs: ['**/node_modules/@loopback/**'],\n icon: '🔄',\n },\n {\n title: 'feathers',\n includeInputs: ['**/node_modules/feathers/**'],\n icon: '🪶',\n },\n {\n title: 'meteor',\n includeInputs: ['**/node_modules/meteor/**'],\n icon: '☄️',\n },\n {\n title: 'typeorm',\n includeInputs: ['**/node_modules/typeorm/**'],\n icon: '🗄️',\n },\n {\n title: '@prisma/*',\n includeInputs: ['**/node_modules/@prisma/**'],\n icon: '📐',\n },\n {\n title: 'sequelize',\n includeInputs: ['**/node_modules/sequelize/**'],\n icon: '🐆',\n },\n {\n title: 'mongoose',\n includeInputs: ['**/node_modules/mongoose/**'],\n icon: '🐭',\n },\n {\n title: 'graphql',\n includeInputs: ['**/node_modules/graphql/**'],\n icon: '🔮',\n },\n {\n title: '@apollo/*',\n includeInputs: ['**/node_modules/@apollo/**'],\n icon: '🛰️',\n },\n {\n title: 'axios',\n includeInputs: ['**/node_modules/axios/**'],\n icon: '🎣',\n },\n {\n title: 'socket.io',\n includeInputs: ['**/node_modules/socket.io/**'],\n icon: '🔌',\n },\n {\n title: 'eslint',\n includeInputs: ['**/node_modules/eslint/**'],\n icon: '🧹',\n },\n {\n title: 'prettier',\n includeInputs: ['**/node_modules/prettier/**'],\n icon: '🖌️',\n },\n {\n title: 'husky',\n includeInputs: ['**/node_modules/husky/**'],\n icon: '🐶',\n },\n {\n title: 'lint-staged',\n includeInputs: ['**/node_modules/lint-staged/**'],\n icon: '🐝',\n },\n {\n title: 'storybook',\n includeInputs: ['**/node_modules/@storybook/**'],\n icon: '📖',\n },\n {\n title: 'packages/*',\n includeInputs: ['packages/**/*'],\n // folder icon\n icon: '📁',\n },\n {\n title: 'Dependencies',\n includeInputs: ['**/node_modules/@*/**', '**/node_modules/**'],\n },\n];\n\n/**\n * Default pruning options for bundle stats analysis.\n * These settings control how the bundle tree is simplified and organized.\n */\nexport const DEFAULT_PRUNING: PruningConfig = {\n maxChildren: 10,\n maxDepth: 4,\n};\n\n/**\n * Plugin slug for bundle stats plugin\n */\nexport const BUNDLE_STATS_PLUGIN_SLUG = 'bundle-stats';\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/normalize.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'ExportedBundleStatsConfig' is defined but never used.", + "line": 3, + "column": 36, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 3, + "endColumn": 61 + }, + { + "ruleId": "no-duplicate-imports", + "severity": 1, + "message": "'./runner/audits/scoring.js' import is duplicated.", + "line": 7, + "column": 1, + "nodeType": "ImportDeclaration", + "messageId": "import", + "endLine": 7, + "endColumn": 62 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 28, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 30, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 37, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 37, + "endColumn": 77 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 42, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 42, + "endColumn": 78 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 55, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 58, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 61, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 63, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 64, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 64, + "endColumn": 78 + }, + { + "ruleId": "unicorn/no-array-push-push", + "severity": 1, + "message": "Do not call `Array#push()` multiple times.", + "line": 64, + "column": 13, + "nodeType": "Identifier", + "messageId": "error", + "endLine": 64, + "endColumn": 17, + "suggestions": [ + { + "messageId": "suggestion", + "fix": { + "range": [2380, 2468], + "text": " ` - Error: >\\`${formatBytes(max)}\\` - Exceeds size budget`\n );" + }, + "data": {}, + "desc": "Merge with previous one." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 66, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 66, + "endColumn": 77 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 69, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 69, + "endColumn": 75 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 5.", + "line": 89, + "column": 15, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 89, + "endColumn": 16 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'formatStandardizedTreeSection' has too many lines (77). Maximum allowed is 50.", + "line": 99, + "column": 1, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 184, + "endColumn": 2 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 109, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 109, + "endColumn": 40 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 113, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 113, + "endColumn": 73 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 116, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 116, + "endColumn": 68 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 119, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 119, + "endColumn": 62 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 122, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 122, + "endColumn": 66 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 131, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 131, + "endColumn": 27 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 136, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 136, + "endColumn": 39 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 139, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 139, + "endColumn": 36 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 151, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 151, + "endColumn": 66 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 153, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 153, + "endColumn": 58 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 173, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 173, + "endColumn": 64 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'formatStandardizedSelectionSection' has too many lines (51). Maximum allowed is 50.", + "line": 186, + "column": 1, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 245, + "endColumn": 2 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 192, + "column": 3, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 192, + "endColumn": 48 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 3.", + "line": 197, + "column": 17, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 197, + "endColumn": 18 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 3.", + "line": 201, + "column": 41, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 201, + "endColumn": 42 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 3.", + "line": 202, + "column": 51, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 202, + "endColumn": 52 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 204, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 204, + "endColumn": 59 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 216, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 216, + "endColumn": 59 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 3.", + "line": 222, + "column": 17, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 222, + "endColumn": 18 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 3.", + "line": 226, + "column": 40, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 226, + "endColumn": 41 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 3.", + "line": 227, + "column": 50, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 227, + "endColumn": 51 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 229, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 229, + "endColumn": 58 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 241, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 241, + "endColumn": 58 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 259, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 259, + "endColumn": 47 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 268, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 268, + "endColumn": 36 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 273, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 273, + "endColumn": 35 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 278, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 278, + "endColumn": 38 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 288, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 288, + "endColumn": 34 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 293, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 293, + "endColumn": 33 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 362, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 362, + "endColumn": 60 + }, + { + "ruleId": "max-lines", + "severity": 1, + "message": "File has too many lines (403). Maximum allowed is 300.", + "line": 365, + "column": 1, + "nodeType": null, + "messageId": "exceed", + "endLine": 495, + "endColumn": 1 + }, + { + "ruleId": "@typescript-eslint/consistent-type-assertions", + "severity": 2, + "message": "Always prefer const x: T = { ... }.", + "line": 365, + "column": 25, + "nodeType": "TSAsExpression", + "messageId": "unexpectedObjectTypeAssertion", + "endLine": 368, + "endColumn": 23, + "suggestions": [ + { + "messageId": "replaceObjectTypeAssertionWithSatisfies", + "data": { + "cast": "PenaltyConfig" + }, + "fix": { + "range": [11334, 11531], + "text": "{\n ...restPenalty, // Preserve all penalty properties including warningWeight, errorWeight\n ...(artefactSize ? { artefactSize: normalizeRange(artefactSize) } : {}),\n } satisfies PenaltyConfig" + }, + "desc": "Use const x = { ... } satisfies PenaltyConfig instead." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 387, + "column": 3, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 387, + "endColumn": 70 + } + ], + "suppressedMessages": [], + "errorCount": 30, + "fatalErrorCount": 0, + "warningCount": 16, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { Audit } from '@code-pushup/models';\nimport { formatBytes, slugify } from '@code-pushup/utils';\nimport type { BundleStatsConfig as ExportedBundleStatsConfig } from '../index.js';\nimport type { InsightsTableConfig } from './runner/audits/details/table.js';\nimport type { DependencyTreeConfig } from './runner/audits/details/tree.js';\nimport type { PenaltyConfig, ScoringConfig } from './runner/audits/scoring.js';\nimport { DEFAULT_PENALTY } from './runner/audits/scoring.js';\nimport type { SelectionConfig } from './runner/audits/selection.js';\nimport type { BundleStatsConfig, MinMax } from './runner/types.js';\nimport type {\n BundleStatsAuditOptions,\n PluginBundleStatsAuditOptions,\n PluginDependencyTreeOptions,\n PluginInsightsTableOptions,\n PluginScoringOptions,\n SelectionGeneralConfig,\n SelectionOptions,\n} from './types.js';\n\nfunction formatStandardizedScoringSection(scoring: ScoringConfig): string {\n const { totalSize, penalty } = scoring;\n const items: string[] = [];\n\n // Artefact Size section\n if (penalty && penalty.artefactSize) {\n const [min, max] = penalty.artefactSize;\n const weight = penalty.errorWeight || 0;\n items.push(\n ` - Artefact Size: >\\`${formatBytes(min)}\\` & <\\`${formatBytes(max)}\\`; weight: \\`${weight}\\``,\n );\n }\n\n // Blacklist section\n if (penalty && penalty.blacklist) {\n const count = penalty.blacklist.length;\n const weight = penalty.errorWeight || 0;\n items.push(` - Blacklist: \\`${count}\\` matches; weight: \\`${weight}\\``);\n }\n\n // Total Size section (if configured)\n if (totalSize && totalSize[1] !== Infinity) {\n items.push(` - Total Size: >\\`${formatBytes(totalSize[1])}\\` threshold`);\n }\n\n return items.length > 0 ? `- **Scoring:**\\n${items.join('\\n')}` : '';\n}\n\nfunction formatStandardizedIssuesSection(scoring: ScoringConfig): string {\n const { penalty } = scoring;\n const items: string[] = [];\n\n if (penalty) {\n // Check if this audit generates issues\n if (penalty.blacklist && penalty.blacklist.length > 0) {\n items.push(\n ` - Error: \\`1+\\` candidates - Violation detected, requires action`,\n ` - Info: \\`0\\` candidates - No violations found`,\n );\n } else if (penalty.artefactSize) {\n const [, max] = penalty.artefactSize;\n items.push(\n ` - Warning: <\\`${formatBytes(max)}\\` - Size acceptable but monitor growth`,\n );\n items.push(` - Error: >\\`${formatBytes(max)}\\` - Exceeds size budget`);\n } else {\n items.push(` - Info: \\`0\\` violations - Analysis only, no penalties`);\n }\n } else {\n items.push(` - Info: \\`0\\` violations - Analysis only, no penalties`);\n }\n\n return `- **Issues:**\\n${items.join('\\n')}`;\n}\n\nfunction formatStandardizedTableSection(\n insightsTable: InsightsTableConfig | undefined,\n): string {\n if (\n !insightsTable ||\n !insightsTable.groups ||\n insightsTable.groups.length === 0\n ) {\n return ''; // Hide empty table section\n }\n\n const groupItems = insightsTable.groups\n .filter(group => group.title)\n .map(group => `*${group.icon || ''}${group.title}*`)\n .slice(0, 5); // Limit to prevent overly long descriptions\n\n const groupsText =\n groupItems.length > 0\n ? `Detail listing of ${groupItems.join(', ')}`\n : 'Configured groups';\n\n return `- **Table:**\\n - Groups: ${groupsText}\\n - Rest: Other contributing modules`;\n}\n\nfunction formatStandardizedTreeSection(\n dependencyTree: DependencyTreeConfig | undefined,\n): string {\n if (!dependencyTree) {\n return ''; // Hide disabled tree section\n }\n\n const { pruning, groups, mode } = dependencyTree;\n\n // Format pruning settings\n let pruningText = 'Default settings';\n if (pruning) {\n const pruningParts: string[] = [];\n if (pruning.minSize) {\n pruningParts.push(`Min size: \\`${formatBytes(pruning.minSize)}\\``);\n }\n if (pruning.maxChildren) {\n pruningParts.push(`Max children: \\`${pruning.maxChildren}\\``);\n }\n if (pruning.maxDepth) {\n pruningParts.push(`Max depth: \\`${pruning.maxDepth}\\``);\n }\n if (pruning.pathLength) {\n pruningParts.push(`Path length: \\`${pruning.pathLength}\\``);\n }\n\n if (pruningParts.length > 0) {\n pruningText = pruningParts.join(', ');\n }\n }\n\n // Format groups\n let groupsText = 'None';\n if (groups && groups.length > 0) {\n const groupSummaries = groups.map(group => {\n const parts: string[] = [];\n if (group.title) {\n parts.push(`\"${group.title}\"`);\n }\n if (group.icon) {\n parts.push(`${group.icon}`);\n }\n if (group.includeInputs) {\n if (Array.isArray(group.includeInputs)) {\n const includePatterns = group.includeInputs\n .slice(0, 2)\n .map((p: string) => `\"${p}\"`)\n .join(', ');\n const moreCount =\n group.includeInputs.length > 2\n ? `, +${group.includeInputs.length - 2} more`\n : '';\n parts.push(`include: [${includePatterns}${moreCount}]`);\n } else {\n parts.push(`include: \"${group.includeInputs}\"`);\n }\n }\n if (\n group.excludeInputs &&\n (typeof group.excludeInputs === 'string'\n ? [group.excludeInputs]\n : group.excludeInputs\n ).length > 0\n ) {\n const excludeArray =\n typeof group.excludeInputs === 'string'\n ? [group.excludeInputs]\n : group.excludeInputs;\n const excludePatterns = excludeArray\n .slice(0, 1)\n .map((p: string) => `\"${p}\"`)\n .join(', ');\n const moreCount =\n excludeArray.length > 1 ? `, +${excludeArray.length - 1} more` : '';\n parts.push(`exclude: [${excludePatterns}${moreCount}]`);\n }\n return parts.join(' ');\n });\n groupsText = groupSummaries.join('; ');\n }\n\n // Format mode\n const modeText = mode || 'onlyMatching';\n\n return `- **Tree:**\\n - Mode: \\`${modeText}\\`\\n - Groups: ${groupsText}\\n - Pruning: ${pruningText}`;\n}\n\nfunction formatStandardizedSelectionSection(\n selection: SelectionConfig,\n): string {\n const items: string[] = [];\n\n // Selection mode\n items.push(` - Mode: \\`${selection.mode}\\``);\n\n // Output patterns\n if (selection.includeOutputs.length > 0) {\n const patterns = selection.includeOutputs\n .slice(0, 3)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.includeOutputs.length > 3\n ? ` (+${selection.includeOutputs.length - 3} more)`\n : '';\n items.push(` - Include Outputs: ${patterns}${extra}`);\n }\n\n if (selection.excludeOutputs.length > 0) {\n const patterns = selection.excludeOutputs\n .slice(0, 2)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.excludeOutputs.length > 2\n ? ` (+${selection.excludeOutputs.length - 2} more)`\n : '';\n items.push(` - Exclude Outputs: ${patterns}${extra}`);\n }\n\n // Input patterns\n if (selection.includeInputs.length > 0) {\n const patterns = selection.includeInputs\n .slice(0, 3)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.includeInputs.length > 3\n ? ` (+${selection.includeInputs.length - 3} more)`\n : '';\n items.push(` - Include Inputs: ${patterns}${extra}`);\n }\n\n if (selection.excludeInputs.length > 0) {\n const patterns = selection.excludeInputs\n .slice(0, 2)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.excludeInputs.length > 2\n ? ` (+${selection.excludeInputs.length - 2} more)`\n : '';\n items.push(` - Exclude Inputs: ${patterns}${extra}`);\n }\n\n return `- **Selection:**\\n${items.join('\\n')}`;\n}\n\nexport function cleanTitleForSlug(title: string): string {\n return title\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .toLowerCase();\n}\n\nexport function prepareDescription(config: BundleStatsConfig): string {\n const { description, scoring, selection, dependencyTree, insightsTable } =\n config;\n\n // Start with the action paragraph (preserve existing custom descriptions)\n let enhancedDescription = description || '';\n\n // Only add standardized sections if we have a custom description\n if (enhancedDescription.trim()) {\n const sections: string[] = [];\n\n // Add standardized sections\n const scoringSection = formatStandardizedScoringSection(scoring);\n if (scoringSection) {\n sections.push(scoringSection);\n }\n\n const issuesSection = formatStandardizedIssuesSection(scoring);\n if (issuesSection) {\n sections.push(issuesSection);\n }\n\n const selectionSection = formatStandardizedSelectionSection(selection);\n if (selectionSection) {\n sections.push(selectionSection);\n }\n\n // Handle insightsTable which could be false\n const normalizedInsightsTable =\n insightsTable === false ? undefined : insightsTable;\n const tableSection = formatStandardizedTableSection(\n normalizedInsightsTable,\n );\n if (tableSection) {\n sections.push(tableSection);\n }\n\n const treeSection = formatStandardizedTreeSection(dependencyTree);\n if (treeSection) {\n sections.push(treeSection);\n }\n\n // Wrap config sections in details if any exist\n if (sections.length > 0) {\n const configContent = sections.join('\\n\\n');\n enhancedDescription += `\\n\\n
\\n⚙️ Configuration\\n\\n${configContent}\\n\\n
`;\n }\n }\n\n return enhancedDescription.trim() || '';\n}\n\n/**\n * Converts SelectionGeneralConfig to SelectionOptions by adding default empty arrays.\n */\nexport function selectionGeneralConfigToOptions(\n config: SelectionGeneralConfig,\n): SelectionOptions {\n return {\n ...config,\n mode: 'withStartupDeps',\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n includeImports: [],\n excludeImports: [],\n includeEntryPoints: [],\n excludeEntryPoints: [],\n };\n}\n\nexport function normalizeSelectionOptions(\n options: SelectionOptions | undefined,\n): SelectionConfig {\n if (options === undefined) {\n // Default: include all outputs for startup mode\n return {\n mode: 'withStartupDeps',\n includeOutputs: ['**/*'],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n }\n\n const globalInclude = options.include || [];\n const globalExclude = options.exclude || [];\n\n return {\n mode: options.mode || 'withStartupDeps',\n includeOutputs: [...(options.includeOutputs || []), ...globalInclude],\n excludeOutputs: [...(options.excludeOutputs || []), ...globalExclude],\n includeInputs: [...(options.includeInputs || []), ...globalInclude],\n excludeInputs: [...(options.excludeInputs || []), ...globalExclude],\n };\n}\n\nexport function normalizeBundleStatsOptions(\n auditOptions: BundleStatsAuditOptions,\n): BundleStatsConfig {\n const { slug, title, description, scoring, selection, ...restOptions } =\n auditOptions;\n const { penalty, totalSize } = scoring ?? {};\n\n // Use the proper selection normalization helper that merges global patterns\n const normalizedSelection = normalizeSelectionOptions(selection);\n\n let normalizedPenalty: false | PenaltyConfig | undefined;\n if (penalty && typeof penalty === 'object') {\n const { artefactSize, ...restPenalty } = penalty;\n normalizedPenalty = {\n ...restPenalty, // Preserve all penalty properties including warningWeight, errorWeight\n ...(artefactSize ? { artefactSize: normalizeRange(artefactSize) } : {}),\n } as PenaltyConfig;\n }\n\n const normalizedScoring: ScoringConfig = {\n mode: 'matchingWithStaticImports',\n totalSize: normalizeRange(totalSize ?? Infinity),\n penalty: normalizedPenalty,\n };\n\n const normalizedConfig: BundleStatsConfig = {\n slug: slug ?? slugify(title),\n title,\n description: description || '',\n selection: normalizedSelection,\n scoring: normalizedScoring,\n dependencyTree: restOptions.dependencyTree,\n insightsTable: restOptions.insightsTable,\n };\n\n normalizedConfig.description = prepareDescription(normalizedConfig);\n\n return normalizedConfig;\n}\n\n/**\n * Normalizes scoring options. Converts plugin-level scoring to runner scoring config.\n */\nexport function normalizeScoringOptions(\n options: PluginScoringOptions | undefined,\n): ScoringConfig | undefined {\n if (!options) {\n return undefined;\n }\n\n const { penalty } = options;\n\n return {\n mode: 'matchingWithStaticImports',\n totalSize: [0, Infinity], // Default range\n penalty: penalty\n ? {\n ...DEFAULT_PENALTY,\n ...penalty,\n artefactSize: penalty.artefactSize\n ? normalizeRange(penalty.artefactSize)\n : undefined,\n }\n : DEFAULT_PENALTY,\n };\n}\n\n/**\n * Normalizes dependency tree options from plugin configuration.\n * Groups array overwrites, pruning merges with defaults.\n */\nexport function normalizeDependencyTreeOptions(\n options: PluginDependencyTreeOptions | undefined,\n): DependencyTreeConfig {\n return {\n groups: options?.groups ?? [],\n pruning: {\n maxDepth: 2,\n maxChildren: 10,\n minSize: 1000,\n pathLength: 60,\n ...options?.pruning,\n },\n mode: options?.mode ?? 'onlyMatching',\n };\n}\n\n/**\n * Normalizes insights table options. Converts plugin-level options to runner config.\n */\nexport function normalizeInsightsTableOptions(\n options: PluginInsightsTableOptions | false | undefined,\n): InsightsTableConfig | undefined {\n if (options === false || options === undefined) {\n return undefined;\n }\n\n return {\n mode: options.mode || 'onlyMatching',\n groups: options.groups || [],\n pruning: options.pruning\n ? {\n enabled: options.pruning.enabled ?? false,\n maxChildren: options.pruning.maxChildren,\n minSize: options.pruning.minSize,\n }\n : undefined,\n };\n}\n\nexport function normalizeRange(range: MinMax | number): MinMax {\n if (typeof range === 'number') {\n return [0, range];\n }\n\n return range;\n}\n\nexport function getAuditsFromConfigs(configs: BundleStatsConfig[]): Audit[] {\n return configs.map(({ slug, title, description }) => ({\n slug,\n title,\n description,\n }));\n}\n\n/**\n * Normalizes complete plugin options. Centralizes all normalization logic.\n */\nexport function normalizeBundleStatsAuditOptions(\n auditOptions: BundleStatsAuditOptions[],\n pluginOptions: PluginBundleStatsAuditOptions,\n) {\n return {\n bundleStatsConfigs: auditOptions.map(normalizeBundleStatsOptions),\n scoring: normalizeScoringOptions(pluginOptions.scoring),\n dependencyTree: normalizeDependencyTreeOptions(\n pluginOptions.dependencyTree,\n ),\n insightsTable: normalizeInsightsTableOptions(pluginOptions.insightsTable),\n selection: pluginOptions.selection,\n };\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.ts", + "messages": [ + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 27, + "column": 3, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 27, + "endColumn": 15, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "time" + }, + "fix": { + "range": [1084, 1113], + "text": "" + }, + "desc": "Remove the console.time()." + } + ] + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 29, + "column": 3, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 29, + "endColumn": 18, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "timeEnd" + }, + "fix": { + "range": [1164, 1196], + "text": "" + }, + "desc": "Remove the console.timeEnd()." + } + ] + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 54, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 54, + "endColumn": 17, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "time" + }, + "fix": { + "range": [1845, 1896], + "text": "" + }, + "desc": "Remove the console.time()." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'groupingRules' is assigned a value but never used.", + "line": 57, + "column": 11, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 57, + "endColumn": 24 + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 63, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 63, + "endColumn": 20, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "timeEnd" + }, + "fix": { + "range": [2191, 2245], + "text": "" + }, + "desc": "Remove the console.timeEnd()." + } + ] + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 69, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 69, + "endColumn": 17, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "time" + }, + "fix": { + "range": [2364, 2420], + "text": "" + }, + "desc": "Remove the console.time()." + } + ] + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 71, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 71, + "endColumn": 20, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "timeEnd" + }, + "fix": { + "range": [2485, 2544], + "text": "" + }, + "desc": "Remove the console.timeEnd()." + } + ] + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 0, + "warningCount": 6, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { AuditOutput } from '@code-pushup/models';\nimport type { BundleStatsConfig } from '../types.js';\nimport type { UnifiedStats } from '../unify/unified-stats.types.js';\nimport { createDisplayValue, createEmptyAudit } from '../utils.js';\nimport { createAuditOutputDetails } from './details/audit-details.js';\nimport { getIssues } from './details/issues.js';\nimport { createBundleStatsScoring } from './scoring.js';\nimport { selectBundles } from './selection.js';\n\n/**\n * Calculates total bytes from unified stats tree. Aggregates byte counts across all artefacts.\n */\nexport function calculateTotalBytes(statsSlice: UnifiedStats): number {\n return Object.values(statsSlice).reduce((acc, curr) => acc + curr.bytes, 0);\n}\n\n/**\n * Creates audit output from processed tree data and configuration. Combines size scoring with penalty calculations from actual issues.\n */\nexport function createAuditOutput(\n statsSlice: UnifiedStats,\n config: BundleStatsConfig,\n): AuditOutput {\n const trees = Object.values(statsSlice);\n const totalBytes = calculateTotalBytes(statsSlice);\n\n console.time('⚡ GET_ISSUES');\n const issues = getIssues(statsSlice, config);\n console.timeEnd('⚡ GET_ISSUES');\n\n const calculateScore = createBundleStatsScoring({\n mode: config.scoring.mode,\n totalSize: config.scoring.totalSize,\n penalty: config.scoring.penalty,\n });\n\n return {\n slug: config.slug,\n score: calculateScore(totalBytes, issues),\n value: totalBytes,\n displayValue: createDisplayValue(totalBytes, trees.length),\n details: createAuditOutputDetails(issues, statsSlice, config),\n };\n}\n\n/**\n * Generates audit outputs from bundle stats tree and configurations\n */\nexport function generateAuditOutputs(\n bundleStatsTree: UnifiedStats,\n configs: BundleStatsConfig[],\n): AuditOutput[] {\n return configs.map(config => {\n console.time(`🔍 SELECT_BUNDLES - ${config.slug}`);\n\n // Extract grouping rules for feature mode filtering\n const groupingRules =\n config.insightsTable && typeof config.insightsTable === 'object'\n ? config.insightsTable.groups\n : undefined;\n\n const filteredTree = selectBundles(bundleStatsTree, config.selection);\n console.timeEnd(`🔍 SELECT_BUNDLES - ${config.slug}`);\n\n if (!filteredTree || Object.keys(filteredTree).length === 0) {\n return createEmptyAudit(config);\n }\n\n console.time(`📝 CREATE_AUDIT_OUTPUT - ${config.slug}`);\n const result = createAuditOutput(filteredTree, config);\n console.timeEnd(`📝 CREATE_AUDIT_OUTPUT - ${config.slug}`);\n\n return result;\n });\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.unit.test.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/audit-details.ts", + "messages": [ + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 25, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 25, + "endColumn": 17, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "time" + }, + "fix": { + "range": [778, 819], + "text": "" + }, + "desc": "Remove the console.time()." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 26, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 26, + "endColumn": 74 + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 27, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 27, + "endColumn": 20, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "timeEnd" + }, + "fix": { + "range": [899, 943], + "text": "" + }, + "desc": "Remove the console.timeEnd()." + } + ] + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 38, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 38, + "endColumn": 17, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "time" + }, + "fix": { + "range": [1295, 1326], + "text": "" + }, + "desc": "Remove the console.time()." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 39, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 47, + "endColumn": 6 + }, + { + "ruleId": "no-console", + "severity": 1, + "message": "Unexpected console statement.", + "line": 48, + "column": 5, + "nodeType": "MemberExpression", + "messageId": "unexpected", + "endLine": 48, + "endColumn": 20, + "suggestions": [ + { + "messageId": "removeConsole", + "data": { + "propertyName": "timeEnd" + }, + "fix": { + "range": [1684, 1718], + "text": "" + }, + "desc": "Remove the console.timeEnd()." + } + ] + } + ], + "suppressedMessages": [], + "errorCount": 2, + "fatalErrorCount": 0, + "warningCount": 4, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { AuditDetails, Issue } from '@code-pushup/models';\nimport type { BundleStatsConfig } from '../../types.js';\nimport type { UnifiedStats } from '../../unify/unified-stats.types.js';\nimport { createInsightsTable } from './table.js';\nimport { createTree } from './tree.js';\n\n/**\n * Creates audit details containing issues, insights table, and artifact tree based on configuration.\n * Assembles comprehensive output details for bundle analysis reporting.\n */\nexport function createAuditOutputDetails(\n issues: Issue[],\n statsSlice: UnifiedStats,\n config: BundleStatsConfig,\n): AuditDetails {\n const details: AuditDetails = {\n issues,\n };\n\n if (\n config.insightsTable &&\n config.insightsTable.groups &&\n config.insightsTable.groups.length > 0\n ) {\n console.time('📊 CREATE_INSIGHTS_TABLE');\n details.table = createInsightsTable(statsSlice, config.insightsTable);\n console.timeEnd('📊 CREATE_INSIGHTS_TABLE');\n }\n\n // Check if dependency tree is enabled (default: enabled if config exists)\n const isTreeEnabled =\n config.dependencyTree &&\n typeof config.dependencyTree === 'object' &&\n (!('enabled' in config.dependencyTree) ||\n config.dependencyTree.enabled !== false);\n\n if (isTreeEnabled && typeof config.dependencyTree === 'object') {\n console.time('🌳 CREATE_TREE');\n details.trees = [\n createTree(statsSlice, {\n title: config.slug,\n mode: config.dependencyTree.mode ?? 'onlyMatching',\n pruning: config.dependencyTree.pruning ?? {},\n groups: config.dependencyTree.groups ?? [],\n selection: config.selection, // Pass selection config for onlyMatching filtering\n }),\n ];\n console.timeEnd('🌳 CREATE_TREE');\n }\n\n return details;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/formatting.ts", + "messages": [ + { + "ruleId": "import/no-cycle", + "severity": 2, + "message": "Dependency cycle detected.", + "line": 1, + "column": 1, + "nodeType": "ImportDeclaration", + "endLine": 7, + "endColumn": 24 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 37, + "column": 14, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 37, + "endColumn": 23 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: -2.", + "line": 60, + "column": 33, + "nodeType": "UnaryExpression", + "messageId": "noMagic", + "endLine": 60, + "endColumn": 35 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 83, + "column": 3, + "nodeType": "ForStatement", + "messageId": "generic", + "endLine": 95, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 83, + "column": 8, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 83, + "endColumn": 17 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 98, + "column": 3, + "nodeType": "ForStatement", + "messageId": "generic", + "endLine": 106, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 98, + "column": 8, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 98, + "endColumn": 35 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 129, + "column": 21, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 129, + "endColumn": 41 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 137, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 148, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 158, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 169, + "endColumn": 4 + } + ], + "suppressedMessages": [], + "errorCount": 3, + "fatalErrorCount": 0, + "warningCount": 7, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import {\n extractConcreteSegments,\n extractPathSlice,\n findSegmentIndex,\n normalizePathForMatching,\n splitPathSegments,\n} from './grouping.js';\n\n// Regex cache to avoid recreating the same regex patterns\nconst REGEX_CACHE = new Map();\n\nfunction getCachedRegex(pattern: string): RegExp {\n const cached = REGEX_CACHE.get(pattern);\n if (cached) {\n return cached;\n }\n\n const regex = new RegExp(`${pattern}\\\\/([^\\\\/]+)`);\n REGEX_CACHE.set(pattern, regex);\n return regex;\n}\n\nexport function removeFileExtension(name: string): string {\n return name.replace(/\\.(js|ts|jsx|tsx|css|scss|json)$/, '');\n}\n\nexport function isGenericName(name: string): boolean {\n return name === 'index' || name === 'main' || name === '';\n}\n\nexport function extractScopedPackage(\n path: string,\n): { scope: string; package?: string } | null {\n const match = path.match(/@([^/]+)(?:\\/([^/]+))?/);\n if (match) {\n return {\n scope: match[1]!,\n package: match[2],\n };\n }\n return null;\n}\n\nexport function extractMeaningfulPathPart(path: string): string | null {\n const parts = splitPathSegments(path.replace(/^\\.\\//, ''));\n\n if (parts.length === 0) {\n return null;\n }\n\n const lastPart = parts.at(-1);\n if (lastPart) {\n const withoutExt = removeFileExtension(lastPart);\n if (withoutExt && !isGenericName(withoutExt)) {\n return withoutExt;\n }\n }\n\n if (parts.length > 1) {\n const secondLast = parts.at(-2);\n if (secondLast && !isGenericName(secondLast)) {\n return secondLast;\n }\n }\n\n return null;\n}\n\nexport function cleanupGroupName(groupName: string): string {\n const scopedPackage = extractScopedPackage(groupName);\n if (scopedPackage) {\n return scopedPackage.package\n ? `@${scopedPackage.scope}/${scopedPackage.package}`\n : `@${scopedPackage.scope}`;\n }\n\n const segments = splitPathSegments(groupName);\n if (segments.length === 0) {\n return groupName;\n }\n\n // For scoped packages, try to extract the scope and package\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (!segment) {\n continue;\n }\n\n // Handle scoped packages like @angular/router\n if (segment.startsWith('@') && i + 1 < segments.length) {\n const scopeName = segment.slice(1);\n const packageName = segments[i + 1];\n return packageName ? `@${scopeName}/${packageName}` : `@${scopeName}`;\n }\n }\n\n // Extract the last meaningful segment (the actual package/folder name)\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i];\n if (!segment || isGenericName(segment)) {\n continue;\n }\n\n // Return the first meaningful segment we find from the end\n return segment;\n }\n\n const withoutExt = removeFileExtension(groupName);\n if (isGenericName(withoutExt)) {\n return groupName;\n }\n\n return withoutExt || groupName;\n}\n\nexport function extractGroupKeyFromPattern(\n filePath: string,\n pattern: string,\n maxDepth?: number,\n): string | null {\n const normalizedPath = normalizePathForMatching(filePath);\n const concreteSegments = extractConcreteSegments(pattern);\n\n if (concreteSegments.length === 0) {\n return extractMeaningfulPathPart(normalizedPath);\n }\n\n if (maxDepth && maxDepth > 0 && concreteSegments.length > 0) {\n const keyPart = concreteSegments[0]!;\n const keyIndex = findSegmentIndex(filePath, keyPart);\n\n if (keyIndex !== -1) {\n return extractPathSlice(filePath, keyIndex, maxDepth);\n }\n }\n\n for (const segment of concreteSegments) {\n const regex = getCachedRegex(segment); // Use cached regex\n const match = filePath.match(regex) || normalizedPath.match(regex);\n\n if (match?.[1]) {\n const extracted = match[1];\n const cleaned = removeFileExtension(extracted);\n if (cleaned && !isGenericName(cleaned)) {\n return cleaned;\n }\n }\n }\n\n return null;\n}\n\nexport function deriveGroupTitle(\n path: string,\n patterns: readonly string[],\n fallbackTitle: string,\n): string {\n for (const pattern of patterns) {\n const concreteSegments = extractConcreteSegments(pattern);\n\n if (concreteSegments.includes(fallbackTitle)) {\n return fallbackTitle;\n }\n\n const groupName = extractGroupKeyFromPattern(path, pattern);\n if (groupName) {\n return cleanupGroupName(groupName);\n }\n }\n\n return fallbackTitle;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.ts", + "messages": [ + { + "ruleId": "import/no-cycle", + "severity": 2, + "message": "Dependency cycle detected.", + "line": 3, + "column": 1, + "nodeType": "ImportDeclaration", + "endLine": 7, + "endColumn": 26 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'ArtefactType' is defined but never used.", + "line": 8, + "column": 15, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 8, + "endColumn": 27 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 139, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 145, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 141, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 141, + "endColumn": 45 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 143, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 143, + "endColumn": 36 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 161, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 166, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 175, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 180, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 208, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 218, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 249, + "column": 7, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 249, + "endColumn": 35 + }, + { + "ruleId": "@typescript-eslint/consistent-type-assertions", + "severity": 2, + "message": "Always prefer const x: T = { ... }.", + "line": 252, + "column": 17, + "nodeType": "TSAsExpression", + "messageId": "unexpectedObjectTypeAssertion", + "endLine": 258, + "endColumn": 15, + "suggestions": [ + { + "messageId": "replaceObjectTypeAssertionWithSatisfies", + "data": { + "cast": "T" + }, + "fix": { + "range": [6366, 6493], + "text": "{\n title,\n bytes: 0,\n modules: 0,\n type: 'group',\n icon: rule.icon,\n } satisfies T" + }, + "desc": "Use const x = { ... } satisfies T instead." + } + ] + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 330, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 335, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 348, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 348, + "endColumn": 28 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 349, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 358, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.6.", + "line": 359, + "column": 41, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 359, + "endColumn": 44 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.5.", + "line": 363, + "column": 64, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 363, + "endColumn": 67 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'findCommonPath' has too many lines (70). Maximum allowed is 50.", + "line": 371, + "column": 1, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 448, + "endColumn": 2 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'findCommonPath' is defined but never used.", + "line": 371, + "column": 10, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 371, + "endColumn": 24 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 376, + "column": 29, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 376, + "endColumn": 38 + }, + { + "ruleId": "max-lines", + "severity": 1, + "message": "File has too many lines (489). Maximum allowed is 300.", + "line": 377, + "column": 1, + "nodeType": null, + "messageId": "exceed", + "endLine": 601, + "endColumn": 1 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 400, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 412, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 408, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 408, + "endColumn": 35 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 435, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 435, + "endColumn": 39 + }, + { + "ruleId": "no-param-reassign", + "severity": 2, + "message": "Assignment to property of function parameter 'acc'.", + "line": 435, + "column": 9, + "nodeType": "Identifier", + "messageId": "assignmentToFunctionParamProp", + "endLine": 435, + "endColumn": 12 + }, + { + "ruleId": "@typescript-eslint/consistent-type-assertions", + "severity": 2, + "message": "Always prefer const x: T = { ... }.", + "line": 439, + "column": 5, + "nodeType": "TSAsExpression", + "messageId": "unexpectedObjectTypeAssertion", + "endLine": 439, + "endColumn": 33, + "suggestions": [ + { + "messageId": "replaceObjectTypeAssertionWithSatisfies", + "data": { + "cast": "Record" + }, + "fix": { + "range": [11428, 11456], + "text": "{} satisfies Record" + }, + "desc": "Use const x = { ... } satisfies Record instead." + } + ] + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'applyGrouping' has too many lines (125). Maximum allowed is 50.", + "line": 453, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 600, + "endColumn": 2 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 462, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 462, + "endColumn": 31 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 465, + "column": 3, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 465, + "endColumn": 61 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 467, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 578, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'excludeInputs' is assigned a value but never used.", + "line": 471, + "column": 7, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 471, + "endColumn": 20 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 482, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 482, + "endColumn": 32 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 484, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 484, + "endColumn": 34 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 505, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 505, + "endColumn": 47 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 505, + "column": 11, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 505, + "endColumn": 36, + "suggestions": [ + { + "messageId": "suggestOptionalChain", + "fix": { + "range": [13564, 13565], + "text": "?" + }, + "desc": "Consider using the optional chain operator `?.` instead. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 527, + "column": 23, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 529, + "endColumn": 14 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 531, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 531, + "endColumn": 40 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 534, + "column": 9, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 534, + "endColumn": 36 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 565, + "column": 21, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 567, + "endColumn": 12 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 569, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 569, + "endColumn": 37 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 572, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 572, + "endColumn": 67 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 573, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 573, + "endColumn": 43 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 577, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 577, + "endColumn": 63 + } + ], + "suppressedMessages": [], + "errorCount": 24, + "fatalErrorCount": 0, + "warningCount": 17, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { minimatch } from 'minimatch';\nimport type { GroupingRule, LogicalGroupingRule } from '../../types.js';\nimport {\n cleanupGroupName,\n deriveGroupTitle,\n extractGroupKeyFromPattern,\n} from './formatting.js';\nimport type { ArtefactType, StatsNodeValues } from './types.js';\n\nexport type PatternMatcher = (path: string) => boolean;\n\n// Pattern cache to avoid recompiling the same patterns\nconst PATTERN_CACHE = new Map();\n\n/**\n * Normalizes patterns from string | PatternList to readonly string[].\n */\nfunction normalizePatterns(\n patterns?: string | readonly string[],\n): readonly string[] {\n if (!patterns) {\n return [];\n }\n\n const normalizedArray = typeof patterns === 'string' ? [patterns] : patterns;\n\n // Filter out any undefined, null, or empty string values\n return normalizedArray.filter(\n (pattern): pattern is string =>\n typeof pattern === 'string' && pattern.trim() !== '',\n );\n}\n\nexport type MatchOptions = {\n matchBase?: boolean;\n normalizeRelativePaths?: boolean;\n};\n\nexport type GroupData = Omit & {\n title: string;\n type: 'group';\n};\n\nexport type GroupManager = {\n groups: Map;\n findOrCreateGroup: (\n key: string,\n rule: LogicalGroupingRule,\n defaultTitle?: string,\n ) => T;\n getAllGroups: () => T[];\n getGroupsWithData: () => T[];\n};\n\nexport type StatsTreeNode = {\n children: StatsTreeNode[];\n name: string;\n values: StatsNodeValues;\n};\n\nexport type StatsTree = {\n root: StatsTreeNode;\n};\n\nconst DEFAULT_GROUP_NAME = 'Group';\n\nexport function splitPathSegments(path: string): string[] {\n return path.split('/').filter(part => part !== '');\n}\n\nexport function normalizePathForMatching(path: string): string {\n return path.replace(/\\.\\.\\//g, '').replace(/^\\/+/, '');\n}\n\n/**\n * Compiles pattern into cached matcher function. Avoids recompilation overhead.\n */\nexport function compilePattern(\n pattern: string,\n options: MatchOptions = {},\n): PatternMatcher {\n // Create cache key from pattern and options\n const cacheKey = `${pattern}|${JSON.stringify(options)}`;\n\n // Return cached pattern if available\n const cached = PATTERN_CACHE.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // Compile new pattern\n const matcher = (path: string) => {\n const minimatchOptions = options.matchBase ? { matchBase: true } : {};\n if (minimatch(path, pattern, minimatchOptions)) {\n return true;\n }\n if (options.normalizeRelativePaths) {\n const normalizedPath = normalizePathForMatching(path);\n return minimatch(normalizedPath, pattern, minimatchOptions);\n }\n return false;\n };\n\n // Cache and return\n PATTERN_CACHE.set(cacheKey, matcher);\n return matcher;\n}\n\n/**\n * Checks if path matches a GroupingRule using include/exclude logic\n */\nfunction matchesGroupingRule(\n path: string,\n rule: GroupingRule,\n options: MatchOptions = {},\n): boolean {\n const includePatterns = normalizePatterns(rule.includeInputs);\n const excludePatterns = normalizePatterns(rule.excludeInputs);\n\n return evaluatePathWithIncludeExclude(\n path,\n includePatterns,\n excludePatterns,\n options,\n );\n}\n\n/**\n * Separates patterns into include and exclude arrays. Exclude patterns start with !\n * @deprecated - Use the new include/exclude GroupingRule format instead\n */\nfunction separateIncludeExcludePatterns(patterns: readonly string[]): {\n includePatterns: string[];\n excludePatterns: string[];\n} {\n const includePatterns: string[] = [];\n const excludePatterns: string[] = [];\n\n for (const pattern of patterns) {\n if (pattern.startsWith('!')) {\n excludePatterns.push(pattern.slice(1)); // Remove ! prefix\n } else {\n includePatterns.push(pattern);\n }\n }\n\n return { includePatterns, excludePatterns };\n}\n\n/**\n * Evaluates path against include/exclude patterns using the same logic as selection system\n */\nfunction evaluatePathWithIncludeExclude(\n path: string,\n includePatterns: readonly string[],\n excludePatterns: readonly string[],\n options: MatchOptions = {},\n): boolean {\n // If exclude patterns exist, check if path matches any - if so, exclude it\n if (excludePatterns.length > 0) {\n for (const pattern of excludePatterns) {\n const matcher = compilePattern(pattern, options);\n if (matcher(path)) {\n return false;\n }\n }\n }\n\n // If no include patterns, include everything (after exclusion check)\n if (includePatterns.length === 0) {\n return true;\n }\n\n // Check if path matches any include pattern\n for (const pattern of includePatterns) {\n const matcher = compilePattern(pattern, options);\n if (matcher(path)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function matchesAnyPattern(\n path: string,\n patterns: readonly string[],\n options: MatchOptions = {},\n): boolean {\n // Legacy support for old patterns array format\n const { includePatterns, excludePatterns } =\n separateIncludeExcludePatterns(patterns);\n return evaluatePathWithIncludeExclude(\n path,\n includePatterns,\n excludePatterns,\n options,\n );\n}\n\n/**\n * Finds first matching rule for path. Processes rules in forward order for top-down precedence.\n */\nexport function findMatchingRule(\n filePath: string,\n rules: GroupingRule[],\n): GroupingRule | null {\n for (const rule of rules) {\n if (\n rule &&\n matchesGroupingRule(filePath, rule, {\n matchBase: true,\n normalizeRelativePaths: true,\n })\n ) {\n return rule;\n }\n }\n return null;\n}\n\nexport function generateGroupKey(\n filePath: string,\n rule: GroupingRule,\n preferRuleTitle = false,\n): string {\n if (preferRuleTitle && rule.title) {\n return rule.title;\n }\n\n // For new include/exclude format, use the include patterns for title generation\n const includePatterns = normalizePatterns(rule.includeInputs);\n return deriveGroupTitle(\n filePath,\n includePatterns,\n rule.title || DEFAULT_GROUP_NAME,\n );\n}\n\nexport function createGroupManager(): GroupManager {\n const groups = new Map();\n return {\n groups,\n findOrCreateGroup(\n key: string,\n rule: LogicalGroupingRule,\n defaultTitle?: string,\n ): T {\n let group = groups.get(key);\n if (!group) {\n const title = rule.title || defaultTitle || key;\n group = {\n title,\n bytes: 0,\n modules: 0,\n type: 'group',\n icon: rule.icon,\n } as T;\n groups.set(key, group);\n }\n return group;\n },\n getAllGroups(): T[] {\n return [...groups.values()];\n },\n getGroupsWithData(): T[] {\n return [...groups.values()].filter(g => g.bytes > 0);\n },\n };\n}\n\nexport function toLogicalGroupingRule(rule: GroupingRule): LogicalGroupingRule {\n const { numSegments: maxDepth, ...rest } = rule;\n return { ...rest, maxDepth: 1 };\n}\n\nexport function findOrCreateGroupFromRule(\n groupManager: GroupManager,\n key: string,\n rule: GroupingRule,\n defaultTitle?: string,\n): T {\n const logicalRule = toLogicalGroupingRule(rule);\n return groupManager.findOrCreateGroup(key, logicalRule, defaultTitle);\n}\n\nexport function processForTable(\n filePath: string,\n rules: GroupingRule[],\n preferRuleTitle = true,\n): { rule: GroupingRule | null; groupKey: string | null } {\n const rule = findMatchingRule(filePath, rules);\n if (!rule) {\n return { rule: null, groupKey: null };\n }\n const groupKey = generateGroupKey(filePath, rule, preferRuleTitle);\n return { rule, groupKey };\n}\n\nexport function extractConcreteSegments(pattern: string): string[] {\n return splitPathSegments(pattern).filter(\n segment => segment !== '**' && segment !== '*' && !segment.includes('*'),\n );\n}\n\nexport function findSegmentIndex(filePath: string, segment: string): number {\n return splitPathSegments(filePath).indexOf(segment);\n}\n\nexport function extractPathSlice(\n filePath: string,\n startIndex: number,\n maxDepth?: number,\n): string {\n const pathParts = splitPathSegments(filePath);\n const endIndex = maxDepth\n ? Math.min(startIndex + maxDepth, pathParts.length)\n : pathParts.length;\n return pathParts.slice(startIndex, endIndex).join('/');\n}\n\nfunction extractIntelligentGroupKey(\n filePath: string,\n patterns: readonly string[],\n maxDepth: number,\n): string {\n const pathParts = splitPathSegments(filePath);\n\n // Try pattern-based extraction first\n for (const pattern of patterns) {\n const patternKey = extractGroupKeyFromPattern(filePath, pattern, maxDepth);\n if (patternKey) {\n return patternKey;\n }\n }\n\n // Fallback to simple depth-based extraction from the beginning of path\n if (pathParts.length >= maxDepth) {\n return pathParts.slice(0, maxDepth).join('/');\n }\n\n // If path is shorter than maxDepth, use the whole path\n return pathParts.join('/');\n}\n\nfunction checkForScopedPackages(paths: string[]): string | null {\n const scopeGroups = new Map();\n let totalScopedPaths = 0;\n for (const path of paths) {\n const scopedMatch = path.match(/.*\\/@([^/]+)\\/[^/]+/);\n if (scopedMatch) {\n const scope = scopedMatch[1];\n if (scope) {\n scopeGroups.set(scope, (scopeGroups.get(scope) || 0) + 1);\n totalScopedPaths++;\n }\n }\n }\n if (totalScopedPaths > paths.length * 0.6) {\n const dominantScope = [...scopeGroups.entries()].sort(\n ([, a], [, b]) => (b as number) - (a as number),\n )[0];\n if (dominantScope && dominantScope[1] > totalScopedPaths * 0.5) {\n return `@${dominantScope[0]}`;\n }\n return 'Scoped Packages';\n }\n return null;\n}\n\nfunction findCommonPath(paths: string[]): string {\n if (paths.length === 0) {\n return DEFAULT_GROUP_NAME;\n }\n if (paths.length === 1) {\n return deriveGroupTitle(paths[0]!, [], DEFAULT_GROUP_NAME);\n }\n\n const scopedPackagePattern = checkForScopedPackages(paths);\n if (scopedPackagePattern) {\n return scopedPackagePattern;\n }\n\n const commonRelativePrefix = paths.every(path => path.startsWith('../'))\n ? '../'\n : '';\n const normalizedPaths = paths.map(path => {\n const normalized = path.startsWith('../')\n ? path.replace(/^(\\.\\.\\/)+/, '')\n : path;\n return splitPathSegments(normalized);\n });\n\n const firstPath = normalizedPaths[0];\n if (!firstPath || firstPath.length === 0) {\n return DEFAULT_GROUP_NAME;\n }\n\n const commonSegments: string[] = [];\n for (const [i, segment] of firstPath.entries()) {\n if (!segment) {\n continue;\n }\n const isCommonToAll = normalizedPaths.every(\n pathSegments => pathSegments && pathSegments[i] === segment,\n );\n if (isCommonToAll) {\n commonSegments.push(segment);\n } else {\n break;\n }\n }\n\n if (commonSegments.length > 0) {\n const commonPath = `${commonRelativePrefix + commonSegments.join('/')}/**`;\n if (commonPath.includes('@*/') || commonPath.includes('*/')) {\n return DEFAULT_GROUP_NAME;\n }\n return commonPath;\n }\n\n const parentDirs = normalizedPaths\n .map(pathSegments => {\n const parentDir =\n pathSegments && pathSegments.length > 0\n ? pathSegments.slice(0, -1).pop()\n : undefined;\n return parentDir || '';\n })\n .filter(dir => dir.length > 0);\n\n const dirCounts = parentDirs.reduce(\n (acc, dir) => {\n if (dir) {\n acc[dir] = (acc[dir] || 0) + 1;\n }\n return acc;\n },\n {} as Record,\n );\n\n const mostCommonDir = Object.entries(dirCounts).sort(\n ([, a], [, b]) => (b as number) - (a as number),\n )[0]?.[0];\n return mostCommonDir\n ? `${commonRelativePrefix + mostCommonDir}/**`\n : DEFAULT_GROUP_NAME;\n}\n\n/**\n * Groups nodes by patterns at current level only. Organizes files into logical groups without recursive processing.\n */\nexport function applyGrouping(\n nodes: StatsTreeNode[],\n groups: GroupingRule[],\n): StatsTreeNode[] {\n if (!groups || groups.length === 0) {\n return [...nodes].sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n // Process nodes without recursive grouping - caller handles recursion\n let finalNodes = [...nodes];\n // Track original input nodes vs newly created group nodes\n const originalNodes = new Set(nodes);\n finalNodes.sort((a, b) => b.values.bytes - a.values.bytes);\n\n for (const group of groups) {\n const {\n title,\n includeInputs,\n excludeInputs,\n icon,\n numSegments: maxDepth,\n } = group;\n const nodesToGroup: StatsTreeNode[] = [];\n const remainingNodes: StatsTreeNode[] = [];\n\n finalNodes.forEach(node => {\n const matchingRule = findMatchingRule(node.name, [group]);\n if (matchingRule && originalNodes.has(node)) {\n // Only group original input nodes, not previously created group nodes\n nodesToGroup.push(node);\n } else {\n remainingNodes.push(node);\n }\n });\n\n if (nodesToGroup.length > 0) {\n const groupedNodes: StatsTreeNode[] = [];\n\n // When reduce is true, always create a single consolidated group\n const shouldCreateSingleGroup = !maxDepth || maxDepth === 0;\n\n if (!shouldCreateSingleGroup && maxDepth && maxDepth > 0) {\n const pathGroups = new Map();\n nodesToGroup.forEach(node => {\n const groupKey = extractIntelligentGroupKey(\n node.name,\n normalizePatterns(includeInputs),\n maxDepth,\n );\n if (!pathGroups.has(groupKey)) {\n pathGroups.set(groupKey, []);\n }\n pathGroups.get(groupKey)!.push(node);\n });\n\n pathGroups.forEach((nodesInGroup, groupPath) => {\n const totalBytes = nodesInGroup.reduce(\n (sum, node) => sum + node.values.bytes,\n 0,\n );\n const totalModules = nodesInGroup.reduce(\n (sum, node) => sum + node.values.modules,\n 0,\n );\n\n const folderNode: StatsTreeNode = {\n name: title || cleanupGroupName(groupPath),\n values: {\n path: groupPath,\n bytes: totalBytes,\n modules: totalModules,\n type: 'group',\n icon,\n },\n children: nodesInGroup.sort(\n (a, b) => b.values.bytes - a.values.bytes,\n ),\n };\n groupedNodes.push(folderNode);\n });\n } else {\n let effectiveTitle: string;\n if (title) {\n effectiveTitle = title;\n } else {\n const samplePath = nodesToGroup[0]?.name || '';\n effectiveTitle = deriveGroupTitle(\n samplePath,\n normalizePatterns(includeInputs),\n DEFAULT_GROUP_NAME,\n );\n }\n\n const totalBytes = nodesToGroup.reduce(\n (sum, node) => sum + node.values.bytes,\n 0,\n );\n const totalModules = nodesToGroup.reduce(\n (sum, node) => sum + node.values.modules,\n 0,\n );\n\n const groupNode: StatsTreeNode = {\n name: effectiveTitle,\n values: {\n path: '',\n bytes: totalBytes,\n modules: totalModules,\n type: 'group',\n icon,\n },\n // When reduce is true, don't show children - collapse to summary only\n children: nodesToGroup.sort(\n (a, b) => b.values.bytes - a.values.bytes,\n ),\n };\n groupedNodes.push(groupNode);\n }\n\n groupedNodes.sort((a, b) => b.values.bytes - a.values.bytes);\n remainingNodes.push(...groupedNodes);\n }\n\n finalNodes = remainingNodes;\n finalNodes.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n // Filter out files that are excluded by any group's exclude patterns\n return finalNodes.filter(node => {\n // Keep group nodes (created by grouping process)\n if (!originalNodes.has(node)) {\n return true;\n }\n\n // For original nodes, check if they're excluded by any group\n return !groups.some(group => {\n if (!group.excludeInputs || group.excludeInputs.length === 0) {\n return false;\n }\n\n const excludePatterns = normalizePatterns(group.excludeInputs);\n return excludePatterns.some(pattern => {\n const matcher = compilePattern(pattern);\n return matcher(node.name);\n });\n });\n });\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.unit.test.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'StatsTreeNode' is defined but never used.", + "line": 4, + "column": 8, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 4, + "endColumn": 21 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'applyGrouping' is defined but never used.", + "line": 5, + "column": 3, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 5, + "endColumn": 16 + } + ], + "suppressedMessages": [], + "errorCount": 2, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it } from 'vitest';\nimport type { GroupingRule } from '../../types.js';\nimport {\n type StatsTreeNode,\n applyGrouping,\n findMatchingRule,\n} from './grouping.js';\n\ndescribe('GroupingRule exclude logic', () => {\n it('should exclude paths that match exclude patterns even when they match include patterns', () => {\n const rule: GroupingRule = {\n includeInputs: '**/node_modules/**',\n excludeInputs: [\n '**/node_modules/react/**',\n '**/node_modules/@angular/**',\n ],\n };\n\n // These paths match include but should be excluded\n expect(findMatchingRule('node_modules/react/index.js', [rule])).toBeNull();\n expect(\n findMatchingRule('node_modules/@angular/core/index.js', [rule]),\n ).toBeNull();\n\n // This path matches include and is not excluded\n expect(findMatchingRule('node_modules/lodash/index.js', [rule])).toEqual(\n rule,\n );\n });\n\n it('should handle multiple exclude patterns', () => {\n const rule: GroupingRule = {\n includeInputs: '**/src/**',\n excludeInputs: ['**/*.test.ts', '**/*.spec.ts', '**/src/legacy/**'],\n };\n\n // These should be excluded\n expect(findMatchingRule('src/app.test.ts', [rule])).toBeNull();\n expect(findMatchingRule('src/utils.spec.ts', [rule])).toBeNull();\n expect(findMatchingRule('src/legacy/old-code.ts', [rule])).toBeNull();\n\n // This should match\n expect(findMatchingRule('src/app.ts', [rule])).toEqual(rule);\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 50_000.", + "line": 18, + "column": 38, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 18, + "endColumn": 44 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 71, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 76, + "endColumn": 4 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'checkBlacklistIssues' has too many lines (91). Maximum allowed is 50.", + "line": 199, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 302, + "endColumn": 2 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 212, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 219, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 229, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 236, + "endColumn": 8 + }, + { + "ruleId": "guard-for-in", + "severity": 2, + "message": "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", + "line": 242, + "column": 5, + "nodeType": "ForInStatement", + "messageId": "wrap", + "endLine": 257, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 242, + "column": 5, + "nodeType": "ForInStatement", + "messageId": "generic", + "endLine": 257, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 248, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 255, + "endColumn": 10 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 262, + "column": 5, + "nodeType": "ForStatement", + "messageId": "generic", + "endLine": 298, + "endColumn": 6 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 262, + "column": 10, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 262, + "endColumn": 19 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 263, + "column": 26, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 263, + "endColumn": 44 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 271, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 278, + "endColumn": 10 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 288, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 295, + "endColumn": 12 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'getIssues' has too many lines (66). Maximum allowed is 50.", + "line": 311, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 393, + "endColumn": 2 + }, + { + "ruleId": "guard-for-in", + "severity": 2, + "message": "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", + "line": 344, + "column": 3, + "nodeType": "ForInStatement", + "messageId": "wrap", + "endLine": 367, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 344, + "column": 3, + "nodeType": "ForInStatement", + "messageId": "generic", + "endLine": 367, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 345, + "column": 20, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 345, + "endColumn": 43 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 348, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 355, + "endColumn": 8 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 370, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 390, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'patternKey' is assigned a value but never used. Allowed unused elements of array destructuring must match /^_/u.", + "line": 371, + "column": 5, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 371, + "endColumn": 15 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 376, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 376, + "endColumn": 80 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 376, + "column": 42, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 376, + "endColumn": 51 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 380, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 388, + "endColumn": 8 + }, + { + "ruleId": "@typescript-eslint/max-params", + "severity": 1, + "message": "Function 'createBlacklistedPatternIssue' has too many parameters (5). Maximum allowed is 4.", + "line": 398, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 398, + "endColumn": 46 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'files' is defined but never used. Allowed unused args must match /^_/u.", + "line": 403, + "column": 3, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 403, + "endColumn": 8 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'collectBlacklistedPatterns' has too many lines (77). Maximum allowed is 50.", + "line": 418, + "column": 1, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 506, + "endColumn": 2 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 433, + "column": 24, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 433, + "endColumn": 60 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 435, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 435, + "endColumn": 38 + }, + { + "ruleId": "max-lines", + "severity": 1, + "message": "File has too many lines (351). Maximum allowed is 300.", + "line": 444, + "column": 1, + "nodeType": null, + "messageId": "exceed", + "endLine": 507, + "endColumn": 1 + }, + { + "ruleId": "guard-for-in", + "severity": 2, + "message": "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", + "line": 469, + "column": 5, + "nodeType": "ForInStatement", + "messageId": "wrap", + "endLine": 477, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 469, + "column": 5, + "nodeType": "ForInStatement", + "messageId": "generic", + "endLine": 477, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 482, + "column": 5, + "nodeType": "ForStatement", + "messageId": "generic", + "endLine": 504, + "endColumn": 6 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 482, + "column": 10, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 482, + "endColumn": 19 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 483, + "column": 26, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 483, + "endColumn": 44 + } + ], + "suppressedMessages": [], + "errorCount": 19, + "fatalErrorCount": 0, + "warningCount": 15, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { minimatch } from 'minimatch';\nimport type { Issue } from '@code-pushup/models';\nimport { formatBytes } from '@code-pushup/utils';\nimport type { BundleStatsConfig } from '../../types.js';\nimport type {\n UnifiedStats,\n UnifiedStatsBundle,\n} from '../../unify/unified-stats.types.js';\nimport type { BlacklistEntry, BlacklistPatternList } from '../scoring.js';\n\n// ===== PERFORMANCE OPTIMIZATIONS =====\n\n// Cache for blacklist pattern matches to avoid repeated minimatch calls\nconst BLACKLIST_PATTERN_CACHE = new Map();\n\n// Clear cache when it gets too large to prevent memory issues\nfunction clearCacheIfNeeded(): void {\n if (BLACKLIST_PATTERN_CACHE.size > 50_000) {\n BLACKLIST_PATTERN_CACHE.clear();\n }\n}\n\n// ===== ISSUE ICONS =====\n\nexport const ISSUE_ICONS = {\n TOO_LARGE: '🔺',\n TOO_SMALL: '🔻',\n BLACKLIST: '🚫',\n} as const;\n\n/**\n * Normalizes blacklist entry to extract pattern string and hint.\n */\nfunction normalizeBlacklistEntry(entry: BlacklistEntry): {\n pattern: string;\n hint?: string;\n} {\n if (typeof entry === 'string') {\n return { pattern: entry };\n }\n return { pattern: entry.pattern, hint: entry.hint };\n}\n\n/**\n * Optimized pattern matching with caching. Avoids repeated minimatch calls for same path-pattern pairs.\n */\nfunction matchesPattern(path: string, pattern: string): boolean {\n const cacheKey = `${path}|${pattern}`;\n\n const cached = BLACKLIST_PATTERN_CACHE.get(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = minimatch(path, pattern, { matchBase: true });\n BLACKLIST_PATTERN_CACHE.set(cacheKey, result);\n\n return result;\n}\n\n/**\n * Checks if a path matches any of the given blacklist patterns. Enables pattern-based filtering with optimized caching.\n */\nfunction matchesBlacklistPattern(\n path: string,\n patterns: BlacklistPatternList,\n): { pattern: string; hint?: string } | null {\n // Clear cache periodically to prevent memory bloat\n clearCacheIfNeeded();\n\n for (const entry of patterns) {\n const { pattern, hint } = normalizeBlacklistEntry(entry);\n if (matchesPattern(path, pattern)) {\n return { pattern, hint };\n }\n }\n return null;\n}\n\n/**\n * Creates error issue for oversized artifact exceeding maximum threshold. Indicates unoptimized bundle or accidental check-in requiring optimization.\n *\n * @param outputPath - Path to the output file that exceeds size limit\n * @param bytes - Actual size of the artifact in bytes\n * @param maxSize - Maximum allowed size threshold in bytes\n * @returns Issue object with error severity and optimization recommendation\n *\n * @example\n * ```js\n * createTooLargeIssue('dist/bundle.js', 1048576, 500000)\n * // Returns: { message: \"🔺 `dist/bundle.js` is **1 MB** _(> 488 kB)_\", severity: 'error', ... }\n * ```\n */\nexport function createTooLargeIssue(\n outputPath: string,\n bytes: number,\n maxSize: number,\n): Issue {\n return {\n message: `${ISSUE_ICONS.TOO_LARGE} \\`${outputPath}\\` is **${formatBytes(bytes)}** _(> ${formatBytes(maxSize)})_`,\n severity: 'error',\n source: { file: outputPath },\n };\n}\n\n/**\n * Creates warning issue for undersized artifact below minimum threshold. Signals missing dependencies or incomplete build requiring verification.\n *\n * @param outputPath - Path to the output file that is below size limit\n * @param bytes - Actual size of the artifact in bytes\n * @param minSize - Minimum expected size threshold in bytes\n * @returns Issue object with warning severity and verification recommendation\n *\n * @example\n * ```js\n * createTooSmallIssue('dist/chunk.js', 512, 2048)\n * // Returns: { message: \"🔻 `dist/chunk.js` is **512 B** _(< 2 kB)_\", severity: 'warning', ... }\n * ```\n */\nexport function createTooSmallIssue(\n outputPath: string,\n bytes: number,\n minSize: number,\n): Issue {\n return {\n message: `${ISSUE_ICONS.TOO_SMALL} \\`${outputPath}\\` is **${formatBytes(bytes)}** _(< ${formatBytes(minSize)})_`,\n severity: 'warning',\n source: { file: outputPath },\n };\n}\n\n/**\n * Creates error issue for blacklisted import pattern match. Enforces dependency restrictions for security and architectural compliance.\n */\nexport function createBlacklistedIssue(\n importPath: string,\n outputPath: string,\n pattern: string,\n hint?: string,\n): Issue {\n const baseMessage = `${ISSUE_ICONS.BLACKLIST} \\`${importPath}\\` matches blacklist pattern \\`${pattern}\\``;\n const message = hint ? `${baseMessage} - ${hint}` : baseMessage;\n\n return {\n message,\n severity: 'error',\n source: { file: outputPath },\n };\n}\n\n/**\n * Validates artifact size against configured thresholds and returns appropriate issues. Ensures bundles stay within acceptable size ranges.\n *\n * @param outputPath - Path to the output file being checked\n * @param output - Output metadata containing size information\n * @param minSize - Minimum expected size threshold in bytes (optional)\n * @param maxSize - Maximum allowed size threshold in bytes (optional)\n * @returns Array of size-related issues found\n */\nexport function checkSizeIssues(\n outputPath: string,\n output: UnifiedStatsBundle,\n minSize?: number,\n maxSize?: number,\n): Issue[] {\n const outputBytes = output.bytes;\n\n if (maxSize !== undefined && outputBytes > maxSize) {\n return [createTooLargeIssue(outputPath, outputBytes, maxSize)];\n } else if (minSize !== undefined && outputBytes < minSize) {\n return [createTooSmallIssue(outputPath, outputBytes, minSize)];\n }\n\n return [];\n}\n\n/**\n * Scans artifact inputs and imports for blacklisted patterns and returns violation issues.\n * Enforces dependency restrictions across bundle contents.\n *\n * Searches for blacklisted paths in these locations:\n * 1. Primary File Path Locations:\n * - Object keys in the inputs section\n * - \"path\" properties in imports\n * - \"original\" properties in imports (exact import statements as written in source code)\n * 2. Entry Point Locations:\n * - \"entryPoint\" properties in chunk/output definitions\n * 3. Output File Locations:\n * - Output file paths (as object keys)\n * 4. Special Path Patterns:\n * - Disabled paths with \"(disabled):\" prefix\n * - Runtime paths with \"\" pattern\n *\n * @param outputPath - Path to the output file being scanned\n * @param output - Output metadata containing inputs and imports\n * @param blacklistPatterns - Array of blacklist patterns (strings or objects with hints)\n * @returns Array of blacklist-related issues found\n */\nexport function checkBlacklistIssues(\n outputPath: string,\n output: UnifiedStatsBundle,\n blacklistPatterns: BlacklistPatternList,\n): Issue[] {\n const issues: Issue[] = [];\n\n // 1. Check output path itself (object key in outputs section)\n const outputPathMatch = matchesBlacklistPattern(\n outputPath,\n blacklistPatterns,\n );\n if (outputPathMatch) {\n issues.push(\n createBlacklistedIssue(\n outputPath,\n outputPath,\n outputPathMatch.pattern,\n outputPathMatch.hint,\n ),\n );\n }\n\n // 2. Check entryPoint property\n if (output.entryPoint) {\n const entryPointMatch = matchesBlacklistPattern(\n output.entryPoint,\n blacklistPatterns,\n );\n if (entryPointMatch) {\n issues.push(\n createBlacklistedIssue(\n output.entryPoint,\n outputPath,\n entryPointMatch.pattern,\n entryPointMatch.hint,\n ),\n );\n }\n }\n\n // 3. Check input paths (object keys in inputs section)\n if (output.inputs) {\n for (const inputPath in output.inputs) {\n const matchedPattern = matchesBlacklistPattern(\n inputPath,\n blacklistPatterns,\n );\n if (matchedPattern) {\n issues.push(\n createBlacklistedIssue(\n inputPath,\n outputPath,\n matchedPattern.pattern,\n matchedPattern.hint,\n ),\n );\n }\n }\n }\n\n // 4. Check import paths and original import statements\n if (output.imports) {\n for (let i = 0; i < output.imports.length; i++) {\n const importInfo = output.imports[i]!;\n\n // Check resolved import path\n const importPathMatch = matchesBlacklistPattern(\n importInfo.path,\n blacklistPatterns,\n );\n if (importPathMatch) {\n issues.push(\n createBlacklistedIssue(\n importInfo.path,\n outputPath,\n importPathMatch.pattern,\n importPathMatch.hint,\n ),\n );\n }\n\n // Check original import statement (exact import as written in source code)\n if (importInfo.original) {\n const originalMatch = matchesBlacklistPattern(\n importInfo.original,\n blacklistPatterns,\n );\n if (originalMatch) {\n issues.push(\n createBlacklistedIssue(\n importInfo.original,\n outputPath,\n originalMatch.pattern,\n originalMatch.hint,\n ),\n );\n }\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Generates comprehensive diagnostic issues for bundle artifacts including size violations and blacklisted imports. Provides actionable feedback for bundle optimization and dependency management.\n *\n * @param statsSlice - Unified bundle statistics containing output files and metadata\n * @param config - Bundle configuration with penalty options and diagnostic thresholds\n * @returns Array of diagnostic issues with severity levels and recommended actions\n */\nexport function getIssues(\n statsSlice: UnifiedStats,\n config: BundleStatsConfig,\n): Issue[] {\n // Clear cache at start of each audit run for clean state\n BLACKLIST_PATTERN_CACHE.clear();\n\n const issues: Issue[] = [];\n const { penalty = false } = config.scoring || { penalty: false };\n\n if (!penalty) {\n return issues;\n }\n\n const blacklistPatterns = penalty?.blacklist;\n const artefactSizeThresholds = penalty?.artefactSize;\n\n if (!blacklistPatterns?.length && !artefactSizeThresholds) {\n return issues;\n }\n\n const minArtifactSize = artefactSizeThresholds?.[0];\n const maxArtifactSize = artefactSizeThresholds?.[1];\n const hasBlacklist = blacklistPatterns && blacklistPatterns.length > 0;\n const hasSizeThresholds =\n minArtifactSize !== undefined || maxArtifactSize !== undefined;\n\n // Track unique blacklisted patterns per bundle to avoid duplicates\n const blacklistedPatterns = new Map<\n string,\n { pattern: string; hint?: string; files: string[]; outputPath: string }\n >();\n\n for (const outputPath in statsSlice) {\n const output = statsSlice[outputPath]!;\n\n if (hasSizeThresholds) {\n issues.push(\n ...checkSizeIssues(\n outputPath,\n output,\n minArtifactSize,\n maxArtifactSize,\n ),\n );\n }\n\n if (hasBlacklist) {\n // Collect blacklisted patterns without creating issues yet\n collectBlacklistedPatterns(\n outputPath,\n output,\n blacklistPatterns,\n blacklistedPatterns,\n );\n }\n }\n\n // Create unique issues for blacklisted patterns\n for (const [\n patternKey,\n { pattern, hint, files, outputPath },\n ] of blacklistedPatterns) {\n if (files.length === 1) {\n // Single file - show specific file name\n issues.push(createBlacklistedIssue(files[0]!, outputPath, pattern, hint));\n } else {\n // Multiple files - show pattern summary\n const summaryMessage = `Blacklisted modules matching \\`${pattern}\\` included in file`;\n issues.push(\n createBlacklistedPatternIssue(\n summaryMessage,\n outputPath,\n pattern,\n hint,\n files,\n ),\n );\n }\n }\n\n return issues;\n}\n\n/**\n * Creates error issue for multiple blacklisted files from same pattern. Consolidates multiple violations into single issue.\n */\nexport function createBlacklistedPatternIssue(\n summaryMessage: string,\n outputPath: string,\n pattern: string,\n hint?: string,\n files?: string[],\n): Issue {\n const baseMessage = `${ISSUE_ICONS.BLACKLIST} ${summaryMessage}`;\n const message = hint ? `${baseMessage} - ${hint}` : baseMessage;\n\n return {\n message,\n severity: 'error',\n source: { file: outputPath },\n };\n}\n\n/**\n * Collects blacklisted patterns without creating duplicate issues. Groups by pattern per bundle.\n */\nfunction collectBlacklistedPatterns(\n outputPath: string,\n output: UnifiedStatsBundle,\n blacklistPatterns: BlacklistPatternList,\n blacklistedPatterns: Map<\n string,\n { pattern: string; hint?: string; files: string[]; outputPath: string }\n >,\n): void {\n const addToPattern = (\n filePath: string,\n matchResult: { pattern: string; hint?: string },\n ) => {\n const patternKey = `${outputPath}:${matchResult.pattern}`;\n if (blacklistedPatterns.has(patternKey)) {\n const existing = blacklistedPatterns.get(patternKey)!;\n if (!existing.files.includes(filePath)) {\n existing.files.push(filePath);\n }\n } else {\n blacklistedPatterns.set(patternKey, {\n pattern: matchResult.pattern,\n hint: matchResult.hint,\n files: [filePath],\n outputPath,\n });\n }\n };\n\n // 1. Check output path itself (object key in outputs section)\n const outputPathMatch = matchesBlacklistPattern(\n outputPath,\n blacklistPatterns,\n );\n if (outputPathMatch) {\n addToPattern(outputPath, outputPathMatch);\n }\n\n // 2. Check entryPoint property\n if (output.entryPoint) {\n const entryPointMatch = matchesBlacklistPattern(\n output.entryPoint,\n blacklistPatterns,\n );\n if (entryPointMatch) {\n addToPattern(output.entryPoint, entryPointMatch);\n }\n }\n\n // 3. Check input paths (object keys in inputs section)\n if (output.inputs) {\n for (const inputPath in output.inputs) {\n const matchedPattern = matchesBlacklistPattern(\n inputPath,\n blacklistPatterns,\n );\n if (matchedPattern) {\n addToPattern(inputPath, matchedPattern);\n }\n }\n }\n\n // 4. Check import paths and original import statements\n if (output.imports) {\n for (let i = 0; i < output.imports.length; i++) {\n const importInfo = output.imports[i]!;\n\n // Check resolved import path\n const importPathMatch = matchesBlacklistPattern(\n importInfo.path,\n blacklistPatterns,\n );\n if (importPathMatch) {\n addToPattern(importInfo.path, importPathMatch);\n }\n\n // Check original import statement (exact import as written in source code)\n if (importInfo.original) {\n const originalMatch = matchesBlacklistPattern(\n importInfo.original,\n blacklistPatterns,\n );\n if (originalMatch) {\n addToPattern(importInfo.original, originalMatch);\n }\n }\n }\n }\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.unit.test.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'afterEach' is defined but never used.", + "line": 1, + "column": 10, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 1, + "endColumn": 19 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'beforeEach' is defined but never used.", + "line": 1, + "column": 21, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 1, + "endColumn": 31 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'vi' is defined but never used.", + "line": 1, + "column": 55, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 1, + "endColumn": 57 + } + ], + "suppressedMessages": [], + "errorCount": 3, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\nimport {\n checkBlacklistIssues,\n checkSizeIssues,\n createBlacklistedIssue,\n createTooLargeIssue,\n createTooSmallIssue,\n getIssues,\n} from './issues.js';\n\ndescribe('createTooLargeIssue', () => {\n it('should create error issue for oversized artifact', () => {\n expect(createTooLargeIssue('bundle.js', 1_048_576, 500_000)).toStrictEqual({\n severity: 'error',\n message: '🔺 `bundle.js` is **1 MB** _(> 488.28 kB)_',\n source: { file: 'bundle.js' },\n });\n });\n});\n\ndescribe('createTooSmallIssue', () => {\n it('should create warning issue for undersized artifact', () => {\n expect(createTooSmallIssue('chunk.js', 512, 2048)).toStrictEqual({\n severity: 'warning',\n message: '🔻 `chunk.js` is **512 B** _(< 2 kB)_',\n source: { file: 'chunk.js' },\n });\n });\n});\n\ndescribe('createBlacklistedIssue', () => {\n it('should create error issue for blacklisted import', () => {\n expect(\n createBlacklistedIssue('src/math.ts', 'dist/bundle.js', '**/*math*'),\n ).toStrictEqual({\n severity: 'error',\n message: '🚫 `src/math.ts` matches blacklist pattern `**/*math*`',\n source: { file: 'dist/bundle.js' },\n });\n });\n});\n\ndescribe('checkSizeIssues', () => {\n it('should return too large issue when file exceeds maxSize', () => {\n expect(\n checkSizeIssues(\n 'big.js',\n { path: 'big.js', bytes: 1000 },\n undefined,\n 500,\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should return too small issue when file is below minSize', () => {\n expect(\n checkSizeIssues(\n 'small.js',\n { path: 'small.js', bytes: 100 },\n 500,\n undefined,\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'warning' })]);\n });\n\n it('should return empty array when file is within size range', () => {\n expect(\n checkSizeIssues('ok.js', { path: 'ok.js', bytes: 750 }, 500, 1000),\n ).toStrictEqual([]);\n });\n});\n\ndescribe('checkBlacklistIssues', () => {\n it('should check output path itself for blacklist patterns', () => {\n expect(\n checkBlacklistIssues('a.js', { path: 'a.js', bytes: 1 }, ['a*']),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check output path itself for blacklist patterns with hint', () => {\n const issues = checkBlacklistIssues('a.js', { path: 'a.js', bytes: 1 }, [\n { pattern: 'a*', hint: 'Test hint message' },\n ]);\n expect(issues).toStrictEqual([\n expect.objectContaining({\n severity: 'error',\n message: expect.stringContaining('Test hint message'),\n }),\n ]);\n });\n\n it('should check entryPoint property for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n { path: 'out.js', bytes: 1, entryPoint: 'b.js' },\n ['b*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check input paths for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n { path: 'out.js', bytes: 1, inputs: { 'c.js': { bytes: 1 } } },\n ['c*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check import resolved paths for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n imports: [{ path: 'd.js', kind: 'static' }],\n },\n ['d*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check import original statements for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n imports: [{ path: 'x.js', kind: 'static', original: './e' }],\n },\n ['./e*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should return multiple issues when multiple paths match blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'f.js',\n {\n path: 'f.js',\n bytes: 1,\n inputs: { 'g.js': { bytes: 1 } },\n imports: [{ path: 'h.js', kind: 'static' }],\n },\n ['*'],\n ),\n ).toStrictEqual([\n expect.objectContaining({ severity: 'error' }),\n expect.objectContaining({ severity: 'error' }),\n expect.objectContaining({ severity: 'error' }),\n ]);\n });\n\n it('should match disabled paths with (disabled): prefix', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n inputs: { '(disabled):i.js': { bytes: 1 } },\n },\n ['*disabled*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should match runtime paths with pattern', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n imports: [{ path: '', kind: 'static' }],\n },\n [''],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n});\n\ndescribe('getIssues', () => {\n it('should return empty array when no configuration is provided', () => {\n expect(getIssues({}, {} as any)).toStrictEqual([]);\n });\n\n it('should process multiple outputs and return issues', () => {\n expect(\n getIssues(\n {\n 'a.js': { path: 'a.js', bytes: 1 },\n 'b.js': { path: 'b.js', bytes: 2 },\n },\n {\n title: 'Test',\n slug: 'test',\n selection: { includeOutputs: ['**/*.js'] },\n scoring: {\n totalSize: [0, 1000],\n penalty: { blacklist: ['a*'] },\n },\n } as any,\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts", + "messages": [ + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'aggregateAndSortGroups' has too many lines (117). Maximum allowed is 50.", + "line": 40, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 190, + "endColumn": 2 + }, + { + "ruleId": "complexity", + "severity": 1, + "message": "Function 'aggregateAndSortGroups' has a complexity of 26. Maximum allowed is 20.", + "line": 40, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "complex", + "endLine": 190, + "endColumn": 2 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 63, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 72, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 74, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 74, + "endColumn": 26 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 84, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 98, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 88, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 96, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 90, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 94, + "endColumn": 13 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 104, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 142, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 111, + "column": 5, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 111, + "endColumn": 58 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 120, + "column": 7, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 120, + "endColumn": 50 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 131, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 131, + "endColumn": 32 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 132, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 132, + "endColumn": 25 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 145, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 175, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 154, + "column": 5, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 154, + "endColumn": 58 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 162, + "column": 7, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 162, + "endColumn": 50 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 172, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 172, + "endColumn": 36 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 186, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 186, + "endColumn": 45 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'createTable' has too many lines (64). Maximum allowed is 50.", + "line": 195, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 275, + "endColumn": 2 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 203, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 203, + "endColumn": 32 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 204, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 204, + "endColumn": 38 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 214, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 220, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 216, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 216, + "endColumn": 31 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 218, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 218, + "endColumn": 33 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 223, + "column": 5, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 223, + "endColumn": 34 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 227, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 227, + "endColumn": 41 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 245, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 256, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 251, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 255, + "endColumn": 7 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 260, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 264, + "endColumn": 7 + } + ], + "suppressedMessages": [], + "errorCount": 10, + "fatalErrorCount": 0, + "warningCount": 18, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { Table } from '@code-pushup/models';\nimport { formatBytes } from '@code-pushup/utils';\nimport type { GroupingRule } from '../../types.js';\nimport type { UnifiedStats } from '../../unify/unified-stats.types.js';\nimport {\n type GroupData,\n createGroupManager,\n findOrCreateGroupFromRule,\n processForTable,\n} from './grouping.js';\n\nconst DEFAULT_GROUP_NAME = 'Group';\nconst REST_GROUP_NAME = 'Rest';\n\n// Performance optimizations: Simple pattern cache only\nconst PATTERN_MATCH_CACHE = new Map<\n string,\n { rule: GroupingRule | null; groupKey: string | null }\n>();\n\nexport type SharedViewConfig = {\n enabled?: boolean;\n mode?: 'onlyMatching' | 'all';\n};\n\nexport type TablePruningConfig = {\n enabled?: boolean;\n maxChildren?: number;\n minSize?: number;\n};\n\nexport type InsightsTableConfig = SharedViewConfig & {\n groups: GroupingRule[];\n pruning?: TablePruningConfig;\n};\n\n/**\n * Simplified aggregation with algorithmic optimizations. Eliminates expensive nested operations and redundant pattern matching.\n */\nexport function aggregateAndSortGroups(\n statsSlice: UnifiedStats,\n insights: InsightsTableConfig,\n): { groups: GroupData[]; restGroup: { title: string; bytes: number } } {\n const groupingRules = insights.groups || [];\n\n // Early exit optimization\n if (groupingRules.length === 0) {\n const totalBytes = Object.values(statsSlice).reduce(\n (acc, { bytes }) => acc + bytes,\n 0,\n );\n return {\n groups: [],\n restGroup: { bytes: totalBytes, title: REST_GROUP_NAME },\n };\n }\n\n const groupManager = createGroupManager();\n PATTERN_MATCH_CACHE.clear();\n\n // Pre-create all possible groups to avoid repeated lookups\n const preCreatedGroups = new Map();\n for (const rule of groupingRules) {\n const effectiveTitle = rule.title || DEFAULT_GROUP_NAME;\n const group = findOrCreateGroupFromRule(\n groupManager,\n effectiveTitle,\n rule,\n effectiveTitle,\n );\n preCreatedGroups.set(effectiveTitle, group);\n }\n\n let totalRestBytes = 0;\n const outputEntries = Object.entries(statsSlice);\n\n // Single-pass processing: collect all inputs first, then process in batch\n const inputsToProcess: {\n inputPath: string;\n inputBytes: number;\n outputKey: string;\n }[] = [];\n\n for (const [outputKey, output] of outputEntries) {\n totalRestBytes += output.bytes;\n\n if (output.inputs) {\n for (const [inputPath, input] of Object.entries(output.inputs)) {\n if (input.bytes > 0) {\n inputsToProcess.push({\n inputPath,\n inputBytes: input.bytes,\n outputKey,\n });\n }\n }\n }\n }\n\n // Process all inputs in single optimized loop with early termination\n const outputBytesConsumed = new Map();\n const processedInputs = new Set(); // Track inputs that have been fully consumed\n\n for (const { inputPath, inputBytes, outputKey } of inputsToProcess) {\n // Skip inputs that have already been fully processed by a previous rule\n if (processedInputs.has(inputPath)) {\n continue;\n }\n\n // Use cached pattern matching\n let matchResult = PATTERN_MATCH_CACHE.get(inputPath);\n if (!matchResult) {\n matchResult = processForTable(inputPath, groupingRules, true);\n PATTERN_MATCH_CACHE.set(inputPath, matchResult);\n }\n\n const { rule, groupKey } = matchResult;\n if (rule && groupKey) {\n // Use pre-created group or create new\n let group = preCreatedGroups.get(groupKey);\n if (!group) {\n group = findOrCreateGroupFromRule(\n groupManager,\n groupKey,\n rule,\n rule.title || groupKey,\n );\n preCreatedGroups.set(groupKey, group);\n }\n\n group.bytes += inputBytes;\n group.modules += 1;\n\n // Track consumed bytes per output\n const consumed = outputBytesConsumed.get(outputKey) || 0;\n outputBytesConsumed.set(outputKey, consumed + inputBytes);\n totalRestBytes -= inputBytes;\n\n // Mark input as fully processed - no need to check it against other patterns\n processedInputs.add(inputPath);\n }\n }\n\n // Process remaining output bytes efficiently, skipping outputs with no remaining bytes\n for (const [outputKey, output] of outputEntries) {\n const consumedBytes = outputBytesConsumed.get(outputKey) || 0;\n const remainingBytes = output.bytes - consumedBytes;\n\n // Skip outputs that have been fully consumed by input processing\n if (remainingBytes <= 0) {\n continue;\n }\n\n let matchResult = PATTERN_MATCH_CACHE.get(outputKey);\n if (!matchResult) {\n matchResult = processForTable(outputKey, groupingRules, true);\n PATTERN_MATCH_CACHE.set(outputKey, matchResult);\n }\n\n const { rule, groupKey } = matchResult;\n if (rule && groupKey) {\n let group = preCreatedGroups.get(groupKey);\n if (!group) {\n group = findOrCreateGroupFromRule(\n groupManager,\n groupKey,\n rule,\n rule.title || groupKey,\n );\n preCreatedGroups.set(groupKey, group);\n }\n group.bytes += remainingBytes;\n totalRestBytes -= remainingBytes;\n }\n }\n\n const restGroup = {\n bytes: Math.max(0, totalRestBytes),\n title: REST_GROUP_NAME,\n };\n\n const groups = groupManager.getGroupsWithData();\n\n // Optimized sorting - only sort if we have multiple groups\n if (groups.length > 1) {\n groups.sort((a, b) => b.bytes - a.bytes);\n }\n\n return { groups, restGroup };\n}\n\n/**\n * Transforms aggregated group data into table format. Creates table rows from group statistics.\n */\nexport function createTable(\n groups: GroupData[],\n restGroup: { title: string; bytes: number },\n viewMode: 'onlyMatching' | 'all' = 'onlyMatching',\n pruning?: TablePruningConfig,\n): Table {\n const rows: { group: string; modules: string; size: string }[] = [];\n\n let processedGroups = groups;\n let processedRestGroup = restGroup;\n\n // Apply pruning if enabled\n if (pruning?.enabled) {\n const { minSize = 0, maxChildren } = pruning;\n\n // Filter groups by minimum size\n const keptGroups: GroupData[] = [];\n const prunedGroups: GroupData[] = [];\n\n for (const group of groups) {\n if (group.bytes >= minSize) {\n keptGroups.push(group);\n } else {\n prunedGroups.push(group);\n }\n }\n\n // Apply maxChildren limit\n let finalGroups = keptGroups;\n if (maxChildren && keptGroups.length > maxChildren) {\n finalGroups = keptGroups.slice(0, maxChildren);\n const excessGroups = keptGroups.slice(maxChildren);\n prunedGroups.push(...excessGroups);\n }\n\n // Add pruned groups to rest\n if (prunedGroups.length > 0) {\n const prunedBytes = prunedGroups.reduce(\n (sum, group) => sum + group.bytes,\n 0,\n );\n processedRestGroup = {\n title: REST_GROUP_NAME,\n bytes: restGroup.bytes + prunedBytes,\n };\n }\n\n processedGroups = finalGroups;\n }\n\n for (const group of processedGroups) {\n // Apply viewMode filtering\n if (viewMode === 'onlyMatching' && group.bytes === 0) {\n continue;\n }\n\n rows.push({\n group: group.icon ? `${group.icon} ${group.title}` : group.title,\n modules: group.modules.toString(),\n size: formatBytes(group.bytes),\n });\n }\n\n // Apply viewMode filtering to rest group\n if (processedRestGroup.bytes > 0 || viewMode === 'all') {\n rows.push({\n group: 'Rest',\n modules: '-',\n size: formatBytes(processedRestGroup.bytes),\n });\n }\n\n return {\n columns: [\n { key: 'group', label: 'Group', align: 'left' },\n { key: 'modules', label: 'Modules', align: 'right' },\n { key: 'size', label: 'Size', align: 'right' },\n ],\n rows,\n };\n}\n\n/**\n * Creates insights table from stats and grouping rules. Combines aggregation and table formatting.\n */\nexport function createInsightsTable(\n statsSlice: UnifiedStats,\n insights: InsightsTableConfig,\n): Table {\n const { groups, restGroup } = aggregateAndSortGroups(statsSlice, insights);\n return createTable(\n groups,\n restGroup,\n insights.mode || 'onlyMatching',\n insights.pruning,\n );\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.unit.test.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.ts", + "messages": [ + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 69, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 107, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 71, + "column": 5, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 71, + "endColumn": 42 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 76, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 89, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 78, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 87, + "endColumn": 13 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 92, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 92, + "endColumn": 68 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 97, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 106, + "endColumn": 7 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 110, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 110, + "endColumn": 59 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 123, + "column": 21, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 123, + "endColumn": 38 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 172, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 172, + "endColumn": 52 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 179, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 179, + "endColumn": 67 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'createTree' has too many lines (55). Maximum allowed is 50.", + "line": 207, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 283, + "endColumn": 2 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'selection' is assigned a value but never used.", + "line": 214, + "column": 41, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 214, + "endColumn": 50 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 25_000.", + "line": 217, + "column": 34, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 217, + "endColumn": 40 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 221, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 221, + "endColumn": 46 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 227, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 231, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 229, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 229, + "endColumn": 68 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 243, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 243, + "endColumn": 36 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 253, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 253, + "endColumn": 22 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 254, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 254, + "endColumn": 24 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 255, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 258, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 999.", + "line": 291, + "column": 35, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 291, + "endColumn": 38 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 999.", + "line": 292, + "column": 41, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 292, + "endColumn": 44 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 999.", + "line": 294, + "column": 39, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 294, + "endColumn": 42 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'pruneTreeRecursive' has too many lines (66). Maximum allowed is 50.", + "line": 302, + "column": 1, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 387, + "endColumn": 2 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 315, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 315, + "endColumn": 66 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 322, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 342, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 334, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 337, + "endColumn": 9 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 340, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 340, + "endColumn": 34 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 345, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 345, + "endColumn": 36 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 351, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 351, + "endColumn": 38 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 359, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 359, + "endColumn": 46 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 359, + "column": 26, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 359, + "endColumn": 45 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 382, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 382, + "endColumn": 35 + } + ], + "suppressedMessages": [], + "errorCount": 16, + "fatalErrorCount": 0, + "warningCount": 17, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { BasicTree, BasicTreeNode } from '@code-pushup/models';\nimport { formatBytes, pluralizeToken, truncateText } from '@code-pushup/utils';\nimport type { GroupingRule } from '../../types.js';\nimport type { UnifiedStats } from '../../unify/unified-stats.types';\nimport type { SelectionConfig } from '../selection.js';\nimport {\n type StatsTreeNode,\n applyGrouping as applyGroupingAndSort,\n} from './grouping.js';\nimport type { SharedViewConfig } from './table.js';\nimport type { StatsNodeValues } from './types.js';\n\n/**\n * Helper type that transforms picked properties by adding \"Display\" suffix and making them strings.\n */\nexport type AddDisplaySuffix = {\n [K in keyof T as `${string & K}Display`]: string;\n};\n\n/**\n * Display values for StatsTreeNode with formatted strings.\n */\nexport type StatsTreeNodeDisplayValues = AddDisplaySuffix<\n Pick\n>;\n\nexport type FormattedStatsTreeNode = {\n name: string;\n values?: Record;\n children: FormattedStatsTreeNode[];\n};\n\n/**\n * Display tree structure for bundle statistics output.\n */\nexport type FormattedStatsTree = {\n root: FormattedStatsTreeNode;\n};\n\nexport const DEFAULT_PATH_LENGTH = 40;\n\n// Simple performance optimization: single cache for formatted strings\nconst STRING_FORMAT_CACHE = new Map();\n\nexport type DependencyTreeConfig = {\n groups?: GroupingRule[] | false;\n pruning?: PruningConfig;\n} & SharedViewConfig;\n\nexport type PruningConfig = {\n enabled?: boolean;\n maxChildren?: number;\n maxDepth?: number;\n minSize?: number;\n pathLength?: number | false;\n};\n\nexport type PruneTreeNode = {\n children: StatsTreeNode[];\n};\n\n/**\n * Converts statistics to tree structure. Streamlined for speed.\n */\nexport function convertStatsToTree(stats: UnifiedStats): StatsTreeNode[] {\n const artifacts = Object.values(stats);\n const result: StatsTreeNode[] = [];\n\n for (const artefact of artifacts) {\n const isEntry = Boolean(artefact.entryPoint);\n let inputNodes: StatsTreeNode[] = [];\n\n if (artefact.inputs) {\n const validInputs: StatsTreeNode[] = [];\n\n for (const [path, input] of Object.entries(artefact.inputs)) {\n if (input.bytes > 0) {\n validInputs.push({\n name: path,\n values: {\n path,\n bytes: input.bytes,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n });\n }\n }\n\n if (validInputs.length > 1) {\n validInputs.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n inputNodes = validInputs;\n }\n\n result.push({\n name: artefact.path,\n values: {\n path: artefact.path,\n bytes: artefact.bytes,\n modules: inputNodes.length,\n type: isEntry ? 'entry-file' : 'static-import',\n },\n children: inputNodes,\n });\n }\n\n if (result.length > 1) {\n result.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n return result;\n}\n\n/**\n * Flattens single-child groups to reduce hierarchy and applies group icons to actual files.\n */\nfunction flattenSingleChildGroups(nodes: StatsTreeNode[]): StatsTreeNode[] {\n return nodes.map(node => {\n // If this is a group with exactly one child, flatten it\n if (node.values.type === 'group' && node.children.length === 1) {\n const child = node.children[0]!;\n\n // Use the group's icon for the child file if the group has an icon\n return {\n ...child,\n values: {\n ...child.values,\n icon: node.values.icon, // Use group icon only if it exists\n },\n children: flattenSingleChildGroups(child.children), // Recursively flatten children\n };\n }\n\n // For other nodes, just recursively process children\n return {\n ...node,\n children: flattenSingleChildGroups(node.children),\n };\n });\n}\n\n/**\n * Formats tree nodes with clean names and separate values for proper alignment.\n */\nexport function formatStatsTreeForDisplay(\n node: StatsTreeNode,\n pathLength: number | false = DEFAULT_PATH_LENGTH,\n): FormattedStatsTreeNode {\n const maxChars = pathLength === false ? DEFAULT_PATH_LENGTH : pathLength;\n\n // Clean name truncation (no icons or size info)\n const cleanName =\n maxChars < node.name.length\n ? truncateText(node.name, { maxChars, position: 'middle' })\n : node.name;\n\n // Use only explicitly configured icons\n const icon = node.values.icon;\n\n // Recurse through children (keep it simple - recursion is fast in JS)\n const children = node.children.map(child =>\n formatStatsTreeForDisplay(child, pathLength),\n );\n\n const values: Record = {};\n\n // Show size for all nodes except intermediate nodes in single-child chains\n // This means: entry files, groups with multiple children, and leaf files all show size\n if (node.children.length !== 1) {\n values['size'] = formatBytes(node.values.bytes);\n }\n\n // Only show source count if more than 1 source\n if (node.values.modules > 1) {\n // For \"...\" groups that represent multiple files, show \"files\" instead of \"sources\"\n const token = node.name === '...' ? 'file' : 'module';\n values['modules'] = pluralizeToken(token, node.values.modules);\n }\n\n return {\n name: icon ? `${icon} ${cleanName}` : cleanName,\n values,\n children,\n };\n}\n\n/**\n * Converts FormattedStatsTreeNode to BasicTreeNode for proper ASCII display.\n */\nfunction formattedStatsTreeNodeToBasicTreeNode(\n node: FormattedStatsTreeNode,\n): BasicTreeNode {\n return {\n name: node.name,\n ...(node.values && { values: node.values }),\n ...(node.children.length > 0 && {\n children: node.children.map(formattedStatsTreeNodeToBasicTreeNode),\n }),\n };\n}\n\n/**\n * Creates artifact tree with focused optimizations.\n */\nexport function createTree(\n statsSlice: UnifiedStats,\n options: {\n title: string;\n selection?: SelectionConfig;\n } & DependencyTreeConfig,\n): BasicTree {\n const { title, groups, pruning, mode, selection } = options;\n\n // Simple cache management\n if (STRING_FORMAT_CACHE.size > 25_000) {\n STRING_FORMAT_CACHE.clear();\n }\n\n let nodes = convertStatsToTree(statsSlice);\n\n // Apply grouping if needed\n if (Array.isArray(groups) && groups.length > 0 && nodes.length > 0) {\n // Apply grouping only to inputs (children) within each output file\n // Don't group the output files themselves\n for (const node of nodes) {\n if (node.children.length > 0) {\n node.children = applyGroupingAndSort(node.children, groups);\n }\n }\n\n // Flatten single-child groups after applying grouping\n nodes = flattenSingleChildGroups(nodes);\n }\n\n // Apply onlyMatching mode filtering - hide files with no matching inputs\n if (mode === 'onlyMatching') {\n nodes = nodes.filter(node => node.children.length > 0);\n }\n\n // Apply pruning only if explicitly configured and enabled\n let prunedNodes: StatsTreeNode[];\n if (pruning && pruning.enabled !== false) {\n const prunedRoot = pruneTree({ children: nodes }, pruning);\n prunedNodes = prunedRoot.children;\n } else {\n // No pruning - show all nodes\n prunedNodes = nodes;\n }\n\n // Calculate totals\n let totalBytes = 0;\n let totalModules = 0;\n for (const node of prunedNodes) {\n totalBytes += node.values.bytes;\n totalModules += node.values.modules;\n }\n\n // Format nodes\n const formattedChildren = prunedNodes.map(node =>\n formatStatsTreeForDisplay(node, pruning?.pathLength),\n );\n\n const formattedRoot: FormattedStatsTreeNode = {\n name: title,\n values: {\n 'total size': formatBytes(totalBytes),\n ...(totalModules > 1 && { 'total modules': totalModules }),\n files: prunedNodes.length,\n },\n children: formattedChildren,\n };\n\n // Convert to BasicTree for proper ASCII display\n const root = formattedStatsTreeNodeToBasicTreeNode(formattedRoot);\n\n return {\n type: 'basic',\n title,\n root,\n };\n}\n\nexport function pruneTree(\n rootNode: PruneTreeNode,\n options: PruningConfig,\n): PruneTreeNode {\n // Provide defaults for all required properties\n const completeOptions: Required = {\n maxDepth: options.maxDepth ?? 999,\n maxChildren: options.maxChildren ?? 999,\n minSize: options.minSize ?? 0,\n pathLength: options.pathLength ?? 999,\n enabled: options.enabled ?? true,\n };\n\n // Start from 1 so that maxDepth: 2 stops at package level, maxDepth: 3 shows individual files\n return pruneTreeRecursive(rootNode, completeOptions, 1);\n}\n\nfunction pruneTreeRecursive(\n node: PruneTreeNode,\n options: Required,\n currentDepth: number,\n): PruneTreeNode {\n const { maxChildren, maxDepth, minSize } = options;\n\n if (node.children.length === 0) {\n return node;\n }\n\n // Sort children by size (largest first)\n if (node.children.length > 1) {\n node.children.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n // Apply maxChildren and minSize filtering at all levels within maxDepth\n const keptChildren: StatsTreeNode[] = [];\n const groupedChildren: StatsTreeNode[] = [];\n\n for (const child of node.children) {\n if (child.values.bytes >= minSize) {\n // Recursively prune child's subtree if within maxDepth\n const prunedChild =\n currentDepth < maxDepth\n ? pruneTreeRecursive(\n { children: child.children },\n options,\n currentDepth + 1,\n )\n : { children: [] };\n\n keptChildren.push({\n ...child,\n children: prunedChild.children,\n });\n } else {\n // Collect small files for grouping\n groupedChildren.push(child);\n }\n }\n\n // Apply maxChildren limit - move overflow to grouped items\n let finalChildren = keptChildren;\n if (keptChildren.length > maxChildren) {\n const kept = keptChildren.slice(0, maxChildren);\n const overflow = keptChildren.slice(maxChildren);\n\n // Add overflow files to the grouped items\n groupedChildren.push(...overflow);\n finalChildren = kept;\n }\n\n // Create \"...\" group if we have multiple items to represent, or show single item directly\n if (groupedChildren.length > 0) {\n if (groupedChildren.length === 1) {\n // If there's only one grouped item, show it directly instead of creating \"...\" group\n finalChildren.push(groupedChildren[0]!);\n } else {\n // Multiple items - create \"...\" group\n const totalBytes = groupedChildren.reduce(\n (sum, child) => sum + child.values.bytes,\n 0,\n );\n const totalModules = groupedChildren.reduce(\n (sum, child) => sum + child.values.modules,\n 0,\n );\n\n const moreNode = {\n name: '...',\n values: {\n path: '',\n bytes: totalBytes,\n modules: totalModules,\n type: 'group' as const,\n },\n children: [], // Empty - just represents the grouped items\n };\n\n finalChildren.push(moreNode);\n }\n }\n\n return { children: finalChildren };\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.unit.test.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'GroupingRule' is defined but never used.", + "line": 2, + "column": 15, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 2, + "endColumn": 27 + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it } from 'vitest';\nimport type { GroupingRule } from '../../types.js';\nimport { type StatsTreeNode, applyGrouping } from './grouping.js';\n\ndescribe('applyGrouping', () => {\n it('should group inputs by single pattern', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['src/**'], title: 'Source Files' },\n ]),\n ).toStrictEqual([\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'Source Files',\n values: {\n path: '',\n bytes: 150,\n modules: 2,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs by multiple patterns', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n path: 'src/utils/helper.ts',\n bytes: 40,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'tests/unit.test.ts',\n values: {\n path: 'tests/unit.test.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['src/**', 'tests/**'], title: 'Project Files' },\n ]),\n ).toStrictEqual([\n {\n name: 'Project Files',\n values: {\n bytes: 180,\n modules: 3,\n type: 'group',\n path: '',\n icon: undefined,\n },\n children: [\n {\n name: 'src/components/Button.tsx',\n values: {\n bytes: 80,\n modules: 1,\n type: 'static-import',\n path: 'src/components/Button.tsx',\n },\n children: [],\n },\n {\n name: 'tests/unit.test.ts',\n values: {\n bytes: 60,\n modules: 1,\n type: 'static-import',\n path: 'tests/unit.test.ts',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n bytes: 40,\n modules: 1,\n type: 'static-import',\n path: 'src/utils/helper.ts',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs with include/exclude patterns', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/components/Button.test.tsx',\n values: {\n path: 'src/components/Button.test.tsx',\n bytes: 40,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n path: 'src/utils/helper.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n {\n title: 'Source Code',\n includeInputs: ['src/**'],\n excludeInputs: ['**/*.test.*'],\n },\n ]),\n ).toStrictEqual([\n {\n name: 'Source Code',\n values: {\n path: '',\n bytes: 140,\n modules: 2,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n path: 'src/utils/helper.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs with numSegments', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 120,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'node_modules/lodash/core.js',\n values: {\n path: 'node_modules/lodash/core.js',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['node_modules/**'], numSegments: 2 },\n ]),\n ).toStrictEqual([\n {\n name: 'react',\n values: {\n path: 'node_modules/react',\n bytes: 120,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 120,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'lodash',\n values: {\n path: 'node_modules/lodash',\n bytes: 80,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'node_modules/lodash/core.js',\n values: {\n path: 'node_modules/lodash/core.js',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should add icons to nodes', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [{ includeInputs: ['src/**'], icon: '📦' }]),\n ).toStrictEqual([\n {\n name: 'Group',\n values: {\n path: '',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: '📦',\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should add title to nodes', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['src/**'], title: 'Source Code' },\n ]),\n ).toStrictEqual([\n {\n name: 'Source Code',\n values: {\n path: '',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should autoderive title from patterns', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [{ includeInputs: ['node_modules/**'] }]),\n ).toStrictEqual([\n {\n name: 'react',\n values: {\n path: '',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should separate packages into different groups with numSegments', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'packages/design-system/ui/button/src/button.component.ts',\n values: {\n path: 'packages/design-system/ui/button/src/button.component.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'packages/vanilla/lib/core/services/service.ts',\n values: {\n path: 'packages/vanilla/lib/core/services/service.ts',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'packages/themepark/components/theme.ts',\n values: {\n path: 'packages/themepark/components/theme.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['packages/**'], numSegments: 2 },\n ]),\n ).toStrictEqual([\n {\n name: 'design-system',\n values: {\n path: 'packages/design-system',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'packages/design-system/ui/button/src/button.component.ts',\n values: {\n path: 'packages/design-system/ui/button/src/button.component.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'vanilla',\n values: {\n path: 'packages/vanilla',\n bytes: 80,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'packages/vanilla/lib/core/services/service.ts',\n values: {\n path: 'packages/vanilla/lib/core/services/service.ts',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'themepark',\n values: {\n path: 'packages/themepark',\n bytes: 60,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'packages/themepark/components/theme.ts',\n values: {\n path: 'packages/themepark/components/theme.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should handle complex include/exclude combinations', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/components/Button.test.tsx',\n values: {\n path: 'src/components/Button.test.tsx',\n bytes: 40,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/components/Modal.spec.tsx',\n values: {\n path: 'src/components/Modal.spec.tsx',\n bytes: 30,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n {\n title: 'Source Code',\n includeInputs: ['src/**'],\n excludeInputs: ['**/*.test.*', '**/*.spec.*'],\n icon: '📦',\n },\n {\n title: 'Dependencies',\n includeInputs: ['node_modules/**'],\n icon: '🔗',\n },\n ]),\n ).toStrictEqual([\n {\n name: 'Dependencies',\n values: {\n path: '',\n bytes: 200,\n modules: 1,\n type: 'group',\n icon: '🔗',\n },\n children: [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'Source Code',\n values: {\n path: '',\n bytes: 80,\n modules: 1,\n type: 'group',\n icon: '📦',\n },\n children: [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs by multiple patterns with icons', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 300,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n {\n includeInputs: ['src/main.ts', 'src/utils.ts'],\n title: 'Source Files',\n icon: '📄',\n },\n ]),\n ).toStrictEqual([\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 300,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'Source Files',\n values: {\n path: '',\n bytes: 150,\n modules: 2,\n type: 'group',\n icon: '📄',\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/types.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/scoring.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.1.", + "line": 34, + "column": 18, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 34, + "endColumn": 21 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.2.", + "line": 35, + "column": 16, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 35, + "endColumn": 19 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.2.", + "line": 66, + "column": 47, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 66, + "endColumn": 50 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.1.", + "line": 67, + "column": 51, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 67, + "endColumn": 54 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 69, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 69, + "endColumn": 22 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 70, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 70, + "endColumn": 24 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 72, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 78, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 150, + "column": 5, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 150, + "endColumn": 27 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.2.", + "line": 178, + "column": 36, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 178, + "endColumn": 39 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.2.", + "line": 201, + "column": 46, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 201, + "endColumn": 49 + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 0.1.", + "line": 202, + "column": 50, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 202, + "endColumn": 53 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 11, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { Issue } from '@code-pushup/models';\nimport type { MinMax } from '../types.js';\n\nexport type BlacklistPatternList = readonly BlacklistEntry[];\nexport type BlacklistEntry =\n | string\n | {\n pattern: string;\n hint?: string;\n };\n\nexport type PenaltyConfig = {\n enabled?: boolean;\n artefactSize?: [number, number];\n warningWeight?: number;\n errorWeight?: number;\n /**\n * glob patterns when matching get penalised\n * e.g. packagenames outdates, should be lazy loaded, etc.\n * Can be simple strings or objects with pattern and optional hint\n */\n blacklist?: BlacklistPatternList;\n};\n\nexport type ScoringConfig = {\n mode: 'off' | 'matchingWithStaticImports' | 'onlyMatching';\n totalSize?: MinMax;\n penalty?: false | PenaltyConfig;\n};\n\nexport type ScoreCalculator = (value: number, issues: Issue[]) => number;\n\nexport const DEFAULT_PENALTY: PenaltyConfig = {\n warningWeight: 0.1,\n errorWeight: 0.2,\n};\n\n/**\n * Calculates normalized penalty score from issues using provided penalty options. Legacy function for backward compatibility.\n *\n * ## Penalty Parameters\n * - **E**: Count of issues of severity errors (🚨)\n * - **W**: Count of issues of severity warnings (⚠️)\n * - **we**: Weight per error issue (default 0.2)\n * - **ww**: Weight per warning issue (default 0.1)\n *\n * ## Default Penalty Options\n * When penalty options are not provided, these defaults are used:\n * - **errorWeight**: 0.2\n * - **warningWeight**: 0.1\n *\n * ## Issues Penalty Formula\n * ```\n * penalty = we × E + ww × W\n * normalizedPenalty = penalty / (we + ww)\n * ```\n *\n * @param issues - Array of diagnostic issues with severity levels\n * @param penalty - Penalty configuration with error and warning weights\n * @returns Normalized penalty score (0-1) based on issue counts and weights\n */\nexport function calculatePenalty(\n issues: Issue[],\n penalty?: PenaltyConfig,\n): number {\n const errorWeight = penalty?.errorWeight ?? 0.2;\n const warningWeight = penalty?.warningWeight ?? 0.1;\n\n let errorCount = 0;\n let warningCount = 0;\n\n for (const issue of issues) {\n if (issue.severity === 'error') {\n errorCount++;\n } else if (issue.severity === 'warning') {\n warningCount++;\n }\n }\n\n const penaltyValue = errorWeight * errorCount + warningWeight * warningCount;\n const totalWeight = errorWeight + warningWeight;\n\n return totalWeight > 0 ? penaltyValue / totalWeight : 0;\n}\n\n/**\n * Creates a score calculator function configured with bundle settings. Applies direct penalty subtraction for intuitive scoring behavior with a maximum penalty cap of 20%.\n *\n * ## Scoring\n * Assigns a score in the range [0 … 1] to each artefact (or artefact selection) based on:\n * - Size vs. configurable minimum and maximum thresholds (if totalSize provided, otherwise defaults to 100%)\n * - Direct penalty subtraction based on issue severity levels (when enabled)\n * - Penalty is capped at maximum 20% of the size score\n *\n * A perfect score (1) means \"within acceptable range\"; lower values indicate regressions.\n *\n * ## Size Parameters\n * - **S**: Actual bytes\n * - **Min**: Minimum threshold bytes (lower bound)\n * - **Max**: Maximum threshold bytes (upper bound)\n *\n * ## Size Score Formula\n * When totalSize is not provided:\n * ```\n * sizeScore = 1 (100%)\n * ```\n *\n * For single threshold (number):\n * ```\n * sizeScore = {\n * 1, if S ≤ threshold\n * 0, if S > threshold\n * }\n * ```\n *\n * For range thresholds [Min, Max]:\n * ```\n * sizeScore = {\n * max(0, S/Min), if S < Min (penalize under-sized bundles)\n * 1, if Min ≤ S ≤ Max (perfect score)\n * 0, if S > Max (too big = score 0)\n * }\n * ```\n *\n * ## Penalty Calculation\n * Direct subtraction approach with 20% maximum penalty cap:\n * ```\n * penaltyShift = errors × errorWeight + warnings × warningWeight\n * cappedPenalty = min(penaltyShift, sizeScore × 0.2)\n * ```\n * Default weights: errorWeight = 0.2, warningWeight = 0.1\n *\n * ## Final Score Calculation\n * ```\n * finalScore = max(0, sizeScore - cappedPenalty)\n * ```\n * This creates a penalty shift pattern where issues directly reduce the score by their weight values,\n * but the total penalty reduction is capped at 20% of the original size score.\n * Note: When `penalty` is `false` or undefined, only size score is used.\n *\n * @param options - Scoring configuration containing optional thresholds and penalty weights\n * @returns Score calculator function that takes (value, issues) and returns score [0-1]\n */\nexport function createBundleStatsScoring(\n options: ScoringConfig,\n): ScoreCalculator {\n const { totalSize, penalty } = options;\n\n return (value: number, issues: Issue[] = []): number => {\n let sizeScore: number;\n\n if (!totalSize) {\n // No size constraints - default to perfect score (100%)\n sizeScore = 1;\n } else if (Array.isArray(totalSize)) {\n // Range thresholds [min, max]\n const [minThreshold, maxThreshold] = totalSize;\n\n if (value < minThreshold) {\n sizeScore = Math.max(0, value / minThreshold);\n } else if (value <= maxThreshold) {\n sizeScore = 1;\n } else {\n sizeScore = 0;\n }\n } else {\n sizeScore = value <= totalSize ? 1 : 0;\n }\n\n if (penalty === false || penalty === undefined || issues.length === 0) {\n return sizeScore;\n }\n\n const penaltyOptions = penalty || DEFAULT_PENALTY;\n const penaltyShift = calculatePenaltyShift(issues, penaltyOptions);\n\n // Cap penalty at maximum 20% of the size score\n const maxPenalty = sizeScore * 0.2;\n const cappedPenalty = Math.min(penaltyShift, maxPenalty);\n\n return Math.max(0, sizeScore - cappedPenalty);\n };\n}\n\n/**\n * Calculates direct penalty shift based on issue counts and weights. Creates intuitive score reduction where each issue subtracts its weight from the final score.\n *\n * @param issues - Array of diagnostic issues with severity levels\n * @param options - Penalty configuration with error and warning weights\n * @returns Direct penalty shift value to subtract from size score\n */\nfunction calculatePenaltyShift(\n issues: Issue[],\n options: PenaltyConfig,\n): number {\n const errorCount = issues.filter(issue => issue.severity === 'error').length;\n const warningCount = issues.filter(\n issue => issue.severity === 'warning',\n ).length;\n\n const errorWeight = options.errorWeight ?? 0.2;\n const warningWeight = options.warningWeight ?? 0.1;\n\n // Direct penalty: each error/warning reduces score by its weight\n return errorCount * errorWeight + warningCount * warningWeight;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/selection.ts", + "messages": [ + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 42, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 46, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 54, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 56, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'getImportPaths' is defined but never used.", + "line": 59, + "column": 11, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 59, + "endColumn": 25 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 63, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 65, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 75, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 79, + "endColumn": 4 + }, + { + "ruleId": "sonarjs/no-identical-functions", + "severity": 2, + "message": "Update this function so that its implementation is not identical to the one on line 68.", + "line": 83, + "column": 10, + "nodeType": null, + "messageId": "identicalFunctions", + "endLine": 83, + "endColumn": 26 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 90, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 94, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'pathsMatchPatterns' is defined but never used.", + "line": 98, + "column": 10, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 98, + "endColumn": 28 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 108, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 110, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 109, + "column": 5, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 109, + "endColumn": 25 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 118, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 122, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 131, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 135, + "endColumn": 4 + }, + { + "ruleId": "sonarjs/prefer-single-boolean-return", + "severity": 1, + "message": "Replace this if-then-else flow by a single return statement.", + "line": 176, + "column": 5, + "nodeType": "IfStatement", + "messageId": "replaceIfThenElseByReturn", + "endLine": 178, + "endColumn": 6, + "suggestions": [ + { + "messageId": "suggest", + "fix": { + "range": [4033, 4132], + "text": "return !(hasExcludedInput(bundle, patterns.excludeInputs));" + }, + "desc": "Replace with single return statement" + } + ] + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 203, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 203, + "endColumn": 25 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 204, + "column": 3, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 204, + "endColumn": 26 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 206, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 212, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 208, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 208, + "endColumn": 44 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 232, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 236, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 234, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 234, + "endColumn": 29 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'selectBundles' has too many lines (88). Maximum allowed is 50.", + "line": 267, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 381, + "endColumn": 2 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 277, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 279, + "endColumn": 4 + }, + { + "ruleId": "sonarjs/no-unused-collection", + "severity": 2, + "message": "Either use this collection's contents or remove the collection.", + "line": 288, + "column": 9, + "nodeType": "Identifier", + "messageId": "unusedCollection", + "endLine": 288, + "endColumn": 21 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 307, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 326, + "endColumn": 4 + }, + { + "ruleId": "functional/no-let", + "severity": 1, + "message": "Unexpected let, use const instead.", + "line": 313, + "column": 5, + "nodeType": "VariableDeclaration", + "messageId": "generic", + "endLine": 313, + "endColumn": 34 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 337, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 341, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 338, + "column": 7, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 340, + "endColumn": 8 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 344, + "column": 5, + "nodeType": "WhileStatement", + "messageId": "generic", + "endLine": 377, + "endColumn": 6 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 345, + "column": 26, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 345, + "endColumn": 49 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 345, + "column": 26, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 345, + "endColumn": 48 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 368, + "column": 9, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 375, + "endColumn": 10 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", + "line": 369, + "column": 11, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 374, + "endColumn": 12 + }, + { + "ruleId": "max-lines", + "severity": 1, + "message": "File has too many lines (311). Maximum allowed is 300.", + "line": 370, + "column": 1, + "nodeType": null, + "messageId": "exceed", + "endLine": 382, + "endColumn": 1 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 373, + "column": 13, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 373, + "endColumn": 53 + } + ], + "suppressedMessages": [], + "errorCount": 11, + "fatalErrorCount": 0, + "warningCount": 22, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n} from '../unify/unified-stats.types.js';\nimport { type PatternMatcher, compilePattern } from './details/grouping.js';\n\nexport type SelectionOutputsConfig = {\n includeOutputs: string[];\n excludeOutputs: string[];\n};\n\nexport type SelectionInputsConfig = {\n includeInputs: string[];\n excludeInputs: string[];\n};\n\nexport type SelectionMode =\n | 'matchingOnly'\n | 'bundle'\n | 'withStartupDeps'\n | 'withAllDeps';\n\nexport type SelectionConfig = {\n mode: SelectionMode;\n} & SelectionOutputsConfig &\n SelectionInputsConfig;\n\nexport type CompiledPatterns = {\n includeOutputs: PatternMatcher[];\n excludeOutputs: PatternMatcher[];\n includeInputs: PatternMatcher[];\n excludeInputs: PatternMatcher[];\n};\n\nfunction compilePatterns(patterns: string[]): PatternMatcher[] {\n return patterns.map(pattern =>\n compilePattern(pattern, { normalizeRelativePaths: true }),\n );\n}\n\nfunction matchesAnyPattern(path: string, patterns: PatternMatcher[]): boolean {\n for (const pattern of patterns) {\n if (pattern(path)) {\n return true;\n } // Early exit on first match\n }\n return false;\n}\n\nfunction* getInputPaths(bundle: UnifiedStatsBundle): Generator {\n if (!bundle.inputs) {\n return;\n }\n for (const path of Object.keys(bundle.inputs)) {\n yield path;\n }\n}\n\nfunction* getImportPaths(bundle: UnifiedStatsBundle): Generator {\n if (!bundle.imports) {\n return;\n }\n for (const imp of bundle.imports) {\n yield imp.path;\n }\n}\n\nfunction hasMatchingInput(\n bundle: UnifiedStatsBundle,\n patterns: PatternMatcher[],\n): boolean {\n if (patterns.length === 0) {\n return false;\n }\n for (const path of getInputPaths(bundle)) {\n if (matchesAnyPattern(path, patterns)) {\n return true;\n } // Stop on first match\n }\n return false;\n}\n\nfunction hasExcludedInput(\n bundle: UnifiedStatsBundle,\n patterns: PatternMatcher[],\n): boolean {\n if (patterns.length === 0) {\n return false;\n }\n for (const path of getInputPaths(bundle)) {\n if (matchesAnyPattern(path, patterns)) {\n return true;\n } // Stop on first exclusion\n }\n return false;\n}\n\nfunction pathsMatchPatterns(\n paths: Generator,\n includePatterns: PatternMatcher[],\n excludePatterns: PatternMatcher[],\n): boolean {\n if (includePatterns.length === 0 && excludePatterns.length === 0) {\n return true;\n }\n\n const pathArray: string[] = [];\n for (const path of paths) {\n pathArray.push(path);\n }\n\n if (pathArray.length === 0) {\n return includePatterns.length === 0;\n }\n\n // Check excludes first (early exit)\n if (excludePatterns.length > 0) {\n for (const path of pathArray) {\n if (matchesAnyPattern(path, excludePatterns)) {\n return false;\n }\n }\n }\n\n // If no includes specified, and nothing excluded, include it\n if (includePatterns.length === 0) {\n return true;\n }\n\n // Check includes\n for (const path of pathArray) {\n if (matchesAnyPattern(path, includePatterns)) {\n return true;\n }\n }\n\n return false;\n}\n\n// Mode-specific processors for optimized selection\nconst bundleSelectors = {\n matchingOnly: (\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n ): boolean =>\n patterns.includeInputs.length > 0 &&\n hasMatchingInput(bundle, patterns.includeInputs),\n\n bundle: (bundle: UnifiedStatsBundle, patterns: CompiledPatterns): boolean => {\n const hasIncludePatterns =\n patterns.includeOutputs.length > 0 || patterns.includeInputs.length > 0;\n if (!hasIncludePatterns) {\n return false;\n }\n\n // Check output patterns\n if (\n patterns.includeOutputs.length > 0 &&\n !matchesAnyPattern(bundle.path, patterns.includeOutputs)\n ) {\n return false;\n }\n\n // Check input patterns\n if (\n patterns.includeInputs.length > 0 &&\n !hasMatchingInput(bundle, patterns.includeInputs)\n ) {\n return false;\n }\n\n // Check exclusions\n if (matchesAnyPattern(bundle.path, patterns.excludeOutputs)) {\n return false;\n }\n if (hasExcludedInput(bundle, patterns.excludeInputs)) {\n return false;\n }\n\n return true;\n },\n\n withStartupDeps: (\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n ): boolean => bundleSelectors.bundle(bundle, patterns),\n\n withAllDeps: (\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n ): boolean => bundleSelectors.bundle(bundle, patterns),\n};\n\nfunction processMatchingOnlyBundle(\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n): UnifiedStatsBundle | null {\n if (!bundle.inputs) {\n return null;\n }\n\n const filteredInputs: typeof bundle.inputs = {};\n let filteredBytes = 0;\n let hasMatches = false;\n\n for (const [inputPath, inputData] of Object.entries(bundle.inputs)) {\n if (matchesAnyPattern(inputPath, patterns.includeInputs)) {\n filteredInputs[inputPath] = inputData;\n filteredBytes += inputData.bytes;\n hasMatches = true;\n }\n }\n\n return hasMatches\n ? {\n path: bundle.path,\n bytes: filteredBytes,\n inputs: filteredInputs,\n }\n : null;\n}\n\nfunction collectImportsForMode(\n bundle: UnifiedStatsBundle,\n mode: SelectionMode,\n): string[] {\n if (!bundle.imports) {\n return [];\n }\n\n const imports: string[] = [];\n for (const imp of bundle.imports) {\n if (mode === 'withAllDeps' || imp.kind === 'import-statement') {\n imports.push(imp.path);\n }\n }\n return imports;\n}\n\nfunction validatePatterns(patterns: CompiledPatterns): void {\n const hasAnyPatterns = [\n patterns.includeOutputs,\n patterns.excludeOutputs,\n patterns.includeInputs,\n patterns.excludeInputs,\n ].some(arr => arr.length > 0);\n\n if (!hasAnyPatterns) {\n throw new Error(\n 'Selection requires at least one include/exclude pattern for outputs or inputs. ' +\n 'Provide patterns like: { includeOutputs: [\"*.js\"] } or { includeInputs: [\"src/**\"] }',\n );\n }\n}\n\nexport function compileSelectionPatterns(\n config: SelectionConfig,\n): CompiledPatterns {\n return {\n includeOutputs: compilePatterns(config.includeOutputs),\n excludeOutputs: compilePatterns(config.excludeOutputs),\n includeInputs: compilePatterns(config.includeInputs),\n excludeInputs: compilePatterns(config.excludeInputs),\n };\n}\n\nexport function selectBundles(\n unifiedStats: UnifiedStats,\n selectionConfig: SelectionConfig,\n): UnifiedStats {\n // 🚀 Smart Optimization 1: Single-pass pattern compilation\n const patterns = compileSelectionPatterns(selectionConfig);\n validatePatterns(patterns);\n\n // 🚀 Smart Optimization 2: O(1) bundle lookups with simple map\n const pathToKey = new Map();\n for (const [key, bundle] of Object.entries(unifiedStats)) {\n pathToKey.set(bundle.path, key);\n }\n\n const findBundleByPath = (path: string) => {\n const key = pathToKey.get(path);\n return key && unifiedStats[key] ? { key, bundle: unifiedStats[key] } : null;\n };\n\n // 🚀 Smart Optimization 3: Early exit & set-based processing\n const selectedBundles = new Map();\n const excludedKeys = new Set();\n\n // Get mode-specific selector for optimized processing\n const isSelected = (bundle: UnifiedStatsBundle): boolean => {\n switch (selectionConfig.mode) {\n case 'matchingOnly':\n return bundleSelectors.matchingOnly(bundle, patterns);\n case 'bundle':\n return bundleSelectors.bundle(bundle, patterns);\n case 'withStartupDeps':\n return bundleSelectors.withStartupDeps(bundle, patterns);\n case 'withAllDeps':\n return bundleSelectors.withAllDeps(bundle, patterns);\n default:\n return false;\n }\n };\n\n // Process all bundles with early exits\n for (const [key, bundle] of Object.entries(unifiedStats)) {\n if (!isSelected(bundle)) {\n excludedKeys.add(key);\n continue; // Early exit\n }\n\n let processedBundle = bundle;\n\n // Special processing for matchingOnly mode\n if (selectionConfig.mode === 'matchingOnly') {\n const filtered = processMatchingOnlyBundle(bundle, patterns);\n if (!filtered) {\n excludedKeys.add(key);\n continue; // Early exit\n }\n processedBundle = filtered;\n }\n\n selectedBundles.set(key, processedBundle);\n }\n\n // 🚀 Smart Optimization 4: Optimized dependency processing\n if (\n selectionConfig.mode === 'withStartupDeps' ||\n selectionConfig.mode === 'withAllDeps'\n ) {\n const processed = new Set();\n const importsToProcess: string[] = [];\n\n // Collect all imports from selected bundles\n for (const bundle of selectedBundles.values()) {\n importsToProcess.push(\n ...collectImportsForMode(bundle, selectionConfig.mode),\n );\n }\n\n // Process imports with optimized lookups and early exits\n while (importsToProcess.length > 0) {\n const importPath = importsToProcess.pop()!;\n if (processed.has(importPath)) {\n continue;\n } // Early exit\n processed.add(importPath);\n\n const found = findBundleByPath(importPath);\n if (!found || selectedBundles.has(found.key)) {\n continue;\n } // Early exit\n\n // Check if import should be excluded\n if (matchesAnyPattern(found.bundle.path, patterns.excludeOutputs)) {\n continue;\n }\n if (hasExcludedInput(found.bundle, patterns.excludeInputs)) {\n continue;\n }\n\n selectedBundles.set(found.key, found.bundle);\n\n // Add nested static imports for further processing\n if (found.bundle.imports) {\n for (const nestedImport of found.bundle.imports) {\n if (\n nestedImport.kind === 'import-statement' &&\n !processed.has(nestedImport.path)\n ) {\n importsToProcess.push(nestedImport.path);\n }\n }\n }\n }\n }\n\n return Object.fromEntries(selectedBundles);\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/selection.unit.test.ts", + "messages": [ + { + "ruleId": "vitest/no-conditional-expect", + "severity": 1, + "message": "Avoid calling `expect` inside conditional statements", + "line": 264, + "column": 9, + "nodeType": "CallExpression", + "messageId": "noConditionalExpect", + "endLine": 266, + "endColumn": 21 + }, + { + "ruleId": "vitest/no-conditional-expect", + "severity": 1, + "message": "Avoid calling `expect` inside conditional statements", + "line": 305, + "column": 9, + "nodeType": "CallExpression", + "messageId": "noConditionalExpect", + "endLine": 307, + "endColumn": 21 + }, + { + "ruleId": "vitest/no-conditional-expect", + "severity": 1, + "message": "Avoid calling `expect` inside conditional statements", + "line": 323, + "column": 9, + "nodeType": "CallExpression", + "messageId": "noConditionalExpect", + "endLine": 323, + "endColumn": 61 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 3, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it } from 'vitest';\nimport { normalizeSelectionOptions } from '../../normalize.js';\nimport type { UnifiedStats } from '../unify/unified-stats.types.js';\nimport { compileSelectionPatterns, selectBundles } from './selection.js';\n\ndescribe('compileSelectionPatterns', () => {\n it('should return object with correct structure for all pattern types', () => {\n const result = compileSelectionPatterns({\n mode: 'bundle',\n includeOutputs: ['dist/**/*.js'],\n excludeOutputs: ['dist/**/*.map'],\n includeInputs: ['src/**/*.ts'],\n excludeInputs: ['**/*.test.ts'],\n });\n\n expect(result).toStrictEqual({\n includeOutputs: [expect.any(Function)],\n excludeOutputs: [expect.any(Function)],\n includeInputs: [expect.any(Function)],\n excludeInputs: [expect.any(Function)],\n });\n expect([\n result.includeOutputs[0]!('dist/main.js'),\n result.includeOutputs[0]!('dist/main.map'),\n ]).toEqual([true, false]);\n });\n\n it('should handle empty selection options', () => {\n expect(\n compileSelectionPatterns({\n mode: 'bundle',\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n }),\n ).toStrictEqual({\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n });\n });\n\n it('should merge global include/exclude patterns', () => {\n const result = compileSelectionPatterns(\n normalizeSelectionOptions({\n include: ['src/**'],\n exclude: ['*.test.*'],\n includeOutputs: ['main.js'],\n excludeOutputs: ['dev.js'],\n includeInputs: ['components/**'],\n excludeInputs: ['temp.js'],\n }),\n );\n\n expect(\n [\n result.includeOutputs,\n result.excludeOutputs,\n result.includeInputs,\n result.excludeInputs,\n ].map(arr => arr.length),\n ).toEqual([2, 2, 2, 2]);\n });\n\n it('should work with type configurations', () => {\n const result = compileSelectionPatterns({\n mode: 'bundle' as const,\n includeOutputs: ['*.js'],\n excludeOutputs: ['*.test.js'],\n includeInputs: [],\n excludeInputs: [],\n });\n\n expect([\n result.includeOutputs[0]!('main.js'),\n result.excludeOutputs[0]!('main.test.js'),\n ]).toEqual([true, true]);\n });\n});\n\ndescribe('selectBundles', () => {\n const empty = {\n mode: 'bundle' as const,\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n\n const stats: UnifiedStats = {\n 'dist/index.js': {\n path: 'dist/index.js',\n bytes: 5000,\n inputs: {\n 'src/index.ts': { bytes: 1000 },\n 'src/lib/feature-1.ts': { bytes: 1000 },\n 'src/lib/utils/format.ts': { bytes: 1000 },\n 'src/lib/utils/math.ts': { bytes: 1000 },\n 'src/lib/feature-2.ts': { bytes: 1000 },\n },\n imports: [\n { path: 'dist/chunks/chunk-U6O5K65G.js', kind: 'import-statement' },\n { path: 'dist/chunks/feature-2-X2YVDBQK.js', kind: 'dynamic-import' },\n ],\n },\n 'dist/bin.js': {\n path: 'dist/bin.js',\n bytes: 3000,\n inputs: {\n 'src/bin.ts': { bytes: 500 },\n 'src/lib/feature-1.ts': { bytes: 1000 },\n 'src/lib/utils/format.ts': { bytes: 1000 },\n 'src/lib/utils/math.ts': { bytes: 500 },\n },\n imports: [\n { path: 'dist/chunks/chunk-U6O5K65G.js', kind: 'import-statement' },\n ],\n },\n 'dist/chunks/chunk-U6O5K65G.js': {\n path: 'dist/chunks/chunk-U6O5K65G.js',\n bytes: 2000,\n inputs: {\n 'src/lib/utils/format.ts': { bytes: 1000 },\n 'src/lib/feature-1.ts': { bytes: 500 },\n 'src/lib/utils/math.ts': { bytes: 500 },\n },\n },\n 'dist/chunks/feature-2-X2YVDBQK.js': {\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n bytes: 1000,\n inputs: {\n 'src/lib/feature-2.ts': { bytes: 1000 },\n },\n },\n };\n\n it('should return empty result for empty stats', () => {\n expect(\n selectBundles({}, { ...empty, includeOutputs: ['*.js'] }),\n ).toStrictEqual({});\n });\n\n it('should throw error for empty selection options', () => {\n expect(() => selectBundles({}, empty)).toThrow(\n 'Selection requires at least one include/exclude pattern',\n );\n expect(() =>\n selectBundles(\n { 'main.js': { path: 'dist/main.js', bytes: 0, inputs: {} } },\n empty,\n ),\n ).toThrow('Provide patterns like');\n });\n\n // Byte Inclusion Tests\n it('should select output and dependencies (Include Output)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n }),\n ),\n ).toEqual(['dist/index.js', 'dist/chunks/chunk-U6O5K65G.js']);\n });\n\n it('should include static imports only (Include Output)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n !!result['dist/chunks/chunk-U6O5K65G.js'],\n !!result['dist/chunks/feature-2-X2YVDBQK.js'],\n ]).toEqual([true, false]);\n });\n\n it('should select only bundle file in bundle mode', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n mode: 'bundle',\n includeOutputs: ['**/dist/index.js'],\n }),\n ),\n ).toEqual(['dist/index.js']);\n });\n\n it('should exclude files by pattern (Include/Exclude Output)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/*'],\n excludeOutputs: ['**/bin.js'],\n }),\n ),\n ).toEqual([\n 'dist/index.js',\n 'dist/chunks/chunk-U6O5K65G.js',\n 'dist/chunks/feature-2-X2YVDBQK.js',\n ]);\n });\n\n it('should prioritize exclude over include', () => {\n expect(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/dist/index.js'],\n excludeOutputs: ['**/dist/index.js'],\n }),\n ).toStrictEqual({});\n });\n\n it('should select by input files (Include Input)', () => {\n expect(\n Object.keys(\n selectBundles(stats, { ...empty, includeInputs: ['**/feature-2.ts'] }),\n ),\n ).toEqual(['dist/index.js', 'dist/chunks/feature-2-X2YVDBQK.js']);\n });\n\n it('should select by utility files (Include Input)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeInputs: ['**/utils/format.ts'],\n }),\n ),\n ).toEqual([\n 'dist/index.js',\n 'dist/bin.js',\n 'dist/chunks/chunk-U6O5K65G.js',\n ]);\n });\n\n it('should exclude by input files (Include/Exclude Input)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/*'],\n excludeInputs: ['**/feature-2.ts'],\n }),\n ),\n ).toEqual(['dist/bin.js', 'dist/chunks/chunk-U6O5K65G.js']);\n });\n\n it('should exclude utility files', () => {\n const result = selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/*'],\n excludeInputs: ['**/utils/**'],\n });\n Object.values(result).forEach(\n output =>\n output?.inputs &&\n expect(\n Object.keys(output.inputs).every(path => !path.includes('utils')),\n ).toBe(true),\n );\n });\n\n it('should handle complex filtering (Include/Exclude Mixed)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/index.js', '**/chunks/**'],\n excludeOutputs: ['**/bin.js'],\n excludeInputs: ['**/utils/**'],\n }),\n ),\n ).not.toContain('dist/bin.js');\n });\n\n it('should combine include patterns with OR logic', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/index.js', '**/bin.js'],\n excludeInputs: ['**/feature-2.ts'],\n }),\n ),\n ).toEqual(['dist/bin.js']);\n });\n\n // Dependency Inclusion Tests\n it('should filter inputs in matchingOnly mode', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'matchingOnly',\n includeInputs: ['**/utils/format.ts'],\n });\n Object.values(result).forEach(\n output =>\n output?.inputs &&\n expect(\n Object.keys(output.inputs).every(path => path.includes('format.ts')),\n ).toBe(true),\n );\n });\n\n it('should exclude bundler overhead in matchingOnly mode', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'matchingOnly',\n includeInputs: ['**/feature-1.ts'],\n });\n Object.values(result).forEach(output => {\n if (output?.inputs) {\n const inputBytes = Object.values(output.inputs).reduce(\n (sum, input) => sum + (input?.bytes || 0),\n 0,\n );\n expect(output.bytes).toBeLessThanOrEqual(inputBytes);\n }\n });\n });\n\n it('should include full bundle with overhead (Mode: bundle)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'bundle',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n result['dist/index.js']?.bytes,\n Object.keys(result).length,\n ]).toEqual([5000, 1]);\n });\n\n it('should preserve bundled inputs (Mode: bundle)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n mode: 'bundle',\n includeOutputs: ['**/dist/bin.js'],\n })['dist/bin.js']?.inputs || {},\n ),\n ).toHaveLength(4);\n });\n\n it('should include static imports (Mode: withStartupDeps)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n !!result['dist/chunks/chunk-U6O5K65G.js'],\n !!result['dist/chunks/feature-2-X2YVDBQK.js'],\n ]).toEqual([true, false]);\n });\n\n it('should exclude static imports by pattern (Mode: withStartupDeps)', () => {\n expect(\n selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n excludeOutputs: ['**/chunks/**'],\n })['dist/chunks/chunk-U6O5K65G.js'],\n ).toBeUndefined();\n });\n\n it('should include all imports (Mode: withAllDeps)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'withAllDeps',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n !!result['dist/chunks/chunk-U6O5K65G.js'],\n !!result['dist/chunks/feature-2-X2YVDBQK.js'],\n ]).toEqual([true, true]);\n });\n\n it('should exclude dependencies that match exclude patterns (Mode: withAllDeps)', () => {\n expect(\n selectBundles(stats, {\n ...empty,\n mode: 'withAllDeps',\n includeOutputs: ['**/dist/index.js'],\n excludeOutputs: ['**/chunks/**'],\n }),\n ).toStrictEqual({ 'dist/index.js': stats['dist/index.js'] });\n });\n\n it('should handle nested dependency chains (Mode: withAllDeps)', () => {\n const nestedStats = {\n 'dist/nested.js': {\n path: 'dist/nested.js',\n bytes: 1000,\n inputs: {},\n imports: [{ path: 'dist/level1.js', kind: 'import-statement' }],\n },\n 'dist/level1.js': {\n path: 'dist/level1.js',\n bytes: 500,\n inputs: {},\n imports: [{ path: 'dist/level2.js', kind: 'dynamic-import' }],\n },\n 'dist/level2.js': { path: 'dist/level2.js', bytes: 200, inputs: {} },\n } as unknown as UnifiedStats;\n\n expect(\n Object.keys(\n selectBundles(nestedStats, {\n ...empty,\n mode: 'withAllDeps',\n includeOutputs: ['**/nested.js'],\n }),\n ),\n ).toEqual(['dist/nested.js', 'dist/level1.js']);\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.int.test.ts", + "messages": [ + { + "ruleId": "unicorn/no-empty-file", + "severity": 1, + "message": "Empty files are not allowed.", + "line": 1, + "column": 1, + "nodeType": "Program", + "messageId": "no-empty-file", + "endLine": 1, + "endColumn": 1 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 1, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.ts", + "messages": [ + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'validateBundleStats' has too many lines (66). Maximum allowed is 50.", + "line": 35, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 102, + "endColumn": 2 + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 109, + "column": 12, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 109, + "endColumn": 15, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3597, 3600], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3597, 3600], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 109, + "column": 27, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 109, + "endColumn": 30, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3612, 3615], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3612, 3615], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 112, + "column": 22, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 112, + "endColumn": 25, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3697, 3700], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3697, 3700], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 112, + "column": 36, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 112, + "endColumn": 39, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3711, 3714], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3711, 3714], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "functional/prefer-tacit", + "severity": 1, + "message": "Potentially unnecessary function wrapper.", + "line": 115, + "column": 14, + "nodeType": "ArrowFunctionExpression", + "messageId": "generic", + "endLine": 115, + "endColumn": 54, + "suggestions": [ + { + "messageId": "generic", + "fix": { + "range": [3800, 3840], + "text": "unifyWebpackStats" + }, + "desc": "Potentially unnecessary function wrapper." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 115, + "column": 22, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 115, + "endColumn": 25, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3808, 3811], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3808, 3811], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "functional/prefer-tacit", + "severity": 1, + "message": "Potentially unnecessary function wrapper.", + "line": 117, + "column": 14, + "nodeType": "ArrowFunctionExpression", + "messageId": "generic", + "endLine": 117, + "endColumn": 54, + "suggestions": [ + { + "messageId": "generic", + "fix": { + "range": [3875, 3915], + "text": "unifyRsbuildStats" + }, + "desc": "Potentially unnecessary function wrapper." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 117, + "column": 22, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 117, + "endColumn": 25, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3883, 3886], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3883, 3886], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "functional/prefer-tacit", + "severity": 1, + "message": "Potentially unnecessary function wrapper.", + "line": 119, + "column": 14, + "nodeType": "ArrowFunctionExpression", + "messageId": "generic", + "endLine": 119, + "endColumn": 51, + "suggestions": [ + { + "messageId": "generic", + "fix": { + "range": [3947, 3984], + "text": "unifyViteStats" + }, + "desc": "Potentially unnecessary function wrapper." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 119, + "column": 22, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 119, + "endColumn": 25, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [3955, 3958], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [3955, 3958], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 121, + "column": 22, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 121, + "endColumn": 25, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [4025, 4028], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [4025, 4028], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-explicit-any", + "severity": 2, + "message": "Unexpected any. Specify a different type.", + "line": 121, + "column": 36, + "nodeType": "TSAnyKeyword", + "messageId": "unexpectedAny", + "endLine": 121, + "endColumn": 39, + "suggestions": [ + { + "messageId": "suggestUnknown", + "fix": { + "range": [4039, 4042], + "text": "unknown" + }, + "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." + }, + { + "messageId": "suggestNever", + "fix": { + "range": [4039, 4042], + "text": "never" + }, + "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." + } + ] + }, + { + "ruleId": "@typescript-eslint/no-magic-numbers", + "severity": 1, + "message": "No magic number: 20.", + "line": 159, + "column": 22, + "nodeType": "Literal", + "messageId": "noMagic", + "endLine": 159, + "endColumn": 24 + } + ], + "suppressedMessages": [], + "errorCount": 9, + "fatalErrorCount": 0, + "warningCount": 5, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { AuditOutput, PluginArtifactOptions } from '@code-pushup/models';\nimport { executeProcess, readJsonFile } from '@code-pushup/utils';\nimport { normalizeRange } from '../normalize.js';\nimport type {\n PluginDependencyTreeOptions,\n PluginInsightsTableOptions,\n PluginScoringOptions,\n PluginSelectionOptions,\n} from '../types.js';\nimport { generateAuditOutputs } from './audits/audit-outputs.js';\nimport type { InsightsTableConfig } from './audits/details/table.js';\nimport type { DependencyTreeConfig } from './audits/details/tree.js';\nimport { DEFAULT_PENALTY } from './audits/scoring.js';\nimport type { SelectionConfig } from './audits/selection.js';\nimport type {\n BundleStatsConfig,\n GroupingRule,\n SupportedBundlers,\n} from './types.js';\nimport type { UnifiedStats } from './unify/unified-stats.types.js';\nimport { unifyBundlerStats as unifyEsbuildStats } from './unify/unify.esbuild.js';\nimport { unifyBundlerStats as unifyRsbuildStats } from './unify/unify.rsbuild.js';\nimport { unifyBundlerStats as unifySondaStats } from './unify/unify.sonda.js';\nimport { unifyBundlerStats as unifyViteStats } from './unify/unify.vite.js';\nimport { unifyBundlerStats as unifyWebpackStats } from './unify/unify.webpack.js';\n\nexport type BundleStatsRunnerConfig = {\n bundler: SupportedBundlers;\n bundleStatsConfigs: BundleStatsConfig[];\n} & PluginArtifactOptions;\n\n/**\n * Validates bundle stats data structure based on bundler type. Ensures stats and required properties are properly defined.\n */\nexport function validateBundleStats(\n stats: unknown,\n artefactsPath: string,\n bundler: SupportedBundlers,\n): void {\n if (!stats) {\n throw new Error(`Bundle stats file is null or undefined: ${artefactsPath}`);\n }\n\n if (typeof stats !== 'object') {\n throw new TypeError(\n `Bundle stats file has invalid structure: ${artefactsPath}`,\n );\n }\n\n switch (bundler) {\n case 'esbuild':\n if (!('outputs' in stats)) {\n throw new Error(\n `Bundle stats file missing 'outputs' property for esbuild: ${artefactsPath}`,\n );\n }\n if (!stats.outputs) {\n throw new Error(\n `Bundle stats outputs is null or undefined in file: ${artefactsPath}`,\n );\n }\n break;\n case 'webpack':\n if (\n !('assets' in stats) ||\n !('chunks' in stats) ||\n !('modules' in stats)\n ) {\n throw new Error(\n `Bundle stats file missing required webpack properties (assets, chunks, modules): ${artefactsPath}`,\n );\n }\n break;\n case 'rsbuild':\n if (\n !('assets' in stats) ||\n !('chunks' in stats) ||\n !('modules' in stats)\n ) {\n throw new Error(\n `Bundle stats file missing required rsbuild properties (assets, chunks, modules): ${artefactsPath}`,\n );\n }\n break;\n case 'vite':\n if (!('assets' in stats) || !('chunks' in stats)) {\n throw new Error(\n `Bundle stats file missing required vite properties (assets, chunks): ${artefactsPath}`,\n );\n }\n break;\n case 'sonda':\n if (!('resources' in stats) || !('connections' in stats)) {\n throw new Error(\n `Bundle stats file missing required sonda properties (resources, connections): ${artefactsPath}`,\n );\n }\n break;\n default:\n throw new Error(`Unsupported bundler: ${bundler}`);\n }\n}\n\n/**\n * Returns the appropriate unify function based on bundler type. Provides bundler-specific stats processing.\n */\nexport function getUnifyFunction(\n bundler: SupportedBundlers,\n): (stats: any, options?: any) => UnifiedStats {\n switch (bundler) {\n case 'esbuild':\n return (stats: any, options: any = {}) =>\n unifyEsbuildStats(stats, options);\n case 'webpack':\n return (stats: any) => unifyWebpackStats(stats);\n case 'rsbuild':\n return (stats: any) => unifyRsbuildStats(stats);\n case 'vite':\n return (stats: any) => unifyViteStats(stats);\n case 'sonda':\n return (stats: any, options: any = {}) => unifySondaStats(stats, options);\n default:\n throw new Error(`Unsupported bundler: ${bundler}`);\n }\n}\n\n/**\n * Merges dependency tree configurations from audit and plugin levels.\n * Groups merge (global + local), pruning overwrites (local takes precedence).\n */\nexport function mergeDependencyTreeConfig(\n auditConfig: DependencyTreeConfig | undefined,\n pluginOptions: PluginDependencyTreeOptions | undefined,\n): DependencyTreeConfig | undefined {\n // Only hide if audit config explicitly disables\n if (auditConfig?.enabled === false) {\n return undefined;\n }\n\n // If global options exist, always show them (unless disabled above)\n if (pluginOptions) {\n return {\n // Groups logic: false = hide, array = overwrite global, undefined = use global\n groups: (() => {\n // Only hide if explicitly set to false\n if (auditConfig?.groups === false) {\n return [];\n }\n // If audit defines groups, use them (overwrite global)\n if (auditConfig?.groups !== undefined) {\n return auditConfig.groups as GroupingRule[];\n }\n // Otherwise, use global groups\n return pluginOptions?.groups ?? [];\n })(),\n // Pruning overwrites - local takes precedence over global\n pruning: {\n maxDepth: 2,\n maxChildren: 20,\n pathLength: 60,\n ...pluginOptions?.pruning,\n ...auditConfig?.pruning,\n },\n mode: auditConfig?.mode ?? 'onlyMatching',\n };\n }\n\n // If no global options but config exists, use config\n if (auditConfig) {\n return {\n // Groups fallback - use audit groups or empty array if false\n groups: auditConfig.groups === false ? [] : (auditConfig.groups ?? []),\n // Pruning fallback - use audit pruning with defaults\n pruning: {\n maxDepth: 2,\n maxChildren: 10,\n pathLength: 60,\n ...auditConfig?.pruning,\n },\n mode: auditConfig.mode ?? 'onlyMatching',\n };\n }\n\n return undefined;\n}\n\n/**\n * Merges selection configurations with hybrid strategy. Excludes merge for safety, includes overwrite for scope clarity.\n */\nexport function mergeSelectionConfig(\n auditConfig: SelectionConfig | undefined,\n pluginOptions?: PluginSelectionOptions,\n): SelectionConfig {\n return {\n // mode from audit config takes precedence\n mode: auditConfig?.mode == null ? 'bundle' : auditConfig.mode,\n\n // Include arrays overwrite - config takes precedence for scope clarity\n includeOutputs: auditConfig?.includeOutputs ?? [],\n includeInputs: auditConfig?.includeInputs ?? [],\n\n // Exclude arrays merge - merging exclusions is safe and expected\n excludeOutputs: [\n ...(pluginOptions?.excludeOutputs ?? []),\n ...(auditConfig?.excludeOutputs ?? []),\n ],\n excludeInputs: [\n ...(pluginOptions?.excludeInputs ?? []),\n ...(auditConfig?.excludeInputs ?? []),\n ],\n };\n}\n\n/**\n * Merges scoring configurations with hybrid strategy. Penalty blacklist merges to combine blocked patterns.\n */\nexport function mergeScoringConfig(\n auditConfig: BundleStatsConfig['scoring'] | undefined,\n pluginOptions: PluginScoringOptions | undefined,\n): BundleStatsConfig['scoring'] {\n if (auditConfig?.penalty === false) {\n return auditConfig;\n }\n\n if (!auditConfig) {\n return pluginOptions as BundleStatsConfig['scoring'];\n }\n\n const pluginPenalty = pluginOptions?.penalty;\n const normalizedPluginPenalty = pluginPenalty\n ? {\n ...pluginPenalty,\n artefactSize: pluginPenalty.artefactSize\n ? normalizeRange(pluginPenalty.artefactSize)\n : undefined,\n }\n : undefined;\n\n return {\n ...auditConfig,\n penalty: {\n ...DEFAULT_PENALTY,\n ...normalizedPluginPenalty,\n ...auditConfig?.penalty,\n // Blacklist merges - combine blocked patterns from both sources\n blacklist: [\n ...(normalizedPluginPenalty?.blacklist ?? []),\n ...(auditConfig?.penalty?.blacklist ?? []),\n ],\n },\n };\n}\n\n/**\n * Merges insights configurations with fallback strategy. Uses audit-level when defined, falls back to global when undefined, hides when false.\n */\nexport function mergeInsightsConfig(\n auditConfig: InsightsTableConfig | false | undefined,\n pluginOptions: InsightsTableConfig | false | undefined,\n): InsightsTableConfig | false | undefined {\n if (auditConfig === false) {\n return undefined;\n }\n\n // Insights override - audit-level completely replaces plugin-level when defined\n if (auditConfig !== undefined) {\n return auditConfig;\n }\n\n // Handle false plugin options\n if (pluginOptions === false) {\n return undefined;\n }\n\n return pluginOptions;\n}\n\n/**\n * Creates a bundle stats audit runner that processes bundler output and generates audit results.\n * Supports multiple bundlers (esbuild, webpack, rsbuild) with dynamic module loading.\n */\nexport async function bundleStatsRunner(\n opts: BundleStatsRunnerConfig,\n): Promise<() => Promise> {\n const {\n artifactsPaths,\n generateArtifactsCommand,\n bundleStatsConfigs,\n bundler,\n } = opts;\n\n return async () => {\n if (artifactsPaths && generateArtifactsCommand) {\n const { command, args } =\n typeof generateArtifactsCommand === 'string'\n ? { command: generateArtifactsCommand, args: undefined }\n : generateArtifactsCommand;\n try {\n await executeProcess({\n command,\n args,\n });\n } catch (error) {\n throw new Error(\n `Failed to generate artefacts for plugin bundle-stats. command: ${command} args: ${args} error: ${error}`,\n );\n }\n }\n\n if (Array.isArray(artifactsPaths)) {\n throw new TypeError(\n 'The bundle stats plugin does not support multiple artifact paths. Request feature on GitHub.',\n );\n }\n\n const stats = await readJsonFile(artifactsPaths);\n // @TODO implement zod schema\n validateBundleStats(stats, artifactsPaths, bundler);\n\n const unifyBundlerStats = getUnifyFunction(bundler);\n const unifiedBundleStats = unifyBundlerStats(stats, {});\n\n return generateAuditOutputs(unifiedBundleStats, bundleStatsConfigs);\n };\n}\n\nexport function mergeAuditConfigs(\n configs: BundleStatsConfig[],\n options: {\n dependencyTree?: PluginDependencyTreeOptions;\n selection?: PluginSelectionOptions;\n scoring?: PluginScoringOptions;\n insightsTable?: PluginInsightsTableOptions;\n },\n): BundleStatsConfig[] {\n return configs.map(config => {\n const { insightsTable: configInsights, ...configWithoutInsights } = config;\n\n return {\n ...configWithoutInsights,\n dependencyTree: mergeDependencyTreeConfig(\n config.dependencyTree,\n options.dependencyTree,\n ),\n selection: mergeSelectionConfig(config.selection, options.selection),\n scoring: mergeScoringConfig(config.scoring, options.scoring),\n ...(configInsights === false\n ? {}\n : {\n insightsTable: mergeInsightsConfig(\n configInsights,\n options.insightsTable,\n ),\n }),\n };\n });\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.unit.test.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'vi' is defined but never used.", + "line": 1, + "column": 32, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 1, + "endColumn": 34 + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it, vi } from 'vitest';\nimport type { PluginSelectionOptions } from '../types.js';\nimport type { PenaltyConfig } from './audits/scoring.js';\nimport type { SelectionConfig } from './audits/selection.js';\nimport {\n mergeAuditConfigs,\n mergeDependencyTreeConfig,\n mergeInsightsConfig,\n mergeScoringConfig,\n mergeSelectionConfig,\n} from './bundle-stats-runner.js';\nimport type { GroupingRule } from './types.js';\n\nconst testScoring = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: { warningWeight: 0.1, errorWeight: 0.2 } as PenaltyConfig,\n};\nconst emptySelection: SelectionConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n};\n\ndescribe('mergeDependencyTreeConfig', () => {\n it('should return undefined when both global and config are undefined', () => {\n expect(mergeDependencyTreeConfig(undefined, undefined)).toBeUndefined();\n });\n\n it('should use config when global is undefined', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n const result = mergeDependencyTreeConfig(auditConfig, undefined);\n\n expect(result?.groups).toHaveLength(1);\n expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject(\n { includeInputs: ['**/*.ts'] },\n );\n });\n\n it('should return undefined when config.enabled is false', () => {\n const auditConfig = { enabled: false, groups: [] };\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n expect(\n mergeDependencyTreeConfig(auditConfig, pluginOptions),\n ).toBeUndefined();\n });\n\n it('should merge when global options provided and config undefined', () => {\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n const result = mergeDependencyTreeConfig(undefined, pluginOptions);\n\n expect(result?.groups).toHaveLength(1);\n expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject(\n { includeInputs: ['**/*.js'] },\n );\n });\n\n it('should merge when both global and config options provided', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n const result = mergeDependencyTreeConfig(auditConfig, pluginOptions);\n\n expect(result?.groups).toHaveLength(1);\n expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject(\n { includeInputs: ['**/*.ts'] },\n );\n });\n\n it('should overwrite pruning options (config takes precedence)', () => {\n const auditConfig = { pruning: { maxDepth: 5 } };\n const pluginOptions = { pruning: { maxDepth: 3 } };\n const result = mergeDependencyTreeConfig(auditConfig, pluginOptions);\n\n expect(result?.pruning?.maxDepth).toBe(5);\n });\n\n it('should provide DEFAULT pruning options when no options provided', () => {\n const auditConfig = { groups: [] };\n const result = mergeDependencyTreeConfig(auditConfig, undefined);\n\n expect(result?.pruning).toBeDefined();\n });\n});\n\ndescribe('mergeSelectionConfig', () => {\n it('should merge plugin and audit selection patterns', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: ['main.js'],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: [],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result).toMatchObject({\n includeOutputs: ['main.js'],\n excludeOutputs: ['*.map'],\n });\n });\n\n it('should handle empty plugin options', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: [],\n excludeOutputs: ['dev.js'],\n includeInputs: [],\n excludeInputs: [],\n };\n const result = mergeSelectionConfig(auditConfig);\n\n expect(result).toMatchObject({\n excludeOutputs: ['dev.js'],\n });\n });\n\n it('should merge multiple arrays correctly', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: ['main.js'],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: ['temp.js'],\n };\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: ['test/**'],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result).toMatchObject({\n includeOutputs: ['main.js'],\n excludeOutputs: ['*.map'],\n excludeInputs: ['test/**', 'temp.js'],\n });\n });\n\n it('should handle undefined config selection', () => {\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: [],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(undefined, pluginOptions);\n\n expect(result).toMatchObject({\n includeOutputs: [],\n excludeOutputs: ['*.map'],\n });\n });\n\n it('should handle empty exclude arrays', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n const pluginOptions = {\n excludeOutputs: [],\n excludeInputs: [],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result).toMatchObject(emptySelection);\n });\n\n it('should merge exclude patterns correctly', () => {\n const auditConfig = emptySelection;\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: ['*.test.js'],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result.excludeOutputs).toStrictEqual(['*.map']);\n expect(result.excludeInputs).toStrictEqual(['*.test.js']);\n });\n});\n\ndescribe('mergeScoringConfig', () => {\n it('should return config when config.penalty is false', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: false as const,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n } as PenaltyConfig,\n };\n\n expect(mergeScoringConfig(auditConfig, pluginOptions)).toStrictEqual({\n mode: 'onlyMatching',\n totalSize: [0, 1000],\n penalty: false,\n });\n });\n\n it('should return options when config is undefined', () => {\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n } as PenaltyConfig,\n };\n\n expect(mergeScoringConfig(undefined, pluginOptions)).toStrictEqual(\n pluginOptions,\n );\n });\n\n it('should merge when both config and options provided', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 3,\n } as PenaltyConfig,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n threshold: 100,\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, pluginOptions);\n\n expect(result?.penalty).toMatchObject({ factor: 3, threshold: 100 });\n });\n\n it('should merge penalty blacklists from both sources', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n blacklist: ['config-pattern'],\n } as PenaltyConfig,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n blacklist: ['global-pattern'],\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, pluginOptions);\n\n expect((result?.penalty as any)?.blacklist).toStrictEqual([\n 'global-pattern',\n 'config-pattern',\n ]);\n });\n\n it('should overwrite other penalty properties (config takes precedence)', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 3,\n threshold: 500,\n } as PenaltyConfig,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n threshold: 100,\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, pluginOptions);\n\n expect((result?.penalty as any)?.factor).toBe(3);\n expect((result?.penalty as any)?.threshold).toBe(500);\n });\n\n it('should handle undefined global scoring', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, undefined);\n\n expect((result?.penalty as any)?.factor).toBe(2);\n });\n});\n\ndescribe('mergeInsightsConfig', () => {\n it('should return undefined when config is false', () => {\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n expect(mergeInsightsConfig(false, pluginOptions)).toBeUndefined();\n });\n\n it('should merge arrays when both global and config provided', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n // Function overrides (doesn't merge) - auditConfig takes precedence\n const result = mergeInsightsConfig(auditConfig, pluginOptions);\n expect(\n result && typeof result === 'object' && 'groups' in result\n ? result.groups\n : [],\n ).toHaveLength(1);\n expect(\n result && typeof result === 'object' && 'groups' in result\n ? result.groups?.[0]\n : {},\n ).toMatchObject({ includeInputs: ['**/*.ts'] });\n });\n\n it('should use global when config is undefined', () => {\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n expect(mergeInsightsConfig(undefined, pluginOptions)).toStrictEqual({\n groups: [{ includeInputs: ['**/*.js'], title: 'JavaScript' }],\n });\n });\n\n it('should use config when global is undefined', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n\n expect(mergeInsightsConfig(auditConfig, undefined)).toStrictEqual({\n groups: [{ includeInputs: ['**/*.ts'], title: 'TypeScript' }],\n });\n });\n\n it('should return undefined when both are undefined', () => {\n expect(mergeInsightsConfig(undefined, undefined)).toBeUndefined();\n });\n\n it('should handle false in both global and config', () => {\n expect(mergeInsightsConfig(false, false)).toBeUndefined();\n });\n});\n\ndescribe('mergeAuditConfigs', () => {\n it('should return empty array when given empty configs', () => {\n expect(mergeAuditConfigs([], {})).toStrictEqual([]);\n });\n\n it('should map over multiple configs correctly', () => {\n const configs = [\n {\n slug: 'audit-1',\n title: 'First',\n selection: emptySelection,\n scoring: testScoring,\n },\n {\n slug: 'audit-2',\n title: 'Second',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result).toHaveLength(2);\n expect(result[0]?.slug).toBe('audit-1');\n expect(result[1]?.slug).toBe('audit-2');\n });\n\n it('should set selection property correctly', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const options = {\n selection: { excludeOutputs: ['*.test.js'] } as PluginSelectionOptions,\n };\n const result = mergeAuditConfigs(configs, options);\n\n expect(result[0]?.selection).toBeDefined();\n expect(result[0]?.selection.excludeOutputs).toStrictEqual(['*.test.js']);\n });\n\n it('should set scoring property correctly', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const options = {\n scoring: {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n } satisfies PenaltyConfig,\n },\n };\n const result = mergeAuditConfigs(configs, options);\n\n expect(result[0]?.scoring).toBeDefined();\n });\n\n it('should include insightsTable when config.insightsTable is not false', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n insightsTable: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result[0]).toHaveProperty('insightsTable');\n expect(result[0]?.insightsTable).toHaveLength(1);\n });\n\n it('should exclude insightsTable when config.insightsTable is false', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n insightsTable: false,\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result[0]).not.toHaveProperty('insightsTable');\n });\n\n it('should handle empty options object', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result[0]).toMatchObject({\n slug: 'test',\n selection: {\n mode: 'matchingOnly',\n includeOutputs: [],\n includeInputs: [],\n excludeOutputs: [],\n excludeInputs: [],\n },\n });\n expect((result[0] as any).artefactTree).toBeUndefined();\n });\n\n it('should handle partial options object', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const options = {\n scoring: {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 1.5,\n } as PenaltyConfig,\n },\n };\n const result = mergeAuditConfigs(configs, options);\n\n expect(result[0]).toMatchObject({\n slug: 'test',\n scoring: expect.any(Object),\n });\n expect((result[0] as any).artefactTree).toBeUndefined();\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/constants.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/types.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unified-stats.types.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.ts", + "messages": [ + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'unifyBundlerStats' has too many lines (68). Maximum allowed is 50.", + "line": 56, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 140, + "endColumn": 2 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 65, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 137, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 66, + "column": 24, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 66, + "endColumn": 34 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 92, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 92, + "endColumn": 44 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 95, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 108, + "endColumn": 11 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 103, + "column": 13, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 103, + "endColumn": 50 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying properties of existing object not allowed.", + "line": 110, + "column": 5, + "nodeType": "CallExpression", + "messageId": "object", + "endLine": 110, + "endColumn": 50 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 117, + "column": 9, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 126, + "endColumn": 10 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 118, + "column": 29, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 118, + "endColumn": 38 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", + "line": 121, + "column": 11, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 125, + "endColumn": 12 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 122, + "column": 13, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 124, + "endColumn": 14 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 128, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 128, + "endColumn": 38 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 130, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 130, + "endColumn": 34 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 133, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 133, + "endColumn": 32 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 136, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 136, + "endColumn": 39 + } + ], + "suppressedMessages": [], + "errorCount": 11, + "fatalErrorCount": 0, + "warningCount": 4, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { minimatch } from 'minimatch';\nimport type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type EsBuildImportKind = 'import-statement' | 'dynamic-import';\n\nexport type EsBuildInputImport = {\n path: string;\n kind: EsBuildImportKind;\n original: string;\n};\n\nexport type EsBuildOutputImport = {\n path: string;\n kind: EsBuildImportKind;\n external?: boolean;\n original?: string;\n};\n\nexport type EsBuildInput = {\n bytes: number;\n imports: EsBuildInputImport[];\n format?: string;\n};\n\nexport type EsBuildOutput = {\n bytes: number;\n inputs?: Record;\n entryPoint?: string;\n imports?: EsBuildOutputImport[];\n exports?: string[];\n};\n\nexport type EsBuildCoreStats = {\n outputs: Record;\n inputs: Record;\n};\n\nexport type EsBuildUnifyOptions = {\n excludeOutputs?: string[];\n};\n\n/**\n * Checks if path matches any exclude pattern. Filters unwanted files from bundle stats.\n */\nfunction shouldExcludeOutput(\n outputPath: string,\n excludePatterns: string[],\n): boolean {\n return excludePatterns.some(pattern => minimatch(outputPath, pattern));\n}\n\nexport function unifyBundlerStats(\n stats: EsBuildCoreStats,\n options: EsBuildUnifyOptions,\n): UnifiedStats {\n const { excludeOutputs = ['**/*.map', '**/*.d.ts'] } = options;\n\n const outputKeys = Object.keys(stats.outputs);\n const result: UnifiedStats = {};\n\n for (const outputKey of outputKeys) {\n const outputName = outputKey!;\n const outputInfo = stats.outputs[outputName];\n if (!outputInfo) {\n continue;\n }\n\n // Skip outputs that match exclude patterns\n if (shouldExcludeOutput(outputName, excludeOutputs)) {\n continue;\n }\n\n const {\n bytes,\n entryPoint,\n imports,\n exports,\n inputs: outputInputs,\n ...additionalProps\n } = outputInfo;\n\n const unifiedOutput: UnifiedStatsBundle = {\n path: outputName,\n bytes,\n };\n\n if (entryPoint !== undefined) {\n unifiedOutput.entryPoint = entryPoint;\n }\n\n unifiedOutput.imports = imports\n ? imports.map(imp => {\n const unifiedImport: UnifiedStatsImport = {\n path: imp.path,\n kind: imp.kind,\n };\n\n if ('original' in imp && typeof imp.original === 'string') {\n unifiedImport.original = imp.original;\n }\n\n return unifiedImport;\n })\n : [];\n\n Object.assign(unifiedOutput, additionalProps);\n\n if (outputInputs) {\n const inputKeys = Object.keys(outputInputs);\n if (inputKeys.length > 0) {\n const inputs: Record = {};\n\n for (const inputKey of inputKeys) {\n const inputPath = inputKey!;\n const outputInputInfo = outputInputs[inputPath];\n\n if (outputInputInfo?.bytesInOutput !== undefined) {\n inputs[inputPath] = {\n bytes: outputInputInfo.bytesInOutput,\n };\n }\n }\n\n unifiedOutput.inputs = inputs;\n } else {\n unifiedOutput.inputs = {};\n }\n } else {\n unifiedOutput.inputs = {};\n }\n\n result[outputName] = unifiedOutput;\n }\n\n return result;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.unit.test.ts", + "messages": [ + { + "ruleId": "no-duplicate-imports", + "severity": 1, + "message": "'./unify.esbuild.js' import is duplicated.", + "line": 3, + "column": 1, + "nodeType": "ImportDeclaration", + "messageId": "import", + "endLine": 3, + "endColumn": 60 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 1, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it } from 'vitest';\nimport { unifyBundlerStats } from './unify.esbuild.js';\nimport type { EsBuildCoreStats } from './unify.esbuild.js';\n\ndescribe('unifyBundlerStats', () => {\n it('should only consider outputs and provide default values', () => {\n const esbuildStats: EsBuildCoreStats = {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n },\n },\n };\n expect(unifyBundlerStats(esbuildStats, {})).toStrictEqual({\n 'dist/index.js': {\n path: 'dist/index.js',\n bytes: 100,\n imports: [],\n inputs: {},\n },\n });\n });\n\n it('should parse inputs correctly', () => {\n expect(\n unifyBundlerStats(\n {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n inputs: {\n 'src/index.ts': {\n bytesInOutput: 100,\n },\n },\n },\n },\n },\n {},\n ),\n ).toStrictEqual({\n 'dist/index.js': expect.objectContaining({\n inputs: {\n 'src/index.ts': {\n bytes: 100,\n },\n },\n }),\n });\n });\n\n it('should parse imports correctly', () => {\n expect(\n unifyBundlerStats(\n {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n },\n },\n },\n {},\n ),\n ).toStrictEqual({\n 'dist/index.js': expect.objectContaining({\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n }),\n });\n });\n\n it('should preserve original import paths when present', () => {\n expect(\n unifyBundlerStats(\n {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n imports: [\n {\n path: 'node_modules/rxjs/dist/esm/internal/util/isFunction.js',\n kind: 'import-statement',\n original: './util/isFunction',\n },\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n },\n },\n },\n {},\n ),\n ).toStrictEqual({\n 'dist/index.js': expect.objectContaining({\n imports: [\n {\n path: 'node_modules/rxjs/dist/esm/internal/util/isFunction.js',\n kind: 'import-statement',\n original: './util/isFunction',\n },\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n }),\n });\n });\n\n it('should unify esbuild stats into unified stats structure', () => {\n const esbuildStats: EsBuildCoreStats = {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n {\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n kind: 'dynamic-import',\n },\n ],\n exports: ['default', 'indexOnlyFunction'],\n entryPoint: 'src/index.ts',\n inputs: {\n 'src/index.ts': {\n bytesInOutput: 350,\n },\n },\n bytes: 496,\n },\n 'dist/bin.js': {\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n exports: [],\n entryPoint: 'src/bin.ts',\n inputs: {\n 'src/bin.ts': {\n bytesInOutput: 366,\n },\n },\n bytes: 479,\n },\n 'dist/chunks/chunk-WIJM4GGD.js': {\n imports: [],\n exports: ['calculate', 'externalFunction'],\n inputs: {\n 'src/lib/utils/format.ts': {\n bytesInOutput: 269,\n },\n 'src/lib/feature-1.ts': {\n bytesInOutput: 269,\n },\n 'src/lib/utils/math.ts': {\n bytesInOutput: 145,\n },\n },\n bytes: 806,\n },\n 'dist/chunks/feature-2-X2YVDBQK.js': {\n imports: [],\n exports: ['chart'],\n entryPoint: 'src/lib/feature-2.ts',\n inputs: {\n 'src/lib/feature-2.ts': {\n bytesInOutput: 38,\n },\n },\n bytes: 82,\n },\n },\n };\n\n expect(unifyBundlerStats(esbuildStats, {})).toStrictEqual({\n 'dist/bin.js': {\n bytes: 479,\n entryPoint: 'src/bin.ts',\n imports: [\n {\n kind: 'import-statement',\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n },\n ],\n inputs: {\n 'src/bin.ts': {\n bytes: 366,\n },\n },\n path: 'dist/bin.js',\n },\n 'dist/chunks/chunk-WIJM4GGD.js': {\n bytes: 806,\n imports: [],\n inputs: {\n 'src/lib/feature-1.ts': {\n bytes: 269,\n },\n 'src/lib/utils/format.ts': {\n bytes: 269,\n },\n 'src/lib/utils/math.ts': {\n bytes: 145,\n },\n },\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n },\n 'dist/chunks/feature-2-X2YVDBQK.js': {\n bytes: 82,\n entryPoint: 'src/lib/feature-2.ts',\n imports: [],\n inputs: {\n 'src/lib/feature-2.ts': {\n bytes: 38,\n },\n },\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n },\n 'dist/index.js': {\n bytes: 496,\n entryPoint: 'src/index.ts',\n imports: [\n {\n kind: 'import-statement',\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n },\n {\n kind: 'dynamic-import',\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n },\n ],\n inputs: {\n 'src/index.ts': {\n bytes: 350,\n },\n },\n path: 'dist/index.js',\n },\n });\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'UnifiedStatsImport' is defined but never used.", + "line": 4, + "column": 3, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 4, + "endColumn": 21 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'unifyBundlerStats' has too many lines (92). Maximum allowed is 50.", + "line": 139, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 242, + "endColumn": 2 + }, + { + "ruleId": "complexity", + "severity": 1, + "message": "Function 'unifyBundlerStats' has a complexity of 23. Maximum allowed is 20.", + "line": 139, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "complex", + "endLine": 242, + "endColumn": 2 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 143, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 145, + "endColumn": 4 + }, + { + "ruleId": "sonarjs/no-unused-collection", + "severity": 2, + "message": "Either use this collection's contents or remove the collection.", + "line": 147, + "column": 9, + "nodeType": "Identifier", + "messageId": "unusedCollection", + "endLine": 147, + "endColumn": 19 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 148, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 150, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 152, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 239, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 164, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 183, + "endColumn": 6 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'entryName' is assigned a value but never used. Allowed unused elements of array destructuring must match /^_/u.", + "line": 164, + "column": 17, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 164, + "endColumn": 26 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 169, + "column": 9, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 180, + "endColumn": 10 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", + "line": 171, + "column": 11, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 179, + "endColumn": 12 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", + "line": 175, + "column": 13, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 178, + "endColumn": 14 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 176, + "column": 15, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 176, + "endColumn": 58 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 185, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 224, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 191, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 223, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 197, + "column": 11, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 199, + "endColumn": 12 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 202, + "column": 9, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 222, + "endColumn": 10 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", + "line": 203, + "column": 11, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 221, + "endColumn": 12 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", + "line": 204, + "column": 13, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 210, + "endColumn": 14 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 205, + "column": 15, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 209, + "endColumn": 17 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 216, + "column": 13, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 220, + "endColumn": 15 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 235, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 235, + "endColumn": 44 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 238, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 238, + "endColumn": 39 + } + ], + "suppressedMessages": [], + "errorCount": 9, + "fatalErrorCount": 0, + "warningCount": 14, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type RsbuildImportKind = 'import-statement' | 'dynamic-import';\n\nexport type RsbuildReason = {\n moduleIdentifier: string | null;\n module: string | null;\n moduleName: string | null;\n type: string;\n userRequest: string;\n loc: string;\n active: boolean;\n moduleId: string | null;\n resolvedModuleId: string | null;\n};\n\nexport type RsbuildAsset = {\n type: string;\n name: string;\n size: number;\n emitted: boolean;\n cached: boolean;\n chunkNames: string[];\n chunkIdHints: string[];\n chunks: string[];\n auxiliaryChunks: string[];\n};\n\nexport type RsbuildModule = {\n type: string;\n moduleType: string;\n size: number;\n sizes: Record;\n built: boolean;\n codeGenerated: boolean;\n buildTimeExecuted: boolean;\n cached: boolean;\n identifier: string;\n name: string;\n nameForCondition?: string;\n index: number;\n preOrderIndex: number;\n index2: number;\n postOrderIndex: number;\n cacheable: boolean;\n optional: boolean;\n orphan: boolean;\n dependent?: boolean;\n issuer?: string | null;\n issuerName?: string | null;\n issuerPath?: {\n identifier: string;\n name: string;\n id: string;\n }[];\n failed: boolean;\n errors: number;\n warnings: number;\n id: string;\n issuerId?: string;\n chunks: string[];\n assets: string[];\n reasons: RsbuildReason[];\n usedExports: string[] | null;\n providedExports?: string[];\n optimizationBailout: string[];\n depth: number;\n};\n\nexport type RsbuildChunk = {\n type: string;\n rendered: boolean;\n initial: boolean;\n entry: boolean;\n reason?: string;\n size: number;\n sizes: Record;\n names: string[];\n idHints: string[];\n runtime: string[];\n files: string[];\n auxiliaryFiles: string[];\n hash: string;\n childrenByOrder: Record;\n id: string;\n siblings: string[];\n parents: string[];\n children: string[];\n modules: RsbuildModule[];\n origins: {\n module: string;\n moduleIdentifier: string;\n moduleName: string;\n loc: string;\n request: string;\n moduleId: string;\n }[];\n};\n\nexport type RsbuildEntrypoint = {\n name: string;\n chunks: string[];\n assets: { name: string; size: number }[];\n filteredAssets: number;\n assetsSize: number;\n auxiliaryAssets: { name: string; size: number }[];\n auxiliaryAssetsSize: number;\n children: Record;\n childAssets: Record;\n isOverSizeLimit: boolean;\n};\n\nexport type RsbuildCoreStats = {\n name: string;\n hash: string;\n version: string;\n rspackVersion: string;\n time: number;\n builtAt: number;\n publicPath: string;\n outputPath: string;\n assetsByChunkName: Record;\n assets: RsbuildAsset[];\n chunks: RsbuildChunk[];\n modules: RsbuildModule[];\n entrypoints: Record;\n namedChunkGroups: Record;\n errors: unknown[];\n errorsCount: number;\n warnings: unknown[];\n warningsCount: number;\n children: unknown[];\n};\n\nexport function unifyBundlerStats(stats: RsbuildCoreStats): UnifiedStats {\n const result: UnifiedStats = {};\n\n const chunksMap = new Map();\n for (const chunk of stats.chunks) {\n chunksMap.set(chunk.id, chunk);\n }\n\n const modulesMap = new Map();\n for (const module of stats.modules) {\n modulesMap.set(module.identifier, module);\n }\n\n for (const asset of stats.assets) {\n if (!asset.name.endsWith('.js')) {\n continue;\n }\n\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.size,\n imports: [],\n inputs: {},\n };\n\n for (const [entryName, entrypoint] of Object.entries(stats.entrypoints)) {\n if (\n entrypoint.assets.some(entryAsset => entryAsset.name === asset.name)\n ) {\n const entryChunks = entrypoint.chunks;\n for (const chunkId of entryChunks) {\n const chunk = chunksMap.get(chunkId);\n if (chunk?.entry) {\n const entryModule = chunk.modules.find(module =>\n module.reasons.some(reason => reason.type === 'entry'),\n );\n if (entryModule) {\n unifiedOutput.entryPoint = entryModule.name;\n break;\n }\n }\n }\n break;\n }\n }\n\n for (const chunkId of asset.chunks) {\n const chunk = chunksMap.get(chunkId);\n if (!chunk) {\n continue;\n }\n\n for (const module of chunk.modules) {\n if (module.moduleType === 'runtime') {\n continue;\n }\n\n if (unifiedOutput.inputs) {\n unifiedOutput.inputs[module.name] = {\n bytes: module.size,\n };\n }\n\n for (const reason of module.reasons) {\n if (reason.type === 'import()') {\n if (unifiedOutput.imports) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'dynamic-import',\n original: reason.userRequest,\n });\n }\n } else if (\n (reason.type === 'esm import' ||\n reason.type === 'esm import specifier') &&\n unifiedOutput.imports\n ) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'import-statement',\n original: reason.userRequest,\n });\n }\n }\n }\n }\n\n if (unifiedOutput.imports) {\n const uniqueImports = unifiedOutput.imports.filter(\n (importItem, index, self) =>\n index ===\n self.findIndex(\n item =>\n item.path === importItem.path && item.kind === importItem.kind,\n ),\n );\n unifiedOutput.imports = uniqueImports;\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.unit.test.ts", + "messages": [ + { + "ruleId": "no-duplicate-imports", + "severity": 1, + "message": "'./unify.rsbuild.js' import is duplicated.", + "line": 3, + "column": 1, + "nodeType": "ImportDeclaration", + "messageId": "import", + "endLine": 3, + "endColumn": 60 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 1, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it } from 'vitest';\nimport { unifyBundlerStats } from './unify.rsbuild.js';\nimport type { RsbuildCoreStats } from './unify.rsbuild.js';\n\ndescribe('unifyBundlerStats', () => {\n it('should transform realistic rsbuild stats with multiple assets, chunks, and complex module dependencies', () => {\n const rsbuildStats: RsbuildCoreStats = {\n name: 'web',\n hash: 'f7f35d6bcb429212',\n version: '5.75.0',\n rspackVersion: '1.4.6',\n time: 18,\n builtAt: 1_752_462_348_764,\n publicPath: '/',\n outputPath: '/dist/rsbuild',\n assetsByChunkName: {\n index: ['static/js/index.js'],\n },\n assets: [\n {\n type: 'asset',\n name: 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js',\n size: 79_545,\n emitted: true,\n cached: false,\n chunkNames: [],\n chunkIdHints: ['vendors'],\n chunks: ['vendors-node_modules_minimatch_dist_esm_index_js'],\n auxiliaryChunks: [],\n },\n {\n type: 'asset',\n name: 'static/js/index.js',\n size: 38_142,\n emitted: true,\n cached: false,\n chunkNames: ['index'],\n chunkIdHints: [],\n chunks: ['index'],\n auxiliaryChunks: [],\n },\n {\n type: 'asset',\n name: 'static/js/async/src_lib_feature-2_ts.js',\n size: 708,\n emitted: true,\n cached: false,\n chunkNames: [],\n chunkIdHints: [],\n chunks: ['src_lib_feature-2_ts'],\n auxiliaryChunks: [],\n },\n {\n type: 'asset',\n name: 'index.html',\n size: 242,\n emitted: true,\n cached: false,\n chunkNames: [],\n chunkIdHints: [],\n chunks: [],\n auxiliaryChunks: [],\n },\n ],\n chunks: [\n {\n type: 'chunk',\n rendered: true,\n initial: true,\n entry: true,\n size: 1384,\n sizes: {\n javascript: 1384,\n runtime: 32_421,\n },\n names: ['index'],\n idHints: [],\n runtime: ['index'],\n files: ['static/js/index.js'],\n auxiliaryFiles: ['static/js/index.js.map'],\n hash: '9529fef35c1c4eed',\n childrenByOrder: {},\n id: 'index',\n siblings: [],\n parents: [],\n children: [\n 'src_lib_feature-2_ts',\n 'vendors-node_modules_minimatch_dist_esm_index_js',\n ],\n modules: [\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 461,\n sizes: {\n javascript: 461,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n name: './src/index.ts',\n nameForCondition: '/src/index.ts',\n index: 0,\n preOrderIndex: 0,\n index2: 3,\n postOrderIndex: 3,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: false,\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/index.ts',\n chunks: ['index'],\n assets: [],\n reasons: [\n {\n moduleIdentifier: null,\n module: null,\n moduleName: null,\n type: 'entry',\n userRequest: './src/index.ts',\n loc: 'index',\n active: true,\n moduleId: null,\n resolvedModuleId: null,\n },\n ],\n usedExports: null,\n providedExports: ['default', 'indexOnlyFunction'],\n optimizationBailout: [],\n depth: 0,\n },\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 376,\n sizes: {\n javascript: 376,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-1.ts',\n name: './src/lib/feature-1.ts',\n nameForCondition: '/src/lib/feature-1.ts',\n index: 1,\n preOrderIndex: 1,\n index2: 1,\n postOrderIndex: 1,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: true,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n issuerName: './src/index.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/lib/feature-1.ts',\n issuerId: './src/index.ts',\n chunks: ['index'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import',\n userRequest: './lib/feature-1',\n loc: '1:0-51',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import specifier',\n userRequest: './lib/feature-1',\n loc: '6:79-95',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n ],\n usedExports: null,\n providedExports: ['default', 'externalFunction'],\n optimizationBailout: [],\n depth: 1,\n },\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 172,\n sizes: {\n javascript: 172,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/utils/math.ts',\n name: './src/lib/utils/math.ts',\n nameForCondition: '/src/lib/utils/math.ts',\n index: 3,\n preOrderIndex: 3,\n index2: 2,\n postOrderIndex: 2,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: true,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n issuerName: './src/index.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/lib/utils/math.ts',\n issuerId: './src/index.ts',\n chunks: ['index'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import',\n userRequest: './lib/utils/math',\n loc: '2:0-45',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import specifier',\n userRequest: './lib/utils/math',\n loc: '6:30-39',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n ],\n usedExports: null,\n providedExports: ['add', 'calculate', 'multiply'],\n optimizationBailout: [],\n depth: 1,\n },\n ],\n origins: [\n {\n module: '',\n moduleIdentifier: '',\n moduleName: '',\n loc: 'index',\n request: './src/index.ts',\n moduleId: 'index',\n },\n ],\n },\n {\n type: 'chunk',\n rendered: true,\n initial: false,\n entry: false,\n size: 147,\n sizes: {\n javascript: 147,\n },\n names: [],\n idHints: [],\n runtime: ['index'],\n files: ['static/js/async/src_lib_feature-2_ts.js'],\n auxiliaryFiles: ['static/js/async/src_lib_feature-2_ts.js.map'],\n hash: '30813a925289ba1f',\n childrenByOrder: {},\n id: 'src_lib_feature-2_ts',\n siblings: ['vendors-node_modules_minimatch_dist_esm_index_js'],\n parents: ['index'],\n children: [],\n modules: [\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 147,\n sizes: {\n javascript: 147,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n name: './src/lib/feature-2.ts',\n nameForCondition: '/src/lib/feature-2.ts',\n index: 4,\n preOrderIndex: 4,\n index2: 12,\n postOrderIndex: 12,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: false,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n issuerName: './src/index.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/lib/feature-2.ts',\n issuerId: './src/index.ts',\n chunks: ['src_lib_feature-2_ts'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'import()',\n userRequest: './lib/feature-2',\n loc: '4:28-53',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n ],\n usedExports: null,\n providedExports: ['chart'],\n optimizationBailout: [],\n depth: 1,\n },\n ],\n origins: [\n {\n module:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleName: './src/index.ts',\n loc: '4:28-53',\n request: './lib/feature-2',\n moduleId: './src/index.ts',\n },\n ],\n },\n {\n type: 'chunk',\n rendered: true,\n initial: false,\n entry: false,\n reason: 'split chunk (cache group: defaultVendors)',\n size: 75_559,\n sizes: {\n javascript: 75_559,\n },\n names: [],\n idHints: ['vendors'],\n runtime: ['index'],\n files: [\n 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js',\n ],\n auxiliaryFiles: [\n 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js.map',\n ],\n hash: '204484fe4072555f',\n childrenByOrder: {},\n id: 'vendors-node_modules_minimatch_dist_esm_index_js',\n siblings: ['src_lib_feature-2_ts'],\n parents: ['index'],\n children: [],\n modules: [\n {\n type: 'module',\n moduleType: 'javascript/esm',\n size: 39_098,\n sizes: {\n javascript: 39_098,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'javascript/esm|/node_modules/minimatch/dist/esm/index.js',\n name: '../../../../../node_modules/minimatch/dist/esm/index.js',\n nameForCondition: '/node_modules/minimatch/dist/esm/index.js',\n index: 5,\n preOrderIndex: 5,\n index2: 11,\n postOrderIndex: 11,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: false,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n issuerName: './src/lib/feature-2.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: '../../../../../node_modules/minimatch/dist/esm/index.js',\n issuerId: './src/lib/feature-2.ts',\n chunks: ['vendors-node_modules_minimatch_dist_esm_index_js'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n module: './src/lib/feature-2.ts',\n moduleName: './src/lib/feature-2.ts',\n type: 'esm import',\n userRequest: 'minimatch',\n loc: '1:0-38',\n active: true,\n moduleId: './src/lib/feature-2.ts',\n resolvedModuleId: './src/lib/feature-2.ts',\n },\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n module: './src/lib/feature-2.ts',\n moduleName: './src/lib/feature-2.ts',\n type: 'esm import specifier',\n userRequest: 'minimatch',\n loc: '3:11-20',\n active: true,\n moduleId: './src/lib/feature-2.ts',\n resolvedModuleId: './src/lib/feature-2.ts',\n },\n ],\n usedExports: null,\n providedExports: [\n 'AST',\n 'GLOBSTAR',\n 'Minimatch',\n 'braceExpand',\n 'defaults',\n 'escape',\n 'filter',\n 'makeRe',\n 'match',\n 'minimatch',\n 'sep',\n 'unescape',\n ],\n optimizationBailout: [],\n depth: 2,\n },\n ],\n origins: [\n {\n module:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleName: './src/index.ts',\n loc: '4:28-53',\n request: './lib/feature-2',\n moduleId: './src/index.ts',\n },\n ],\n },\n ],\n modules: [],\n entrypoints: {\n index: {\n name: 'index',\n chunks: ['index'],\n assets: [{ name: 'static/js/index.js', size: 38_142 }],\n filteredAssets: 0,\n assetsSize: 38_142,\n auxiliaryAssets: [{ name: 'static/js/index.js.map', size: 45_982 }],\n auxiliaryAssetsSize: 45_982,\n children: {},\n childAssets: {},\n isOverSizeLimit: false,\n },\n },\n namedChunkGroups: {\n index: {\n name: 'index',\n chunks: ['index'],\n assets: [{ name: 'static/js/index.js', size: 38_142 }],\n filteredAssets: 0,\n assetsSize: 38_142,\n auxiliaryAssets: [{ name: 'static/js/index.js.map', size: 45_982 }],\n auxiliaryAssetsSize: 45_982,\n children: {},\n childAssets: {},\n isOverSizeLimit: false,\n },\n },\n errors: [],\n errorsCount: 0,\n warnings: [],\n warningsCount: 0,\n children: [],\n };\n\n const result = unifyBundlerStats(rsbuildStats);\n\n expect(result).toEqual({\n 'static/js/index.js': {\n path: 'static/js/index.js',\n bytes: 38_142,\n imports: [\n {\n path: './lib/feature-1',\n kind: 'import-statement',\n original: './lib/feature-1',\n },\n {\n path: './lib/utils/math',\n kind: 'import-statement',\n original: './lib/utils/math',\n },\n ],\n inputs: {\n './src/index.ts': {\n bytes: 461,\n },\n './src/lib/feature-1.ts': {\n bytes: 376,\n },\n './src/lib/utils/math.ts': {\n bytes: 172,\n },\n },\n entryPoint: './src/index.ts',\n },\n 'static/js/async/src_lib_feature-2_ts.js': {\n path: 'static/js/async/src_lib_feature-2_ts.js',\n bytes: 708,\n imports: [\n {\n path: './lib/feature-2',\n kind: 'dynamic-import',\n original: './lib/feature-2',\n },\n ],\n inputs: {\n './src/lib/feature-2.ts': {\n bytes: 147,\n },\n },\n },\n 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js': {\n path: 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js',\n bytes: 79_545,\n imports: [\n {\n path: 'minimatch',\n kind: 'import-statement',\n original: 'minimatch',\n },\n ],\n inputs: {\n '../../../../../node_modules/minimatch/dist/esm/index.js': {\n bytes: 39_098,\n },\n },\n },\n });\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.ts", + "messages": [ + { + "ruleId": "sonarjs/no-duplicate-string", + "severity": 1, + "message": "Define a constant instead of duplicating this literal 5 times.", + "line": 64, + "column": 19, + "nodeType": "Literal", + "messageId": "defineConstant", + "endLine": 64, + "endColumn": 35 + }, + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'unifyBundlerStats' has too many lines (82). Maximum allowed is 50.", + "line": 67, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 174, + "endColumn": 2 + }, + { + "ruleId": "complexity", + "severity": 1, + "message": "Function 'unifyBundlerStats' has a complexity of 23. Maximum allowed is 20.", + "line": 67, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "complex", + "endLine": 174, + "endColumn": 2 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 81, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 85, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 92, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 114, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 98, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 112, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 105, + "column": 11, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 109, + "endColumn": 13 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 117, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 141, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 132, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 137, + "endColumn": 8 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 145, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 171, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 160, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 160, + "endColumn": 44 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 165, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 167, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 166, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 166, + "endColumn": 53 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 166, + "column": 9, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 166, + "endColumn": 30, + "suggestions": [ + { + "messageId": "suggestOptionalChain", + "fix": { + "range": [4721, 4722], + "text": "?." + }, + "desc": "Consider using the optional chain operator `?.` instead. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 170, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 170, + "endColumn": 39 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 191, + "column": 3, + "nodeType": "WhileStatement", + "messageId": "generic", + "endLine": 211, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 192, + "column": 21, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 192, + "endColumn": 35 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 192, + "column": 21, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 192, + "endColumn": 34 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 203, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 210, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 208, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 208, + "endColumn": 32 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 227, + "column": 3, + "nodeType": "WhileStatement", + "messageId": "generic", + "endLine": 243, + "endColumn": 4 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 228, + "column": 21, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 228, + "endColumn": 35 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 228, + "column": 21, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 228, + "endColumn": 34 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 234, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 242, + "endColumn": 6 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 240, + "column": 9, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 240, + "endColumn": 32 + } + ], + "suppressedMessages": [], + "errorCount": 11, + "fatalErrorCount": 0, + "warningCount": 14, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { minimatch } from 'minimatch';\nimport type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type SondaResourceKind = 'asset' | 'filesystem';\nexport type SondaResourceType = 'script' | 'style' | 'font' | 'image' | 'other';\nexport type SondaConnectionKind = 'import' | 'entrypoint' | 'dynamic-import';\n\nexport type SondaResource = {\n kind: SondaResourceKind;\n name: string;\n type: SondaResourceType;\n uncompressed: number;\n gzip?: number;\n brotli?: number;\n format?: string;\n};\n\nexport type SondaConnection = {\n kind: SondaConnectionKind;\n source: string;\n target: string;\n original: string | null;\n};\n\nexport type SondaCoreStats = {\n metadata: {\n version: string;\n integration: string;\n sources: boolean;\n gzip: boolean;\n brotli: boolean;\n };\n resources: SondaResource[];\n connections: SondaConnection[];\n dependencies: unknown[];\n issues: unknown[];\n sourcemaps: unknown[];\n};\n\nexport type SondaUnifyOptions = {\n excludeOutputs?: string[];\n};\n\n/**\n * Checks if path matches any exclude pattern. Filters unwanted files from bundle stats.\n */\nfunction shouldExcludeOutput(\n outputPath: string,\n excludePatterns: string[],\n): boolean {\n return excludePatterns.some(pattern => minimatch(outputPath, pattern));\n}\n\n/**\n * Converts Sonda connection kind to unified import kind\n */\nfunction mapConnectionKind(\n kind: SondaConnectionKind,\n): 'import-statement' | 'dynamic-import' {\n return kind === 'dynamic-import' ? 'dynamic-import' : 'import-statement';\n}\n\nexport function unifyBundlerStats(\n stats: SondaCoreStats,\n options: SondaUnifyOptions,\n): UnifiedStats {\n const { excludeOutputs = ['**/*.map', '**/*.d.ts'] } = options;\n\n // Filter asset resources (outputs)\n const assets = stats.resources.filter(r => r.kind === 'asset');\n const filesystemResources = stats.resources.filter(\n r => r.kind === 'filesystem',\n );\n\n // Build a map of entrypoints: output -> source\n const entryPointMap = new Map();\n for (const conn of stats.connections) {\n if (conn.kind === 'entrypoint') {\n entryPointMap.set(conn.target, conn.source);\n }\n }\n\n // Build a map of imports for each output\n const outputImportsMap = new Map();\n const outputInputsMap = new Map>();\n\n // Process connections to build import relationships\n for (const conn of stats.connections) {\n if (conn.kind === 'import' || conn.kind === 'dynamic-import') {\n // Find which output this source belongs to by tracing entrypoints\n const sourceFile = conn.source;\n\n // For each asset, check if this source is part of its dependency tree\n for (const asset of assets) {\n const entryPoint = entryPointMap.get(asset.name);\n if (\n entryPoint &&\n isPartOfDependencyTree(sourceFile, entryPoint, stats.connections)\n ) {\n const imports = outputImportsMap.get(asset.name) || [];\n imports.push({\n path: conn.target,\n kind: mapConnectionKind(conn.kind),\n ...(conn.original && { original: conn.original }),\n });\n outputImportsMap.set(asset.name, imports);\n }\n }\n }\n }\n\n // Build inputs map for each output\n for (const asset of assets) {\n const entryPoint = entryPointMap.get(asset.name);\n if (entryPoint) {\n const inputsMap = new Map();\n\n // Add the entry point itself\n const entryResource = filesystemResources.find(\n r => r.name === entryPoint,\n );\n if (entryResource) {\n inputsMap.set(entryPoint, entryResource.uncompressed);\n }\n\n // Add all dependencies\n const deps = getAllDependencies(entryPoint, stats.connections);\n for (const dep of deps) {\n const depResource = filesystemResources.find(r => r.name === dep);\n if (depResource) {\n inputsMap.set(dep, depResource.uncompressed);\n }\n }\n\n outputInputsMap.set(asset.name, inputsMap);\n }\n }\n\n const result: UnifiedStats = {};\n\n for (const asset of assets) {\n // Skip outputs that match exclude patterns\n if (shouldExcludeOutput(asset.name, excludeOutputs)) {\n continue;\n }\n\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.uncompressed,\n imports: outputImportsMap.get(asset.name) || [],\n inputs: {},\n };\n\n const entryPoint = entryPointMap.get(asset.name);\n if (entryPoint) {\n unifiedOutput.entryPoint = entryPoint;\n }\n\n const inputsMap = outputInputsMap.get(asset.name);\n if (inputsMap) {\n for (const [inputPath, bytes] of inputsMap) {\n unifiedOutput.inputs![inputPath] = { bytes };\n }\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n\n/**\n * Check if a source file is part of the dependency tree of an entry point\n */\nfunction isPartOfDependencyTree(\n source: string,\n entryPoint: string,\n connections: SondaConnection[],\n): boolean {\n if (source === entryPoint) {\n return true;\n }\n\n const visited = new Set();\n const queue = [entryPoint];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n if (current === source) {\n return true;\n }\n\n // Find all imports from current\n for (const conn of connections) {\n if (\n conn.source === current &&\n (conn.kind === 'import' || conn.kind === 'dynamic-import')\n ) {\n queue.push(conn.target);\n }\n }\n }\n\n return false;\n}\n\n/**\n * Get all dependencies of a source file\n */\nfunction getAllDependencies(\n source: string,\n connections: SondaConnection[],\n): string[] {\n const deps = new Set();\n const visited = new Set();\n const queue = [source];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n for (const conn of connections) {\n if (\n conn.source === current &&\n (conn.kind === 'import' || conn.kind === 'dynamic-import')\n ) {\n deps.add(conn.target);\n queue.push(conn.target);\n }\n }\n }\n\n return [...deps];\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.unit.test.ts", + "messages": [], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.vite.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'UnifiedStatsImport' is defined but never used.", + "line": 4, + "column": 3, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 4, + "endColumn": 21 + }, + { + "ruleId": "sonarjs/no-unused-collection", + "severity": 2, + "message": "Either use this collection's contents or remove the collection.", + "line": 39, + "column": 9, + "nodeType": "Identifier", + "messageId": "unusedCollection", + "endLine": 39, + "endColumn": 18 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 40, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 42, + "endColumn": 4 + }, + { + "ruleId": "sonarjs/no-unused-collection", + "severity": 2, + "message": "Either use this collection's contents or remove the collection.", + "line": 44, + "column": 9, + "nodeType": "Identifier", + "messageId": "unusedCollection", + "endLine": 44, + "endColumn": 19 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 45, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 47, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 52, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 81, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 65, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 65, + "endColumn": 50 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 73, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 77, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 74, + "column": 9, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 76, + "endColumn": 10 + }, + { + "ruleId": "@typescript-eslint/no-non-null-assertion", + "severity": 2, + "message": "Forbidden non-null assertion.", + "line": 74, + "column": 9, + "nodeType": "TSNonNullExpression", + "messageId": "noNonNull", + "endLine": 74, + "endColumn": 30, + "suggestions": [ + { + "messageId": "suggestOptionalChain", + "fix": { + "range": [1842, 1843], + "text": "?." + }, + "desc": "Consider using the optional chain operator `?.` instead. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator." + } + ] + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 80, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 80, + "endColumn": 39 + } + ], + "suppressedMessages": [], + "errorCount": 7, + "fatalErrorCount": 0, + "warningCount": 4, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type ViteAsset = {\n name: string;\n size: number;\n};\n\nexport type ViteModule = {\n name: string;\n size: number;\n chunks: string[];\n};\n\nexport type ViteChunk = {\n id: string;\n names: string[];\n files: string[];\n entry: boolean;\n initial: boolean;\n};\n\nexport type ViteCoreStats = {\n builtAt: number;\n assets: ViteAsset[];\n chunks: ViteChunk[];\n modules: ViteModule[];\n};\n\n/**\n * Converts Vite bundle stats to unified format. Processes assets, chunks, and modules for bundle analysis.\n */\nexport function unifyBundlerStats(stats: ViteCoreStats): UnifiedStats {\n const result: UnifiedStats = {};\n\n const chunksMap = new Map();\n for (const chunk of stats.chunks) {\n chunksMap.set(chunk.id, chunk);\n }\n\n const modulesMap = new Map();\n for (const module of stats.modules || []) {\n modulesMap.set(module.name, module);\n }\n\n // Filter out non-JS assets (like source maps)\n const jsAssets = stats.assets.filter(asset => asset.name.endsWith('.js'));\n\n for (const asset of jsAssets) {\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.size,\n imports: [],\n inputs: {},\n };\n\n // Find the chunk that contains this asset\n const chunk = stats.chunks.find(c => c.files.includes(asset.name));\n if (chunk) {\n // Set entry point if it's an entry chunk\n if (chunk.entry && chunk.names.length > 0) {\n unifiedOutput.entryPoint = chunk.names[0];\n }\n\n // Find modules that belong to this chunk\n const chunkModules =\n stats.modules?.filter(module => module.chunks.includes(chunk.id)) || [];\n\n // Add inputs\n for (const module of chunkModules) {\n unifiedOutput.inputs![module.name] = {\n bytes: module.size,\n };\n }\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.ts", + "messages": [ + { + "ruleId": "max-lines-per-function", + "severity": 1, + "message": "Function 'unifyBundlerStats' has too many lines (89). Maximum allowed is 50.", + "line": 66, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "exceed", + "endLine": 165, + "endColumn": 2 + }, + { + "ruleId": "complexity", + "severity": 1, + "message": "Function 'unifyBundlerStats' has a complexity of 22. Maximum allowed is 20.", + "line": 66, + "column": 8, + "nodeType": "FunctionDeclaration", + "messageId": "complex", + "endLine": 165, + "endColumn": 2 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 70, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 72, + "endColumn": 4 + }, + { + "ruleId": "sonarjs/no-unused-collection", + "severity": 2, + "message": "Either use this collection's contents or remove the collection.", + "line": 74, + "column": 9, + "nodeType": "Identifier", + "messageId": "unusedCollection", + "endLine": 74, + "endColumn": 19 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 75, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 77, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 79, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 162, + "endColumn": 4 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 87, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 106, + "endColumn": 6 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'entryName' is assigned a value but never used. Allowed unused elements of array destructuring must match /^_/u.", + "line": 87, + "column": 17, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 87, + "endColumn": 26 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 92, + "column": 9, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 103, + "endColumn": 10 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", + "line": 94, + "column": 11, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 102, + "endColumn": 12 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", + "line": 98, + "column": 13, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 101, + "endColumn": 14 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 99, + "column": 15, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 99, + "endColumn": 58 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 108, + "column": 5, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 147, + "endColumn": 6 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 114, + "column": 7, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 146, + "endColumn": 8 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 120, + "column": 11, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 122, + "endColumn": 12 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 125, + "column": 9, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 145, + "endColumn": 10 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", + "line": 126, + "column": 11, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 144, + "endColumn": 12 + }, + { + "ruleId": "max-depth", + "severity": 1, + "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", + "line": 127, + "column": 13, + "nodeType": "IfStatement", + "messageId": "tooDeeply", + "endLine": 133, + "endColumn": 14 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 128, + "column": 15, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 132, + "endColumn": 17 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an array is not allowed.", + "line": 139, + "column": 13, + "nodeType": "CallExpression", + "messageId": "array", + "endLine": 143, + "endColumn": 15 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 158, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 158, + "endColumn": 44 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 161, + "column": 5, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 161, + "endColumn": 39 + } + ], + "suppressedMessages": [], + "errorCount": 8, + "fatalErrorCount": 0, + "warningCount": 14, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n} from './unified-stats.types.js';\n\nexport type WebpackImportKind = 'import-statement' | 'dynamic-import';\n\nexport type WebpackReason = {\n moduleIdentifier: string | null;\n module: string | null;\n moduleName: string | null;\n type: string;\n userRequest: string;\n loc: string;\n};\n\nexport type WebpackAsset = {\n name: string;\n size: number;\n chunks: string[];\n chunkNames: string[];\n emitted: boolean;\n type: string;\n};\n\nexport type WebpackModule = {\n identifier: string;\n name: string;\n size: number;\n chunks: string[];\n depth: number | null;\n reasons: WebpackReason[];\n type: string;\n moduleType: string;\n issuer: string | null;\n issuerName: string | null;\n providedExports?: string[];\n};\n\nexport type WebpackChunk = {\n id: string;\n names: string[];\n files: string[];\n size: number;\n modules: WebpackModule[];\n parents: string[];\n children: string[];\n entry: boolean;\n initial: boolean;\n runtime?: string[];\n};\n\nexport type WebpackEntrypoint = {\n name: string;\n chunks: string[];\n assets: { name: string; size: number }[];\n};\n\nexport type WebpackCoreStats = {\n assets: WebpackAsset[];\n chunks: WebpackChunk[];\n modules: WebpackModule[];\n entrypoints: Record;\n};\n\nexport function unifyBundlerStats(stats: WebpackCoreStats): UnifiedStats {\n const result: UnifiedStats = {};\n\n const chunksMap = new Map();\n for (const chunk of stats.chunks) {\n chunksMap.set(chunk.id, chunk);\n }\n\n const modulesMap = new Map();\n for (const module of stats.modules) {\n modulesMap.set(module.identifier, module);\n }\n\n for (const asset of stats.assets) {\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.size,\n imports: [],\n inputs: {},\n };\n\n for (const [entryName, entrypoint] of Object.entries(stats.entrypoints)) {\n if (\n entrypoint.assets.some(entryAsset => entryAsset.name === asset.name)\n ) {\n const entryChunks = entrypoint.chunks;\n for (const chunkId of entryChunks) {\n const chunk = chunksMap.get(chunkId);\n if (chunk?.entry) {\n const entryModule = chunk.modules.find(module =>\n module.reasons.some(reason => reason.type === 'entry'),\n );\n if (entryModule) {\n unifiedOutput.entryPoint = entryModule.name;\n break;\n }\n }\n }\n break;\n }\n }\n\n for (const chunkId of asset.chunks) {\n const chunk = chunksMap.get(chunkId);\n if (!chunk) {\n continue;\n }\n\n for (const module of chunk.modules) {\n if (module.type === 'runtime') {\n continue;\n }\n\n if (unifiedOutput.inputs) {\n unifiedOutput.inputs[module.name] = {\n bytes: module.size,\n };\n }\n\n for (const reason of module.reasons) {\n if (reason.type === 'import()') {\n if (unifiedOutput.imports) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'dynamic-import',\n original: reason.userRequest,\n });\n }\n } else if (\n (reason.type === 'harmony side effect evaluation' ||\n reason.type === 'harmony import specifier') &&\n unifiedOutput.imports\n ) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'import-statement',\n original: reason.userRequest,\n });\n }\n }\n }\n }\n\n if (unifiedOutput.imports) {\n const uniqueImports = unifiedOutput.imports.filter(\n (importItem, index, self) =>\n index ===\n self.findIndex(\n item =>\n item.path === importItem.path && item.kind === importItem.kind,\n ),\n );\n unifiedOutput.imports = uniqueImports;\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.unit.test.ts", + "messages": [ + { + "ruleId": "no-duplicate-imports", + "severity": 1, + "message": "'./unify.webpack.js' import is duplicated.", + "line": 3, + "column": 1, + "nodeType": "ImportDeclaration", + "messageId": "import", + "endLine": 3, + "endColumn": 60 + } + ], + "suppressedMessages": [], + "errorCount": 0, + "fatalErrorCount": 0, + "warningCount": 1, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { describe, expect, it } from 'vitest';\nimport { unifyBundlerStats } from './unify.webpack.js';\nimport type { WebpackCoreStats } from './unify.webpack.js';\n\ndescribe('unifyBundlerStats', () => {\n it('should transform basic webpack stats with assets and chunks', () => {\n const webpackStats: WebpackCoreStats = {\n assets: [\n {\n name: 'bundle.js',\n size: 16_823,\n chunks: ['main'],\n chunkNames: ['main'],\n emitted: true,\n type: 'asset',\n },\n ],\n chunks: [\n {\n id: 'main',\n names: ['main'],\n files: ['bundle.js'],\n size: 8415,\n modules: [\n {\n identifier: './src/index.ts',\n name: './src/index.ts',\n size: 463,\n chunks: ['main'],\n depth: 0,\n reasons: [\n {\n moduleIdentifier: null,\n module: null,\n moduleName: null,\n type: 'entry',\n userRequest: './src/index.ts',\n loc: 'main',\n },\n ],\n type: 'module',\n moduleType: 'javascript/auto',\n issuer: null,\n issuerName: null,\n providedExports: ['default', 'indexOnlyFunction'],\n },\n ],\n parents: [],\n children: [],\n entry: true,\n initial: true,\n runtime: ['main'],\n },\n ],\n modules: [\n {\n identifier: './src/index.ts',\n name: './src/index.ts',\n size: 463,\n chunks: ['main'],\n depth: 0,\n reasons: [\n {\n moduleIdentifier: null,\n module: null,\n moduleName: null,\n type: 'entry',\n userRequest: './src/index.ts',\n loc: 'main',\n },\n ],\n type: 'module',\n moduleType: 'javascript/auto',\n issuer: null,\n issuerName: null,\n providedExports: ['default', 'indexOnlyFunction'],\n },\n ],\n entrypoints: {\n main: {\n name: 'main',\n chunks: ['main'],\n assets: [{ name: 'bundle.js', size: 16_823 }],\n },\n },\n };\n\n expect(unifyBundlerStats(webpackStats)).toStrictEqual({\n 'bundle.js': {\n path: 'bundle.js',\n bytes: 16_823,\n imports: [],\n inputs: {\n './src/index.ts': {\n bytes: 463,\n },\n },\n entryPoint: './src/index.ts',\n },\n });\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/utils.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-shadow", + "severity": 1, + "message": "'config' is already declared in the upper scope on line 9 column 3.", + "line": 11, + "column": 30, + "nodeType": "Identifier", + "messageId": "noShadow", + "endLine": 11, + "endColumn": 36 + }, + { + "ruleId": "functional/no-loop-statements", + "severity": 1, + "message": "Unexpected loop, use map or reduce instead.", + "line": 27, + "column": 3, + "nodeType": "ForOfStatement", + "messageId": "generic", + "endLine": 38, + "endColumn": 4 + }, + { + "ruleId": "functional/immutable-data", + "severity": 2, + "message": "Modifying an existing object/array is not allowed.", + "line": 36, + "column": 7, + "nodeType": "AssignmentExpression", + "messageId": "generic", + "endLine": 36, + "endColumn": 34 + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 0, + "warningCount": 2, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { minimatch } from 'minimatch';\nimport type { AuditOutput } from '@code-pushup/models';\nimport { formatBytes } from '@code-pushup/utils';\nimport type { BundleStatsConfig } from './types.js';\nimport type { UnifiedStats } from './unify/unified-stats.types.js';\n\nexport function filterUnifiedTreeByConfig(\n bundleStats: UnifiedStats,\n config: BundleStatsConfig[],\n): UnifiedStats {\n return config.reduce((acc, config) => {\n const filteredStats = filterUnifiedTreeByConfigSingle(bundleStats, config);\n return { ...acc, ...filteredStats };\n }, {});\n}\n\nexport function filterUnifiedTreeByConfigSingle(\n bundleStats: UnifiedStats,\n config: BundleStatsConfig,\n): UnifiedStats | null {\n const { selection } = config;\n const includePatterns = selection.includeOutputs ?? [];\n const excludePatterns = selection.excludeOutputs ?? [];\n\n const filteredStats: UnifiedStats = {};\n\n for (const [path, stats] of Object.entries(bundleStats)) {\n const included =\n includePatterns.length === 0 ||\n includePatterns.some((pattern: string) => minimatch(path, pattern));\n const excluded = excludePatterns.some((pattern: string) =>\n minimatch(path, pattern),\n );\n\n if (included && !excluded) {\n filteredStats[path] = stats;\n }\n }\n\n return Object.keys(filteredStats).length > 0 ? filteredStats : null;\n}\n\nexport function createDisplayValue(\n totalBytes: number,\n fileCount: number,\n): string {\n const formattedBytes = formatBytes(totalBytes);\n const formattedFileCount = `${fileCount} file${fileCount === 1 ? '' : 's'}`;\n return `${formattedBytes} (${formattedFileCount})`;\n}\n\nexport function createEmptyAudit(config: BundleStatsConfig): AuditOutput {\n return {\n slug: config.slug,\n score: 0,\n value: 0,\n displayValue: createDisplayValue(0, 0),\n details: {\n issues: [],\n },\n };\n}\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/stats-generation.int.test.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'writeFileSync' is defined but never used.", + "line": 1, + "column": 10, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 1, + "endColumn": 23 + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { writeFileSync } from 'node:fs';\nimport { cp } from 'node:fs/promises';\nimport path from 'node:path';\nimport { beforeAll, describe, expect, it } from 'vitest';\nimport {\n E2E_ENVIRONMENTS_DIR,\n TEST_OUTPUT_DIR,\n teardownTestFolder,\n} from '@code-pushup/test-utils';\nimport { executeProcess, readJsonFile } from '@code-pushup/utils';\n\nconst FIXTURES_DIR = path.join(\n 'packages',\n 'plugin-bundle-stats',\n 'mocks',\n 'fixtures',\n);\n\nconst tmpRoot = path.join(E2E_ENVIRONMENTS_DIR, 'plugin-bundle-stats');\n\nconst tmpTestOutputRoot = path.join(tmpRoot, TEST_OUTPUT_DIR);\n\nconst fixtureSharedRoot = path.join(FIXTURES_DIR, 'shared-source');\n\nconst SNAPSHOTS_DIR = path.join(\n 'packages',\n 'plugin-bundle-stats',\n 'src',\n 'lib',\n '__snapshots__',\n);\n\ndescribe('esbuild stats generation', () => {\n const tmpEsbuild = path.join(tmpTestOutputRoot, 'esbuild-stats');\n const esbuildDistDir = path.join(tmpEsbuild, 'dist');\n\n beforeAll(async () => {\n await cp(fixtureSharedRoot, tmpEsbuild, {\n recursive: true,\n });\n });\n\n afterAll(async () => {\n await teardownTestFolder(tmpEsbuild);\n });\n\n it('should create stats.json using esbuild', async () => {\n // Copy esbuild configuration\n await cp(path.join(FIXTURES_DIR, 'esbuild'), tmpEsbuild, {\n recursive: true,\n });\n\n const { code } = await executeProcess({\n command: 'node',\n args: ['esbuild.config.cjs'],\n cwd: tmpEsbuild,\n });\n\n expect(code).toBe(0);\n\n const statsPath = path.join(esbuildDistDir, 'stats.json');\n const stats = (await readJsonFile(statsPath)) as Record;\n\n expect(stats).toEqual(\n expect.objectContaining({\n inputs: expect.any(Object),\n outputs: expect.objectContaining({\n 'dist/index.js': expect.any(Object),\n 'dist/bin.js': expect.any(Object),\n }),\n }),\n );\n\n await cp(statsPath, path.join(SNAPSHOTS_DIR, 'esbuild.stats.json'));\n });\n});\n\ndescribe('webpack stats generation', () => {\n const tmpWebpack = path.join(tmpTestOutputRoot, 'webpack-stats');\n const webpackDistDir = path.join(tmpWebpack, 'dist');\n\n beforeAll(async () => {\n await cp(fixtureSharedRoot, tmpWebpack, {\n recursive: true,\n });\n });\n\n afterAll(async () => {\n await teardownTestFolder(tmpWebpack);\n });\n\n it('should create stats.json using webpack@5', async () => {\n await cp(path.join(FIXTURES_DIR, 'webpack'), tmpWebpack, {\n recursive: true,\n });\n\n const { code } = await executeProcess({\n command: 'node',\n args: ['webpack-build.cjs'],\n cwd: tmpWebpack,\n });\n\n expect(code).toBe(0);\n\n const statsPath = path.join(webpackDistDir, 'stats.json');\n const rawStats = (await readJsonFile(statsPath)) as Record;\n\n expect(rawStats).toEqual(\n expect.objectContaining({\n modules: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/src\\/index/),\n }),\n expect.objectContaining({\n name: expect.stringMatching(/src\\/utils/),\n }),\n ]),\n assets: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/bundle\\.js/),\n }),\n ]),\n }),\n );\n\n await cp(statsPath, path.join(SNAPSHOTS_DIR, 'webpack.stats.json'));\n });\n});\n\ndescribe('rsbuild stats generation', () => {\n const tmpRsbuild = path.join(tmpTestOutputRoot, 'rsbuild-stats');\n const rsbuildDistDir = path.join(tmpRsbuild, 'dist');\n\n beforeAll(async () => {\n await cp(fixtureSharedRoot, tmpRsbuild, {\n recursive: true,\n });\n });\n\n afterAll(async () => {\n await teardownTestFolder(tmpRsbuild);\n });\n\n it('should create stats.json using rsbuild', async () => {\n await executeProcess({\n command: 'mkdir',\n args: ['-p', 'dist'],\n cwd: tmpRsbuild,\n });\n\n await cp(path.join(FIXTURES_DIR, 'rsbuild'), path.join(tmpRsbuild), {\n recursive: true,\n });\n\n await cp(fixtureSharedRoot, path.join(tmpRsbuild, 'src'), {\n recursive: true,\n });\n\n const { code } = await executeProcess({\n command: 'node',\n args: ['rsbuild-build.cjs'],\n cwd: tmpRsbuild,\n });\n\n expect(code).toBe(0);\n\n const statsPath = path.join(rsbuildDistDir, 'stats.json');\n const rawStats = (await readJsonFile(statsPath)) as Record;\n\n expect(rawStats).toEqual(\n expect.objectContaining({\n modules: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/src\\/index/),\n }),\n expect.objectContaining({\n name: expect.stringMatching(/src\\/utils/),\n }),\n ]),\n assets: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/bundle\\.js/),\n }),\n ]),\n }),\n );\n\n await cp(statsPath, path.join(SNAPSHOTS_DIR, 'rsbuild.stats.json'));\n });\n});\n", + "usedDeprecatedRules": [ + { + "ruleId": "vitest/no-done-callback", + "replacedBy": [] + } + ] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/types.ts", + "messages": [ + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'TablePruningConfig' is defined but never used.", + "line": 4, + "column": 3, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 4, + "endColumn": 21 + }, + { + "ruleId": "@typescript-eslint/no-unused-vars", + "severity": 2, + "message": "'SelectionConfig' is defined but never used.", + "line": 8, + "column": 15, + "nodeType": null, + "messageId": "unusedVar", + "endLine": 8, + "endColumn": 30 + } + ], + "suppressedMessages": [], + "errorCount": 2, + "fatalErrorCount": 0, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import type { Group, PluginArtifactOptions } from '@code-pushup/models';\nimport type {\n InsightsTableConfig,\n TablePruningConfig,\n} from './runner/audits/details/table.js';\nimport type { DependencyTreeConfig } from './runner/audits/details/tree.js';\nimport type { PenaltyConfig, ScoringConfig } from './runner/audits/scoring.js';\nimport type { SelectionConfig } from './runner/audits/selection.js';\nimport type { SupportedBundlers } from './runner/types.js';\n\nexport type SelectionGeneralConfig = {\n include?: string[];\n exclude?: string[];\n};\n\nexport type PluginDependencyTreeOptions = Omit<\n Partial,\n 'enabled'\n>;\n\nexport type DependencyTreeOptions = DependencyTreeConfig;\n\nexport type SelectionOptions = SelectionGeneralConfig & {\n mode?: 'bundle' | 'matchingOnly' | 'withStartupDeps' | 'withAllDeps';\n includeOutputs?: string[];\n excludeOutputs?: string[];\n includeInputs?: string[];\n excludeInputs?: string[];\n includeImports?: string[];\n excludeImports?: string[];\n includeEntryPoints?: string[];\n excludeEntryPoints?: string[];\n};\n\nexport type PluginSelectionOptions = Omit<\n SelectionOptions,\n | 'include'\n | 'includeOutputs'\n | 'includeInputs'\n | 'includeImports'\n | 'includeEntryPoints'\n>;\n\nexport type PenaltyOptions = Omit & {\n artefactSize?: PenaltyConfig['artefactSize'] | number;\n};\n\nexport type ScoringOptions = {\n enabled?: boolean;\n totalSize?: ScoringConfig['totalSize'] | number;\n penalty?: PenaltyOptions;\n};\n\nexport type PluginPenaltyOptions = Omit;\n\nexport type PluginScoringOptions = {\n penalty?: PluginPenaltyOptions;\n};\n\nexport type InsightsTableOptions = InsightsTableConfig | false;\nexport type PluginInsightsTableOptions = InsightsTableConfig | false;\n\nexport type BundleStatsAuditOptions = {\n slug?: string;\n title: string;\n description?: string;\n selection?: SelectionOptions;\n scoring?: ScoringOptions;\n dependencyTree?: DependencyTreeOptions;\n insightsTable?: InsightsTableOptions;\n};\n\nexport type PluginBundleStatsAuditOptions = {\n selection?: PluginSelectionOptions;\n scoring?: PluginScoringOptions;\n dependencyTree?: PluginDependencyTreeOptions;\n insightsTable?: PluginInsightsTableOptions;\n};\n\nexport type PluginOptions = {\n groups?: Group[];\n bundler: SupportedBundlers;\n audits: BundleStatsAuditOptions[];\n} & PluginBundleStatsAuditOptions &\n PluginArtifactOptions;\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.int.config.ts", + "messages": [ + { + "ruleId": null, + "nodeType": null, + "fatal": true, + "severity": 2, + "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.int.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 1, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "/// \nimport { defineConfig } from 'vite';\nimport { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';\n\nexport default defineConfig({\n cacheDir: '../../node_modules/.vite/plugin-bundle-stats',\n test: {\n reporters: ['basic'],\n globals: true,\n cache: {\n dir: '../../node_modules/.vitest/plugin-bundle-stats',\n },\n alias: tsconfigPathAliases(),\n pool: 'threads',\n poolOptions: { threads: { singleThread: true } },\n coverage: {\n reporter: ['text', 'lcov'],\n reportsDirectory: '../../coverage/plugin-bundle-stats/int-tests',\n exclude: ['mocks/**', '**/types.ts'],\n },\n environment: 'node',\n include: ['src/**/*.int.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],\n globalSetup: ['../../global-setup.ts'],\n setupFiles: [\n '../../testing/test-setup/src/lib/cliui.mock.ts',\n '../../testing/test-setup/src/lib/reset.mocks.ts',\n '../../testing/test-setup/src/lib/chrome-path.mock.ts',\n ],\n },\n});\n", + "usedDeprecatedRules": [] + }, + { + "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.unit.config.ts", + "messages": [ + { + "ruleId": null, + "nodeType": null, + "fatal": true, + "severity": 2, + "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.unit.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." + } + ], + "suppressedMessages": [], + "errorCount": 1, + "fatalErrorCount": 1, + "warningCount": 0, + "fixableErrorCount": 0, + "fixableWarningCount": 0, + "source": "import { createUnitTestConfig } from '../../testing/test-setup-config/src/index.js';\n\nexport default createUnitTestConfig('plugin-bundle-stats');\n", + "usedDeprecatedRules": [] + } +] diff --git a/packages/plugin-bundle-stats/CONTRIBUTING.md b/packages/plugin-bundle-stats/CONTRIBUTING.md new file mode 100644 index 0000000..c8779ee --- /dev/null +++ b/packages/plugin-bundle-stats/CONTRIBUTING.md @@ -0,0 +1,35 @@ +# Contributing + +## Development + +### Generate Build Artifacts + +Before running the plugin, you need to generate the bundle stats files from the test fixtures. Each bundler produces different output formats: + +```bash +# Navigate to the test fixture +cd packages/plugin-bundle-stats/mocks/fixtures/node-minimal + +# Generate artifacts for all bundlers +npm run build + +# Or generate artifacts for specific bundlers +npm run build:esbuild # → dist/esbuild/stats.json +npm run build:esbuild-sonda # → dist/esbuild-sonda/sonda-report.json +npm run build:webpack # → dist/webpack/stats.json +npm run build:rsbuild # → dist/rsbuild/stats.json +npm run build:vite # → dist/vite/stats.json +``` + +### Running the Plugin + +Once the artifacts are generated, you can run the Code PushUp plugin to analyze them: + +```bash +# Run plugin analysis for each bundler +nx run plugin-bundle-stats:code-pushup-minimal-esbuild +nx run plugin-bundle-stats:code-pushup-minimal-esbuild-sonda +nx run plugin-bundle-stats:code-pushup-minimal-webpack +nx run plugin-bundle-stats:code-pushup-minimal-rsbuild +nx run plugin-bundle-stats:code-pushup-minimal-vite +``` diff --git a/packages/plugin-bundle-stats/README.md b/packages/plugin-bundle-stats/README.md new file mode 100644 index 0000000..adfa52f --- /dev/null +++ b/packages/plugin-bundle-stats/README.md @@ -0,0 +1,500 @@ +# @code-pushup/bundle-stats-plugin + +[![npm](https://img.shields.io/npm/v/%40code-pushup%2Fbundle-stats-plugin.svg)](https://www.npmjs.com/package/@code-pushup/bundle-stats-plugin) +[![downloads](https://img.shields.io/npm/dm/%40code-pushup%2Fbundle-stats-plugin)](https://npmtrends.com/@code-pushup/bundle-stats-plugin) +[![dependencies](https://img.shields.io/librariesio/release/npm/%40code-pushup/bundle-stats-plugin)](https://www.npmjs.com/package/@code-pushup/bundle-stats-plugin?activeTab=dependencies) + +🕵️ **Code PushUp plugin for measuring bundle size with diagnostics.** 🔥 + +--- + +This plugin analyzes your build output from modern bundlers to provide detailed bundle size insights and help you track bundle optimization over time. It supports multiple bundlers and provides configurable thresholds for monitoring bundle size targets. + +Bundle statistics are mapped to Code PushUp audits in the following way: + +- **Value**: Total bundle size in bytes for the analyzed configuration +- **Score**: Calculated based on size thresholds with penalties for oversized artifacts +- **Display Value**: Human-readable bundle size (e.g., "2.5 MB") +- **Issues**: Detailed warnings and errors for bundles exceeding thresholds +- **Tree View**: Interactive breakdown of bundle contents showing files, chunks, and imports + +## Getting started + +1. If you haven't already, install [@code-pushup/cli](../cli/README.md) and create a configuration file. + +2. Install as a dev dependency with your package manager: + + ```sh + npm install --save-dev @code-pushup/bundle-stats-plugin + ``` + + ```sh + yarn add --dev @code-pushup/bundle-stats-plugin + ``` + + ```sh + pnpm add --save-dev @code-pushup/bundle-stats-plugin + ``` + +3. Set up your bundler to generate statistics files. The plugin currently supports: + +
+ ESBuild (recommended) + + ```bash + esbuild src/index.js --bundle --outfile=dist/bundle.js --metafile=dist/stats.json + ``` + +
+ +
+ Webpack + + ```js + // webpack.config.js + module.exports = { + // ... your config + plugins: [ + new (require('webpack').StatsWriterPlugin)({ + filename: 'stats.json', + }), + ], + }; + ``` + +
+ +
+ Vite (via Rollup) + + ```js + // vite.config.js + export default { + build: { + rollupOptions: { + plugins: [ + { + name: 'bundle-stats', + generateBundle() { + this.emitFile({ + type: 'asset', + fileName: 'stats.json', + source: JSON.stringify(this.getModuleInfo()), + }); + }, + }, + ], + }, + }, + }; + ``` + +
+ +4. Add this plugin to the `plugins` array in your Code PushUp CLI config file (e.g. `code-pushup.config.ts`). + + ```ts + import bundleStatsPlugin from '@code-pushup/bundle-stats-plugin'; + + export default { + // ... + plugins: [ + // ... + await bundleStatsPlugin({ + artefact: 'dist/stats.json', + bundler: 'esbuild', + configs: [ + { + title: 'Main Bundle', + include: ['main-*.js', 'polyfills-*.js'], + thresholds: { + totalSize: [300 * 1024, 1024 * 1024], // 300KB - 1MB + artefactSize: 500 * 1024, // 500KB max per file + }, + }, + { + title: 'Lazy Chunks', + include: ['**/chunk-*.js'], + thresholds: { + totalSize: [10 * 1024, 100 * 1024], // 10KB - 100KB + }, + }, + ], + }), + ], + }; + ``` + +5.
+ (Optional) Generate bundle stats automatically before analysis + + ```ts + await bundleStatsPlugin({ + generateArtefacts: { + command: 'npm', + args: ['run', 'build:stats'], + cwd: './path/to/your/project', + }, + artefact: 'dist/stats.json', + bundler: 'esbuild', + configs: [ + /* ... */ + ], + }); + ``` + +
+ +6. Run the CLI with `npx code-pushup collect` and view or upload report (refer to [CLI docs](../cli/README.md)). + +## About bundle analysis + +Bundle analysis helps you understand the composition and size of your application bundles. This plugin provides insights into: + +- **Bundle Size Tracking**: Monitor total bundle sizes against configurable thresholds +- **File-by-File Breakdown**: See exactly which files contribute to bundle size +- **Chunk Analysis**: Understand code splitting effectiveness +- **Dependency Insights**: Identify heavy dependencies and opportunities for optimization +- **Threshold Monitoring**: Set size budgets for different bundle types (main, vendor, lazy chunks) + +The plugin organizes bundles into logical groups and provides detailed tree views showing: + +- Entry files (main.js, polyfills.js) +- Lazy-loaded chunks +- Third-party dependencies +- Source files and their relative contributions + +## Plugin architecture + +
+Plugin configuration specification + +The plugin accepts the following parameters: + +#### Required Parameters + +- **`artefact`**: Path to the bundler statistics file (JSON) +- **`bundler`**: Type of bundler used ('esbuild', 'webpack', 'vite', or 'rsbuild') +- **`configs`**: Array of bundle analysis configurations + +#### Bundle Configuration Options + +Each configuration in the `configs` array supports: + +- **`title`**: Human-readable name for the bundle analysis +- **`include`**: Glob patterns for files to include in analysis (e.g., `['main-*.js', '*.css']`) +- **`exclude`**: Glob patterns for files to exclude (optional) +- **`thresholds`**: Size thresholds for scoring + - **`totalSize`**: Total bundle size threshold as number or `[min, max]` tuple + - **`artefactSize`**: Individual file size threshold (optional) + +#### Optional Parameters + +- **`generateArtefacts`**: Command to run before analysis to generate stats files + + - **`command`**: Command to execute (e.g., 'npm', 'npx') + - **`args`**: Array of command arguments + - **`cwd`**: Working directory for command execution + +- **`grouping`**: Options for organizing bundle contents (uses defaults) +- **`pruning`**: Tree display options + - **`maxChildren`**: Maximum child nodes to show (default: 10) + - **`maxDepth`**: Maximum tree depth (default: 2) + - **`startDepth`**: Starting depth for analysis (default: 0) + +
+ +
+Bundle threshold configuration + +Thresholds can be specified as: + +1. **Single number**: Maximum allowed size + + ```ts + thresholds: { + totalSize: 1024 * 1024, // 1MB max + artefactSize: 500 * 1024, // 500KB max per file + } + ``` + +2. **Range tuple**: `[minimum, maximum]` sizes + ```ts + thresholds: { + totalSize: [300 * 1024, 1024 * 1024], // 300KB - 1MB range + } + ``` + +
+ +### Audits + +A audit encapsulates a group of artefacts determined by `BundleStatsConfig`. + +#### Scoring + +The plugin assigns a **score** in the range `[0 … 1]` to each artefact (or artefact group) based on its byte size relative to a configurable **maximum threshold** (`maxArtefactSize`). A perfect score (`1`) means "within budget," and a zero score (`0`) means "critically over budget." + +##### Scoring Parameters + +| **Parameter** | **Description** | +| ------------: | ----------------------------------- | +| `S` | Actual bytes | +| `M` | Size threshold bytes | +| `E` | Number of "Too Large" (🚨) errors | +| `W` | Number of "Too Small" (⚠️) warnings | +| `we` | Weight per error (default 1) | +| `ww` | Weight per warning (default 0.5) | + +###### Size score + +$` +\mathrm{sizeScore} = +\begin{cases} +1, & S \le M\\[6pt] +\max\bigl(0,\;1 - \tfrac{S - M}{M}\bigr), & S > M +\end{cases} +`$ + +###### Issues penalty + +$`penalty = we * E + ww * W`$ + +###### Final blended score + +$` +\mathrm{finalScore} = \max\!\Bigl(0,\;\mathrm{sizeScore} - \frac{\mathrm{penalty}}{we + ww}\Bigr) +`$ + +```mermaid +xychart-beta + title "Score vs Artifact Size (with penalty shift)" + x-axis [0, 1, 1.25, 1.5, 1.75, 2] + y-axis "Score" 0 --> 1 + line Original [1, 1, 0.75, 0.5, 0.25, 0] + line Penalized [0.5, 0.5, 0.25, 0, 0, 0] +``` + +#### Issues + +The plugin optionally creates diagnostic for the given artefacts. +The following table shows all different options: + +| Diagnostic | Description | Config Key | Default | Severity | Recommended Action | +| ------------ | -------------------------------------------------------------------------------------------------------- | --------------- | --------------- | -------- | ----------------------------------------------------------------------- | -------------------------------------------------------------------- | +| Too Large 🚨 | Artifact exceeds the maximum allowed size. May indicate an unoptimized bundle or accidentally checked-in | binary. | maxArtifactSize | 5 MB | Error | Review and optimize the artifact (e.g. code splitting, compression). | +| Too Small ⚠️ | Artifact is below the minimum expected size. Could signal missing dependencies or incomplete build. | minArtifactSize | 1 KB | Warn | Verify that the build output is complete and dependencies are included. | + +**Example Issues:** + +| Severity | Message | Source file | Line(s) | +| :----------: | :----------------------------------------------------------------------------- | :-------------------: | :-----: | +| 🚨 _error_ | `main.js` is 6.12 MB (max 5 MB); enable code-splitting or lazy-loading. | `dist/lib/main.js` | | +| 🚨 _error_ | `vendor.js` is 2.05 MB (max 1.5 MB); apply tree-shaking or serve libs via CDN. | `dist/lib/vendor.js` | | +| ⚠️ _warning_ | `utils.js` is 50 kB (min 100 kB); verify bundling. | `dist/lib/utils.js` | | +| ⚠️ _warning_ | `styles.css` is 10 B (min 1 kB); check CSS inclusion. | `dist/lib/styles.css` | | + +#### Artefact Tree + +**Example:** + +```txt +🗂️ example-group 237.17 kB 101 files +├── 📍 entry-1.js 138 kB 2 files +│ ├── 📄 src/input-1.ts 101 kB +│ └── 📄 src/input-2.ts 37 kB +├── 📄 entry-2.js 30 kB 2 files +│ ├── 📄 node_modules/@angular/router/provider.js +│ └── 📄 node_modules/@angular/router/service.js +├── 🎨 styles.css 14 kB +└── 🔗 static imports from 📍 entry-1.js 104 kB + └── 📄 file-1.js + +``` + +#### Artefact Types + +Each group is also displayed as tree of artefacts, inputs and static imports. +The following types are detected. + +- 📄 - script file - JS/TS artefact +- 🎨 - style files - CSS/SCSS artefacts +- 📍 - entry file - JS/TS artefact +- 🔗 - static imports - List of S/TS artefacts statically imported by another file + +```txt +🗂️ example-group 190 kB 4 files +├── 📍 entry-1.js 100 kB 2 files +├── 📄 file-1.js 30 kB 2 files +├── 🎨 styles.css 10 kB +└── 🔗 static imports from 📍 entry-1.js + └── 📄 file-2.js 50 kB + +``` + +#### Artefact Inputs + +Each artefact is maintains out of inputs ind imports. The inputs are listed under each chunk. + +```txt +🗂️ example-group 60 kB 1 files +└── 📄 file-1.js 60 kB 3 files + ├── 📄 src/lib/cli.js + │ └── 📄 node_modules/yargs/yargs.js + └── 📄 node_modules/zod/helpers + └── 📄 node_modules/zod/helpers/description.js +``` + +#### Artefact Imports + +Each artefact imports that are statically imported and directly contribute to the artefact group size are listed under dedicated import groups per file. This is helpful to understand the true size of you artefact group. +Static imports are loaded together with it's importing parent and therefore will end up in the loaded bytes. Displaying them helps to inderstand why they are part and where they aer imported from. + +```txt +🗂️ example-group 150 kB 6 files +├── 📍 entry-1.js 100 kB +├── 📄 file-1.js 50 kB +├── 🔗 static imports from 📍 entry-1.js 60 kB 2 files +│ ├── 📄 file-2.js 40 kB +│ └── 📄 file-3.js 40 kB +└── 🔗 static imports from 📄 file-1.js 80 kB 2 files + ├── 📄 file-4.js 40 kB + └── 📄 file-5.js 40 kB + +``` + +#### Artefact Grouping + +Artefact inputs can be grouped over the configuration. + +**Ungrouped:** + +```txt +🗂️ example-group 150 kB 1 files +└── 📄 entry-2.js 150 kB 3 files + ├── 📄 node_modules/@angular/router/provider.js + └── 📄 node_modules/@angular/router/service.js + └── 📄 node_modules/@angular/router/utils.js +``` + +**Grouped by:** + +- `patterns` - `node_modules/@angular/router` +- `name` - `@angular/router` +- `icon` - "🅰️" +- `depth` - `1` + +```txt +🗂️ example-group 150 kB 1 files +└── 📄 entry-2.js 150 kB 1 files + └─ 🅰️ @angular/router + +``` + +#### Tree Pruning + +The artefact tree can get quite dense in information. To avoid overload we reduce the amount of visible nodes. + +**Unpruned:** + +```txt +🗂️ example-group 800 kB 10 files +├── 📍 index.js 250 kB 4 files +│ ├── 📄 src/app.js 120 kB 3 files +│ │ ├── 📄 src/components/Header.js 40 kB 2 files +│ │ │ ├── 📄 src/components/Logo.js 15 kB 1 file +│ │ │ └── 📄 src/components/Nav.js 25 kB 1 file +│ │ └── 📄 src/utils/math.js 30 kB 1 file +│ ├── 📄 src/route-1.js 120 kB 3 files +│ ├── 📄 src/route-2.js 120 kB 3 files +│ └── 📄 src/main.css 50 kB 1 file +├── 📄 vendor.js 300 kB 5 files +│ ├── 📄 node_modules/react.js 100 kB 1 file +│ ├── 📄 node_modules/react-dom.js 80 kB 1 file +│ ├── 📄 node_modules/redux.js 60 kB 1 file +│ ├── 📄 node_modules/react-router.js 40 kB 1 file +│ └── 📄 node_modules/lodash.js 20 kB 1 file +└── 📄 logo.svg 250 kB 1 file + +``` + +**Pruning options:** + +- `startDepth` - `1` +- `maxChildren` - `1` +- `maxDepth` - `3` + +**Pruned:** + +```txt +🗂️ example-group 150 kB 10 files +├── 📍 index.js 250 kB 4 files +│ ├── 📄 src/app.js 120 kB +│ └── … 3 more inputs 130 kB +├── 📄 vendor.js 300 kB 5 files +│ ├── 📄 node_modules/react.js 100 kB +│ └── … 4 more inputs 200 kB +└── 📄 logo.svg 250 kB +``` + +
+Audits and bundle organization + +Each configuration creates a separate audit with: + +```ts +{ + slug: 'main-bundle', // Generated from title + title: 'Main Bundle (4 files)', + score: 0.85, + value: 1048576, // Total bytes + displayValue: '1 MB', + details: { + issues: [/* Size threshold violations */], + trees: [/* Interactive bundle breakdown */] + } +} +``` + +
+ +### Optionally set up categories + +Reference audits which you wish to include in custom categories: + +```ts +export default { + // ... + categories: [ + { + slug: 'bundle-size', + title: 'Bundle Size', + refs: [ + { + type: 'audit', + plugin: 'bundle-stats', + slug: 'main-bundle', + weight: 3, + }, + { + type: 'audit', + plugin: 'bundle-stats', + slug: 'lazy-chunks', + weight: 1, + }, + ], + }, + ], +}; +``` + +## Supported bundlers + +| Bundler | Status | Stats Generation | +| ----------- | --------------- | ---------------------------- | +| **ESBuild** | ✅ Full support | `--metafile=stats.json` | +| **Webpack** | 🚧 Partial | Custom stats plugin required | +| **Vite** | 🚧 Planned | Via Rollup plugin | +| **RSBuild** | 🚧 Planned | Native stats output | + +> **Note**: Currently, ESBuild is the most thoroughly tested and recommended bundler for this plugin. diff --git a/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts b/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts new file mode 100644 index 0000000..64d838f --- /dev/null +++ b/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts @@ -0,0 +1,45 @@ +import type { CoreConfig } from '@code-pushup/models'; +import bundleStatsPlugin from './src'; + +const config: CoreConfig = { + plugins: [ + await bundleStatsPlugin({ + artifactsPaths: + 'packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json', + bundler: 'sonda', + audits: [ + { + slug: 'bundle-size', + title: 'Bundle Size Analysis', + description: 'Analyzes bundle size using Sonda report', + selection: { + mode: 'bundle', + includeOutputs: ['**/*.js'], + }, + scoring: { + totalSize: 100_000, + }, + }, + ], + }), + ], + categories: [ + { + slug: 'performance', + title: '⚡ Performance', + description: 'Bundle performance analysis using Sonda', + refs: [ + { + type: 'audit', + plugin: 'bundle-stats', + slug: 'bundle-size', + weight: 1, + }, + ], + }, + ], +}; + +export default (async () => { + return config; +})(); diff --git a/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts b/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts new file mode 100644 index 0000000..f72ddbe --- /dev/null +++ b/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts @@ -0,0 +1,869 @@ +import type { CoreConfig } from '../models/src/index.js'; +import bundleStatsPlugin from './src'; +import { MinMax } from './src/lib/runner/types'; +import { BundleStatsAuditOptions } from './src/lib/types'; + +/** + * Execute code-pushup over Nx: + * nx code-pushup:minimal plugin-bundle-stats + */ + +// ===== Selection Constants ===== +const SELECTION_ALL_OUTPUTS = { + includeOutputs: ['**/*'], +}; + +const SELECTION_OUTPUTS_INDEX_FILE = ['**/index.ts']; + +const SELECTION_ONE_FILE = { + mode: 'bundle' as const, + includeOutputs: SELECTION_OUTPUTS_INDEX_FILE, +}; +// ===== Scoring Constants ===== + +const THRESHOLD_ALWAYS_PASS_MAX = 100_000; // 100KB - much higher than actual bundle size +const THRESHOLD_ALWAYS_FAIL_MAX = 1; +const THRESHOLD_ALWAYS_FAIL_MIN = 1; +const THRESHOLD_ALWAYS_PASS_MIN = 0; +const THRESHOLD_ALWAYS_PASS_RANGE: MinMax = [ + THRESHOLD_ALWAYS_PASS_MIN, + THRESHOLD_ALWAYS_PASS_MAX, +]; + +const DISABLED = { + enabled: false, + totalSize: THRESHOLD_ALWAYS_PASS_MAX, +}; + +const BASE_AUDIT_ALL_FILES = { + selection: { + mode: 'bundle' as const, + includeOutputs: ['**/*.js'], + }, +}; + +const BASE_AUDIT_ALL_FILES_SCORING_DISABLED = { + selection: { + mode: 'bundle' as const, + includeOutputs: ['**/*.js'], + }, + scoring: DISABLED, +}; + +// ===== Audit Groups ===== + +// ===== Audits ===== + +// ===== Selection Audits ===== +const SELECTION_AUDIT_ICON = '🎯'; +const SELECTION_AUDIT_PREFIX = 'selection'; + +/** + * Stats Data + * + * esbuild-minimal.stats.json + * └── outputs + * ├── dist/index.js // entryPoint: ../shared-source/src/index.ts (595 B) + * │ ├── inputs + * │ │ └── ../shared-source/src/index.ts (386 B) + * │ └── imports + * │ ├── dist/chunks/chunk-PKX4VJZC.js // import-statement + * │ ├── dist/chunks/chunk-SK6HMZ5B.js // import-statement + * │ └── dist/chunks/feature-2-SERQNJVR.js // dynamic-import + * ├── dist/bin.js // entryPoint: ../shared-source/src/bin.ts (549 B) + * │ ├── inputs + * │ │ └── ../shared-source/src/bin.ts (373 B) + * │ └── imports + * │ ├── dist/chunks/chunk-PKX4VJZC.js // import-statement + * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement + * ├── dist/chunks/chunk-PKX4VJZC.js // Main shared chunk (51.35 kB) + * │ ├── inputs (13 files: node_modules + source) + * │ │ ├── ../../../../../node_modules/balanced-match/index.js (1.51 kB) + * │ │ ├── ../../../../../node_modules/brace-expansion/index.js (4.67 kB) + * │ │ ├── ../../../../../node_modules/minimatch/dist/esm/*.js (6 files, ~42 kB total) + * │ │ ├── ../shared-source/node_modules/my-lib/index.js (93 B) + * │ │ ├── ../shared-source/src/lib/utils/format.ts (269 B) + * │ │ ├── ../shared-source/src/lib/feature-1.ts (269 B) + * │ │ ├── ../shared-source/src/lib/utils/math.ts (145 B) + * │ │ └── ../shared-source/src/lib/utils/string.ts (54 B) + * │ └── imports + * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement + * ├── dist/chunks/feature-2-SERQNJVR.js // entryPoint: ../shared-source/src/lib/feature-2.ts (130 B) + * │ ├── inputs + * │ │ └── ../shared-source/src/lib/feature-2.ts (38 B) + * │ └── imports + * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement + * └── dist/chunks/chunk-SK6HMZ5B.js // ESM runtime helpers (1.33 kB) + * ├── inputs: (empty - runtime code) + * └── imports: (none) + */ + +const SELECTION_AUDITS: BundleStatsAuditOptions[] = [ + // ===== Selection - Mode Audits ===== + { + slug: `${SELECTION_AUDIT_PREFIX}-mode-bundle`, + title: `${SELECTION_AUDIT_ICON} - Selection - Mode - Bundle`, + description: + 'Demonstrates bundle mode - standard selection with static imports.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'bundle', + includeOutputs: SELECTION_OUTPUTS_INDEX_FILE, + }, + dependencyTree: { + pruning: { + minSize: 1000, + }, + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-mode-matching-only`, + title: `${SELECTION_AUDIT_ICON} - Selection - Mode - Matching Only`, + description: + 'Demonstrates matchingOnly mode - input filtering with size recalculation.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'matchingOnly', + includeInputs: ['**/utils/**'], + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-mode-startup`, + title: `${SELECTION_AUDIT_ICON} - Selection - Mode - withStartupDeps`, + description: + 'Demonstrates withStartupDeps mode - includes static import dependencies.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'withStartupDeps', + includeOutputs: SELECTION_OUTPUTS_INDEX_FILE, + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-mode-with-all-deps`, + title: `${SELECTION_AUDIT_ICON} - Selection - Mode - withAllDeps`, + description: + 'Demonstrates withAllDeps mode - comprehensive tracking (static + dynamic).', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'withAllDeps', + includeOutputs: SELECTION_OUTPUTS_INDEX_FILE, + }, + }, + + // ===== Selection - Pattern Audits ===== + { + slug: `${SELECTION_AUDIT_PREFIX}-pattern-output-include`, + title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Output Include`, + description: 'Demonstrates including only main chunk files.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'bundle', + includeOutputs: SELECTION_OUTPUTS_INDEX_FILE, + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-pattern-output-include-exclude`, + title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Output Include and Exclude`, + description: + 'Demonstrates including and excluding chunk files to focus on entry points.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'bundle', + includeOutputs: ['**/*.js'], + excludeOutputs: ['**/chunks/**'], + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-pattern-input-include`, + title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Input Include`, + description: 'Demonstrates including only source lib files.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-PKX4VJZC.js'], + includeInputs: ['**/src/lib/**'], + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-pattern-input-include-exclude`, + title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Input Include and Exclude`, + description: + 'Demonstrates including source lib files but excluding node_modules.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'bundle', + includeInputs: ['**/src/lib/**'], + excludeInputs: ['**/node_modules/**'], + }, + }, + { + slug: `${SELECTION_AUDIT_PREFIX}-pattern-combined`, + title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Combined`, + description: + 'Demonstrates combining multiple chunk types with pattern matching.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js', '**/chunks/feature-*.js'], + }, + }, +]; + +const SCORING_AUDIT_ICON = '📏'; +const SCORING_AUDIT_PREFIX = 'scoring'; + +const SCORING_AUDITS: BundleStatsAuditOptions[] = [ + // ===== Scoring - General Audits ===== + { + title: `${SCORING_AUDIT_ICON} - Scoring - General - Disabled`, + description: 'Demonstrates disabled scoring.', + slug: `${SCORING_AUDIT_PREFIX}-general-disabled`, + ...BASE_AUDIT_ALL_FILES, + scoring: { + enabled: false, + }, + }, + + // ===== Scoring - Total Size Audits ===== + { + slug: `${SCORING_AUDIT_PREFIX}-total-size-pass`, + title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Pass`, + description: + 'Demonstrates threshold passing when total size is within range limits.', + ...BASE_AUDIT_ALL_FILES, + scoring: { totalSize: THRESHOLD_ALWAYS_PASS_MAX }, + }, + { + slug: `${SCORING_AUDIT_PREFIX}-total-size-too-big`, + title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Too Big`, + description: + 'Demonstrates threshold failure when total size exceeds simple number limit.', + ...BASE_AUDIT_ALL_FILES, + scoring: { totalSize: THRESHOLD_ALWAYS_FAIL_MAX }, + }, + { + slug: `${SCORING_AUDIT_PREFIX}-total-size-too-small`, + title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Too Small`, + description: + 'Demonstrates threshold warning when total size is below minimum in range.', + ...BASE_AUDIT_ALL_FILES, + scoring: { + totalSize: [THRESHOLD_ALWAYS_FAIL_MIN, THRESHOLD_ALWAYS_PASS_MAX], + }, + }, +]; + +// ===== Scoring with Penalty Audits ===== + +const SCORING_PENALTY_AUDITS: BundleStatsAuditOptions[] = [ + // ===== Scoring - Penalty - Artefact Size ===== + { + slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-pass`, + title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Pass`, + description: + 'Demonstrates penalty passing when all files are within size limits.', + selection: SELECTION_ONE_FILE, + scoring: { + penalty: { + artefactSize: THRESHOLD_ALWAYS_PASS_MAX, + }, + }, + }, + { + slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-pass-range`, + title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Pass Range`, + description: 'Demonstrates penalty passing with min/max range constraints.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + scoring: { + penalty: { + artefactSize: [THRESHOLD_ALWAYS_PASS_MIN, THRESHOLD_ALWAYS_PASS_MAX], + }, + }, + }, + { + slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-too-big`, + title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Too Big`, + description: 'Demonstrates penalty failure when files exceed maximum size.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + scoring: { + penalty: { artefactSize: THRESHOLD_ALWAYS_FAIL_MAX }, + }, + }, + { + slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-too-small`, + title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Too Small`, + description: + 'Demonstrates penalty warning when files are below minimum size.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + scoring: { + totalSize: THRESHOLD_ALWAYS_PASS_MAX, + penalty: { + artefactSize: [THRESHOLD_ALWAYS_FAIL_MIN, THRESHOLD_ALWAYS_PASS_MAX], + }, + }, + }, + + // ===== Scoring - Penalty - Blacklist ===== + { + slug: `${SCORING_AUDIT_PREFIX}-penalty-blacklist-pass`, + title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Blacklist Pass`, + description: + 'Demonstrates penalty passing when no blacklisted patterns match.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + scoring: { + penalty: { blacklist: ['**/non-existent-pattern/**'] }, + }, + }, + { + slug: `${SCORING_AUDIT_PREFIX}-penalty-blacklist-fail`, + title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Blacklist Fail`, + description: + 'Demonstrates penalty failure when blacklisted patterns are found.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + scoring: { + penalty: { blacklist: ['**/*'] }, + }, + }, + + { + slug: `${SCORING_AUDIT_PREFIX}-mixed-options`, + title: `${SCORING_AUDIT_ICON} - Scoring - Mixed Options`, + description: 'Demonstrates mixed scoring options.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + scoring: { + totalSize: 1_000_000, + penalty: { + artefactSize: 2_000_000, + blacklist: ['**/src/lib/utils/math.ts'], + }, + }, + }, +]; + +// ===== Issues Audits ===== +const ISSUES_AUDIT_PREFIX = 'issues'; +const ISSUES_AUDIT_ICON = '🚨'; + +// ===== Insights Audits ===== +const INSIGHT_AUDIT_PREFIX = 'insights'; +const INSIGHT_AUDIT_ICON = '📊'; + +const INSIGHT_AUDITS: BundleStatsAuditOptions[] = [ + // ===== Insights - General Audits ===== + { + slug: `${INSIGHT_AUDIT_PREFIX}-general-disabled`, + title: `${INSIGHT_AUDIT_ICON} - Insights - General - Disabled`, + description: 'Demonstrates disabled insights table.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: false, + }, + + // ===== Insights - View Mode Audits ===== + { + slug: `${INSIGHT_AUDIT_PREFIX}-view-mode-only-matching`, + title: `${INSIGHT_AUDIT_ICON} - Insights - View Mode - Only Matching`, + description: + 'Demonstrates onlyMatching mode - shows only files matching selection.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + mode: 'onlyMatching', + groups: [ + { + title: 'Source Files', + includeInputs: ['**/src/**'], + icon: '📄', + }, + ], + }, + }, + { + slug: `${INSIGHT_AUDIT_PREFIX}-view-mode-all`, + title: `${INSIGHT_AUDIT_ICON} - Insights - View Mode - All`, + description: + 'Demonstrates all mode - shows all files regardless of selection.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + mode: 'all', + groups: [ + { + title: 'Source Files', + includeInputs: ['**/src/**'], + icon: '📄', + }, + ], + }, + }, + + // ===== Insights - Pruning Audits ===== + { + slug: `${INSIGHT_AUDIT_PREFIX}-pruning-max-children`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Pruning - Max Children`, + description: + 'Demonstrates maxChildren pruning - limits table entries shown.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { + title: 'All Files', + includeInputs: ['**/*'], + icon: '📄', + }, + ], + pruning: { maxChildren: 3 }, + }, + }, + { + slug: `${INSIGHT_AUDIT_PREFIX}-pruning-min-size`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Pruning - Min Size`, + description: 'Demonstrates minSize pruning - filters out small files.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { + title: 'Large Files Only', + includeInputs: ['**/*'], + icon: '📄', + }, + ], + pruning: { minSize: 1000 }, + }, + }, + + // ===== Insights - Table Audits ===== + { + slug: `${INSIGHT_AUDIT_PREFIX}-table-grouping`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Table - Grouping`, + description: 'Demonstrates how the bundle is grouped.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { + title: 'Math Utilities', + includeInputs: ['**/math.ts'], + icon: '🔧', + }, + { + title: 'Formatting Utilities', + includeInputs: ['**/format.ts'], + icon: '🔧', + }, + { + title: 'Feature 2', + includeInputs: ['**/*feature-2*'], + icon: '🧩', + }, + { + title: 'Entrypoints', + includeInputs: ['src/index.ts', 'src/bin.ts'], + icon: '🏁', + }, + { + title: 'Shared Chunks', + includeInputs: ['dist/chunks/chunk-*.js'], + icon: '🤝', + }, + { + title: 'Node Modules', + includeInputs: ['**/node_modules/**'], + icon: '📦', + }, + { + title: 'Distributables', + includeInputs: ['dist/index.js', 'dist/bin.js'], + icon: '📦', + }, + ], + }, + }, + { + slug: `${INSIGHT_AUDIT_PREFIX}-table-rest-group`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Table - Rest Group`, + description: + 'Demonstrates how all non-matching assets are grouped into the "Rest" row.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { + title: 'Feature 1', + includeInputs: ['**/*feature-1*'], + icon: '🧩', + }, + ], + }, + }, + { + slug: `${INSIGHT_AUDIT_PREFIX}-groups-pattern-only`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Pattern Only`, + description: + 'Demonstrates groups with include patterns only (no title or icon).', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { includeInputs: ['**/src/**'] }, + { includeInputs: ['**/dist/**'] }, + ], + }, + }, + { + slug: `${INSIGHT_AUDIT_PREFIX}-groups-title-icon`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Title Icon`, + description: 'Demonstrates groups with title and icon.', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { + title: 'Source Files', + includeInputs: ['**/src/**'], + icon: '📄', + }, + { + title: 'Node Modules', + includeInputs: ['**/node_modules/**'], + icon: '📦', + }, + ], + }, + }, + { + slug: `${INSIGHT_AUDIT_PREFIX}-groups-path-segments`, + title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Path Segments`, + description: + 'Demonstrates grouping by number of path segments (numSegments).', + ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED, + insightsTable: { + groups: [ + { + includeInputs: ['**/node_modules/**', '**/node_modules/@*/**'], + numSegments: 1, + }, + ], + }, + }, +]; + +// ===== Tree Audits ===== +const TREE_AUDIT_PREFIX = 'tree'; +const TREE_AUDIT_ICON = '🌳'; + +const TREE_AUDITS: BundleStatsAuditOptions[] = [ + // ===== Tree - Disables ===== + { + slug: `${TREE_AUDIT_PREFIX}-disables`, + title: `${TREE_AUDIT_ICON} - Tree - Disables`, + description: + 'Shows how to explicitly disable dependency trees using enabled: false. You should see audit results but no ASCII tree structure, even when global dependencyTree config exists.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { enabled: false }, + }, + + // ===== Tree - Mode ===== + { + slug: `${TREE_AUDIT_PREFIX}-mode-all`, + title: `${TREE_AUDIT_ICON} - Tree - Mode - All`, + description: + 'Demonstrates mode: "all" - shows complete file tree regardless of selection filters. Compare with onlyMatching to see the difference in which files appear in the tree.', + selection: { + mode: 'bundle', + includeOutputs: ['**/*'], + }, + scoring: DISABLED, + dependencyTree: { + mode: 'all', + }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-mode-onlymatching`, + title: `${TREE_AUDIT_ICON} - Tree - Mode - OnlyMatching`, + description: + 'Demonstrates mode: "onlyMatching" (default) - tree only shows files that match the selection criteria. Files outside selection are hidden from tree display.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { mode: 'onlyMatching' }, + }, + + // ===== Tree - Groups ===== + { + slug: `${TREE_AUDIT_PREFIX}-groups-include`, + title: `${TREE_AUDIT_ICON} - Tree - Groups - Include`, + description: + 'Demonstrates groups.include patterns organizing files by type. Shows how dependencies (📦) are grouped with clear visual separation. Uses selection filtering to focus only on node_modules files for a clean demonstration.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { + mode: 'onlyMatching', + pruning: { + maxDepth: 3, + }, + groups: [ + { + includeInputs: ['**/node_modules/**'], + title: 'Dependencies', + icon: '📦', + }, + ], + }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-groups-exclude`, + title: `${TREE_AUDIT_ICON} - Tree - Groups - Exclude`, + description: + 'Demonstrates the recommended approach: using selection excludeInputs to filter out node_modules files, combined with mode: "onlyMatching". While grouping can organize remaining files, selection filtering is the primary and most reliable way to exclude unwanted files from both table and tree displays.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { + mode: 'onlyMatching', + groups: [ + { + includeInputs: ['**/index.js'], + excludeInputs: ['**/node_modules/**'], + }, + ], + }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-groups-include-exclude`, + title: `${TREE_AUDIT_ICON} - Tree - Groups - Include & Exclude`, + description: + 'Shows combining include and exclude patterns for precise filtering. First group shows src files but excludes test files, second shows lib files but excludes test directories.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { + groups: [ + { + includeInputs: ['**/src/**'], + excludeInputs: ['**/node_modules/**'], + }, + ], + }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-groups-title`, + title: `${TREE_AUDIT_ICON} - Tree - Groups - Title`, + description: + 'Demonstrates groups.title property for custom section headers. Look for "Source Files" and "Dependencies" labels that replace default path-based grouping names.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { + groups: [ + { + title: 'Source Files', + includeInputs: ['**/src/**'], + }, + { + title: 'Dependencies', + includeInputs: ['**/node_modules/**'], + }, + ], + }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-groups-icon`, + title: `${TREE_AUDIT_ICON} - Tree - Groups - Icon`, + description: + 'Shows groups.icon property adding visual indicators to grouped sections. Look for 📄 icon next to source files and 📦 icon next to dependencies in the tree display.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { + groups: [ + { + includeInputs: ['**/src/**'], + icon: '📄', + }, + { + includeInputs: ['**/node_modules/**'], + icon: '📦', + }, + ], + }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-groups-numsegments`, + title: `${TREE_AUDIT_ICON} - Tree - Groups - NumSegments`, + description: + 'Demonstrates groups.numSegments for path-based grouping. Node modules are grouped by their top-level package name (1 segment), flattening deep nested structures like @scope/package.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { + groups: [ + { + includeInputs: ['**/node_modules/**', '**/node_modules/@*/**'], + numSegments: 1, + }, + ], + }, + }, + + // ===== Tree - Pruning ===== + { + slug: `${TREE_AUDIT_PREFIX}-pruning-maxchildren`, + title: `${TREE_AUDIT_ICON} - Tree - Pruning - MaxChildren`, + description: + 'Shows pruning.maxChildren: 2 limiting displayed children per node. Large directories will show only first 2 entries plus "...X more items" to prevent overwhelming output.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { pruning: { maxChildren: 2 } }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-pruning-maxdepth`, + title: `${TREE_AUDIT_ICON} - Tree - Pruning - MaxDepth`, + description: + 'Demonstrates pruning.maxDepth: 1 limiting tree depth to prevent deep nesting. Only shows immediate children, deeper levels are truncated with continuation indicators.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { pruning: { maxDepth: 1 } }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-pruning-minsize`, + title: `${TREE_AUDIT_ICON} - Tree - Pruning - MinSize`, + description: + 'Shows pruning.minSize: 1000 filtering out files smaller than 1KB. Small utility files and helpers are hidden, displaying only substantial files that impact bundle size.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { pruning: { minSize: 1000 } }, + }, + { + slug: `${TREE_AUDIT_PREFIX}-pruning-pathlength`, + title: `${TREE_AUDIT_ICON} - Tree - Pruning - PathLength`, + description: + 'Demonstrates pruning.pathLength: 30 truncating long file paths for readability. Paths longer than 30 characters show as "...filename.js" to keep tree display compact.', + selection: { + mode: 'bundle', + includeOutputs: ['**/chunks/chunk-*.js'], + }, + scoring: DISABLED, + dependencyTree: { pruning: { pathLength: 30 } }, + }, +]; + +const config: CoreConfig = { + plugins: [ + await bundleStatsPlugin({ + artifactsPaths: + 'packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json', + bundler: 'esbuild', + audits: [ + ...SCORING_AUDITS, + ...SCORING_PENALTY_AUDITS, + ...SELECTION_AUDITS, + ...INSIGHT_AUDITS, + ...TREE_AUDITS, + ], + groups: [ + { + slug: 'selection-group', + title: '🎯 Selection', + description: + 'Demonstrates different selection modes and pattern matching for bundle analysis.', + refs: SELECTION_AUDITS.filter((audit) => audit.slug).map((audit) => ({ + slug: audit.slug!, + weight: 1, + })), + }, + { + slug: 'scoring-group', + title: '📏 Scoring', + description: + 'Shows scoring mechanisms including thresholds, penalties, and size constraints.', + refs: [...SCORING_AUDITS, ...SCORING_PENALTY_AUDITS] + .filter((audit) => audit.slug) + .map((audit) => ({ + slug: audit.slug!, + weight: 1, + })), + }, + { + slug: 'insights-group', + title: '📊 Insights Table', + description: + 'Configures insights tables with grouping, pruning, and visualization options.', + refs: INSIGHT_AUDITS.filter((audit) => audit.slug).map((audit) => ({ + slug: audit.slug!, + weight: 1, + })), + }, + { + slug: 'tree-group', + title: '🌳 Dependency Tree', + description: + 'Demonstrates dependency tree configurations with grouping and pruning strategies.', + refs: TREE_AUDITS.filter((audit) => audit.slug).map((audit) => ({ + slug: audit.slug!, + weight: 1, + })), + }, + ], + }), + ], + categories: [ + { + slug: 'performance', + title: '⚡ Performance', + description: + 'Comprehensive bundle performance analysis including selection, scoring, insights, and dependency trees.', + refs: [ + { + type: 'group' as const, + plugin: 'bundle-stats', + slug: 'selection-group', + weight: 1, + }, + { + type: 'group' as const, + plugin: 'bundle-stats', + slug: 'scoring-group', + weight: 1, + }, + { + type: 'group' as const, + plugin: 'bundle-stats', + slug: 'insights-group', + weight: 1, + }, + { + type: 'group' as const, + plugin: 'bundle-stats', + slug: 'tree-group', + weight: 1, + }, + ], + }, + ], +}; + +export default (async () => { + return config; +})(); diff --git a/packages/plugin-bundle-stats/debug-test.js b/packages/plugin-bundle-stats/debug-test.js new file mode 100644 index 0000000..3c842df --- /dev/null +++ b/packages/plugin-bundle-stats/debug-test.js @@ -0,0 +1,57 @@ +import { unifyBundlerStats } from './src/lib/runner/unify/unify.esbuild.ts'; + +const esbuildStats = { + inputs: {}, + outputs: { + 'dist/index.js': { + imports: [ + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + { + path: 'dist/chunks/feature-2-X2YVDBQK.js', + kind: 'dynamic-import', + }, + ], + exports: ['default', 'indexOnlyFunction'], + entryPoint: 'src/index.ts', + inputs: { + 'src/index.ts': { + bytesInOutput: 350, + }, + }, + bytes: 496, + }, + }, +}; + +const result = unifyBundlerStats(esbuildStats); +console.log('ACTUAL RESULT:'); +console.log(JSON.stringify(result, null, 2)); + +const expected = { + 'dist/index.js': { + bytes: 496, + entryPoint: 'src/index.ts', + imports: [ + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + { + path: 'dist/chunks/feature-2-X2YVDBQK.js', + kind: 'dynamic-import', + }, + ], + exports: ['default', 'indexOnlyFunction'], + inputs: { + 'src/index.ts': { + bytesInOutput: 350, + }, + }, + }, +}; + +console.log('\nEXPECTED:'); +console.log(JSON.stringify(expected, null, 2)); diff --git a/packages/plugin-bundle-stats/docs/select.md b/packages/plugin-bundle-stats/docs/select.md new file mode 100644 index 0000000..e927189 --- /dev/null +++ b/packages/plugin-bundle-stats/docs/select.md @@ -0,0 +1,334 @@ +### Selection + +To select files for an audit, glob patterns are used to include and exclude parts of the output files. +All options are provided as glob patterns matching either `path`, `path` in `inputs` or `entryPoint`. + +**Types** + +```ts +export interface SelectionOptions { + mode: 'bundle' | 'onlyMatching' | 'withAllDeps' | 'withStartupDeps'; + + // targeting output path of a `OutputNode` + includeOutputs: string[]; + excludeOutputs: string[]; + + // targeting input paths of a `OutputNode` + includeInputs: string[]; + excludeInputs: string[]; +} +``` + +**Example Configuration** + +```ts +const selection: SelectionOptions = { + mode: 'bundle', + includeOutputs: ['**/features/*'], + excludeOutputs: ['**/features/legacy/**'], + excludeInputs: ['**/ui/**'], +}; +``` + +#### Selection Behaviour + +- **🎯Glob syntax**: Supports standard glob patterns like `*`, `**`, `?`, `[abc]`. +- **Include → Exclude**: Selection starts with `include*` patterns (for outputs and inputs), followed by `exclude*` to remove matches. +- **Precedence**: If a file matches both `include` and `exclude`, it will be excluded. +- **🔗 Dependency handling** is controlled by `mode`: + - `'bundle'` and `'onlyMatching'` ignore imports. + - `'withAllDependencies'` and `'withStartupDependencies'`: preserve imports even if excluded + +--- + +> All examples target this stats data. +> +> **Example Stats** +> +> The following is a minimal stats representation used to explain different features of the selection process. +> +> ``` +> stats.json +> └── outputs +> ├── dist/index.js 309kB // entryPoint: src/index.ts +> │ ├── inputs +> │ │ └── src/index.ts +> │ │ ├── src/lib/feature-1.ts 100kB // import-statement +> │ │ │ └── src/lib/utils/format.ts 100kB // import-statement +> │ │ ├── src/lib/utils/math.ts 100kB // import-statement +> │ │ └── src/lib/feature-2.ts 100kB // dynamic-import +> │ └── imports +> │ ├── dist/chunks/chunk-U6O5K65G.js // import-statement +> │ └── dist/chunks/feature-2-X2YVDBQK.js // dynamic-import +> ├── dist/bin.js 309kB // entryPoint: src/bin.ts +> │ ├── inputs +> │ │ ├── src/lib/feature-1.ts 100kB // import-statement +> │ │ │ └── src/lib/utils/format.ts 100kB // import-statement +> │ │ └── src/lib/utils/math.ts 100kB // import-statement +> │ └── imports +> │ └── dist/chunks/chunk-U6O5K65G.js // import-statement +> ├── dist/chunks/chunk-U6O5K65G.js 309kB +> │ └── inputs +> │ ├── src/lib/utils/format.ts 100kB +> │ ├── src/lib/feature-1.ts 100kB +> │ └── src/lib/utils/math.ts 100kB +> └── dist/chunks/feature-2-X2YVDBQK.js 109kB // entryPoint: src/lib/feature-2.ts +> └── inputs +> └── src/lib/feature-2.ts 100kB +> ``` + +```` + +--- + +##### Include Output + +Select only `dist/index.js` and its dependencies. + +**Selection Options** + +```ts +{ + includeOutputs: ['**/dist/index.js'] +} +```` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js // entryPoint: src/index.ts + │ ├── inputs + │ └── imports + │ └── dist/chunks/chunk-U6O5K65G.js // import-statement + └── 🔗 dist/chunks/chunk-U6O5K65G.js // imported by `dist/index.js` + └── inputs +``` + +The target output and its imported dependencies are included. + +##### Include/Exclude Output + +Select all outputs except bin files. + +**Selection Options** + +```ts +{ + includeOutputs: ["**/*"], + excludeOutputs: ["**/bin.js"] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js // entryPoint: src/index.ts + ├── 🔗 dist/chunks/chunk-U6O5K65G.js // imported by `dist/index.js` + ├── 🔗 dist/chunks/feature-2-X2YVDBQK.js // imported by `dist/index.js` + └── // excluded: dist/bin.js +``` + +All outputs are included except those matching the exclude pattern. + +##### Include Input + +Select outputs that contain specific input files. + +**Selection Options** + +```ts +{ + includeInputs: ['**/feature-2.ts']; +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── dist/index.js // entryPoint: src/index.ts + │ └── inputs + │ └── src/index.ts + │ └── 🎯 src/lib/feature-2.ts // dynamic-import + └── 🔗 dist/chunks/feature-2-X2YVDBQK.js // contains feature-2.ts + └── inputs + └── 🎯 src/lib/feature-2.ts +``` + +Only outputs containing the specified input files are included. + +##### Include/Exclude Input + +Select all outputs but exclude those containing feature-2 files. + +**Selection Options** + +```ts +{ + includeOutputs: ["**/*"], + excludeInputs: ["**/feature-2.ts"] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/bin.js // entryPoint: src/bin.ts + ├── 🔗 dist/chunks/chunk-U6O5K65G.js // imported by `dist/bin.js` + ├── // excluded: dist/index.js (contains feature-2.ts) + └── // excluded: dist/chunks/feature-2-X2YVDBQK.js (contains feature-2.ts) +``` + +Outputs containing the excluded input files are filtered out. + +##### Include/Exclude Mixed + +Select feature outputs but exclude utility files. + +**Selection Options** + +```ts +{ + includeOutputs: ['**/features/*', '**/index.js'], + excludeOutputs: ['**/bin.js'], + excludeInputs: ['**/utils/**'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js // matches includeOutputs + │ └── inputs + │ └── src/index.ts + │ ├── src/lib/feature-1.ts 100kB + │ └── src/lib/feature-2.ts 100kB + └── 🔗 dist/chunks/feature-2-X2YVDBQK.js // imported by `dist/index.js` + └── inputs + └── src/lib/feature-2.ts 100kB +``` + +Complex filtering combines output and input patterns for precise selection. + +--- + +##### Mode: `onlyMatching` + +Select only input files that match a pattern — exclude outputs, imports, and bundler overhead. + +**Selection Options** + +```ts +{ + mode: 'onlyMatching', + includeInputs: ['**/lib/utils/format.ts'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── dist/chunks/chunk-U6O5K65G.js 100kB // excludes overhead + └── inputs + └── 🎯 src/lib/utils/format.ts 100kB // matches `includeInputs` +``` + +Only the bytes from matching input files are counted, excluding bundler overhead. + +##### Mode: `bundle` + +Include the full output bundle with overhead and its bundled inputs but not external chunks. + +**Selection Options** + +```ts +{ + mode: 'bundle', + includeOutputs: ['**/dist/index.js'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + └── 🎯 dist/index.js 209kB // matches `includeOutputs` + └── inputs + ├── src/lib/utils/format.ts 100kB + └── src/lib/utils/math.ts 100kB +``` + +Only what's bundled directly in the output file is included. + +##### Mode: `withStartupDeps` + +Include the output and all static imports required at startup. + +**Selection Options** + +```ts +{ + mode: 'withStartupDeps', + includeOutputs: ['**/dist/index.js'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js 209kB + │ └── inputs + │ ├── src/lib/utils/format.ts 100kB + │ └── src/lib/utils/math.ts 100kB + └── 🔗 dist/chunks/chunk-U6O5K65G.js 109kB // statically imported by `dist/index.js` + └── inputs + └── src/lib/utils/log.ts 100kB +``` + +Static imports are preserved even if they would be excluded by patterns. + +##### Mode: `withAllDeps` + +Include the output and all imported files — both static and dynamic. + +**Selection Options** + +```ts +{ + mode: 'withAllDeps', + includeOutputs: ['**/dist/index.js'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js 209kB + │ └── inputs + │ ├── src/lib/utils/format.ts 100kB + │ └── src/lib/utils/math.ts 100kB + ├── 🔗 dist/chunks/chunk-U6O5K65G.js 109kB // static import + │ └── inputs + │ └── src/lib/utils/log.ts 100kB + └── 🔗 dist/chunks/feature-2-X2YVDBQK.js 109kB // dynamic import + └── inputs + └── src/lib/feature-2.ts 100kB +``` + +Both static and dynamic dependencies are included in their entirety. diff --git a/packages/plugin-bundle-stats/docs/table.md b/packages/plugin-bundle-stats/docs/table.md new file mode 100644 index 0000000..10cd0e1 --- /dev/null +++ b/packages/plugin-bundle-stats/docs/table.md @@ -0,0 +1,429 @@ +### Insights Table + +The grouping table provides a summary view of bundle statistics organized by user-defined groups. It aggregates file sizes and counts for quick analysis of different parts of your bundle. + +**Types** + +```ts +export type PatternList = readonly string[]; + +export type SharedViewConfig = { + enabled?: boolean; + mode?: 'onlyMatching' | 'all'; +}; + +export interface TablePruningConfig { + enabled?: boolean; + maxChildren?: number; + minSize?: number; +} + +export type InsightsTableConfig = SharedViewConfig & { + groups: GroupingRule[]; + pruning?: TablePruningConfig; +}; + +export interface GroupingRule { + includeInputs: string | PatternList; + excludeInputs?: string | PatternList; + title?: string; + icon?: string; + numSegments?: number; +} +``` + +**Example Configuration** + +```ts +const tableConfig: InsightsTableConfig = { + mode: 'all', + groups: [ + { + title: 'Features', + includeInputs: ['**/feature-*.ts'], + excludeInputs: ['**/*.spec.ts'], + icon: '🎯', + }, + { + title: 'Utils', + includeInputs: ['**/utils/**'], + icon: '🔧', + }, + ], + pruning: { + enabled: true, + maxChildren: 10, + minSize: 1000, + }, +}; +``` + +--- + +> All examples target this stats data structure. +> +> **Example Stats** +> +> ``` +> stats.json +> └── outputs +> ├── dist/app.js 300kB +> │ ├── inputs +> │ │ ├── src/index.ts 50kB +> │ │ ├── src/feature-1.ts 100kB +> │ │ ├── src/feature-2.ts 75kB +> │ │ └── src/utils/format.ts 25kB +> │ └── imports +> │ └── dist/chunks/vendor.js +> └── dist/chunks/vendor.js 200kB +> └── inputs +> └── node_modules/lodash/index.js 150kB +> ``` + +--- + +#### Mode: `all` + +Shows complete bundle statistics including outputs, inputs, imports and bundler overhead. + +**Table Configuration** + +```ts +{ + mode: 'all', + groups: [ + { + title: 'Features', + includeInputs: ['**/feature-*.ts'] + } + ] +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ----------- | ------- | ------ | +| 🎯 Features | 2 | 175 kB | +| Rest | - | 325 kB | + +#### Mode: `onlyMatching` + +Shows only the bytes that match selection patterns, excluding bundler overhead. + +**Table Configuration** + +```ts +{ + mode: 'onlyMatching', + groups: [ + { + title: 'Features', + includeInputs: ['**/feature-*.ts'] + } + ] +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ----------- | ------- | ------ | +| 🎯 Features | 2 | 175 kB | + +--- + +#### Grouping - Include + +Select files using single or multiple glob patterns. + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Source Code', + includeInputs: ['**/src/**/*.ts', '**/src/**/*.tsx'], + }, + ]; +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ----------- | ------- | ------ | +| Source Code | 4 | 250 kB | +| Rest | - | 250 kB | + +#### Grouping - Include/Exclude + +Combine include and exclude patterns for precise file selection. + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Application Code', + includeInputs: '**/src/**', + excludeInputs: ['**/utils/**', '**/*.spec.ts'], + }, + ]; +} +``` + +**File Matching:** + +```txt +stats.json +└── outputs + └── dist/app.js + ├── 🎯 src/index.ts // included by **/src/** + ├── 🎯 src/feature-1.ts // included by **/src/** + ├── 🎯 src/feature-2.ts // included by **/src/** + └── ❌ src/utils/format.ts // excluded by **/utils/** +``` + +**Table Result:** + +| Group | Modules | Size | +| ---------------- | ------- | ------ | +| Application Code | 3 | 225 kB | +| Rest | - | 275 kB | + +#### Grouping - Icons and Titles + +Customize group display with icons and titles, or let titles be auto-generated from patterns. + +**Manual Titles with Icons:** + +```ts +{ + groups: [ + { + title: 'Core Features', + includeInputs: '**/features/**/*.ts', + icon: '🎯', + }, + { + title: 'Shared Utils', + includeInputs: '**/shared/**', + icon: '🔧', + }, + { + title: 'Third Party', + includeInputs: 'node_modules/**', + icon: '📦', + }, + ]; +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ---------------- | ------- | ------ | +| 🎯 Core Features | 8 | 450 kB | +| 🔧 Shared Utils | 12 | 125 kB | +| 📦 Third Party | 45 | 2.1 MB | +| Rest | - | 75 kB | + +**Auto-Generated Titles:** + +```ts +{ + groups: [ + { + includeInputs: '**/components/feature-*.tsx', + }, + { + includeInputs: ['**/utils/**', '**/helpers/**'], + }, + ]; +} +``` + +**Table Result:** + +| Group | Modules | Size | +| --------------------- | ------- | ------ | +| components/feature-\* | 5 | 175 kB | +| utils/**, helpers/** | 8 | 125 kB | +| Rest | - | 200 kB | + +#### Grouping - NumSegments + +Control how paths are grouped using the `numSegments` property for hierarchical organization. + +**Without numSegments:** + +```txt +└── src/components/ui/Button.tsx +├── src/components/ui/Modal.tsx +├── src/components/forms/Input.tsx +└── src/components/forms/Select.tsx +``` + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Components', + includeInputs: '**/components/**', + numSegments: 2, + }, + ]; +} +``` + +**With numSegments (creates subgroups):** + +```txt +└── Components + ├── ui (Button.tsx, Modal.tsx) + └── forms (Input.tsx, Select.tsx) +``` + +--- + +#### Rest Group - Unmatched Files + +Files that don't match any group pattern are collected in the "Rest" group. + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Features Only', + includeInputs: '**/feature-*.ts', + }, + ]; +} +``` + +**File Matching:** + +```txt +stats.json +└── outputs + └── dist/app.js 300kB + ├── 🎯 src/feature-1.ts // matches group + ├── 🎯 src/feature-2.ts // matches group + ├── ❓ src/index.ts // unmatched -> Rest + └── ❓ src/utils/format.ts // unmatched -> Rest +``` + +**Table Result:** + +| Group | Modules | Size | +| ------------- | ------- | ------ | +| Features Only | 2 | 175 kB | +| Rest | - | 275 kB | + +#### Rest Group - Bundler Overhead + +When using `onlyMatching` mode, bundler overhead becomes part of the Rest group. + +**Group Configuration** + +```ts +{ + mode: 'onlyMatching', + groups: [ + { + title: 'Source Files', + includeInputs: '**/src/**' + } + ] +} +``` + +**File Analysis:** + +```txt +dist/app.js total: 300kB +├── src files: 250kB // matches group +└── bundler overhead: 50kB // becomes Rest +``` + +**Table Result:** + +| Group | Modules | Size | +| ------------ | ------- | ------ | +| Source Files | 4 | 250 kB | +| Rest | - | 50 kB | + +--- + +#### Pruning - Max Children + +Limit the number of groups displayed in the table. + +**Group Configuration** + +```ts +{ + groups: [ + { title: 'Features', includeInputs: '**/feature-*.ts' }, + { title: 'Utils', includeInputs: '**/utils/**' }, + { title: 'Components', includeInputs: '**/components/**' }, + { title: 'Services', includeInputs: '**/services/**' }, + { title: 'Helpers', includeInputs: '**/helpers/**' } + ], + pruning: { + enabled: true, + maxChildren: 3 + } +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ---------- | ------- | ------ | +| Features | 2 | 175 kB | +| Components | 5 | 125 kB | +| Services | 3 | 100 kB | +| Rest | - | 200 kB | + +_Utils and Helpers groups were moved to Rest due to maxChildren limit_ + +#### Pruning - Min Size + +Filter out groups smaller than the specified threshold. + +**Group Configuration** + +```ts +{ + groups: [ + { title: 'Large Feature', includeInputs: '**/large-feature.ts' }, // 100kB + { title: 'Medium Feature', includeInputs: '**/medium-feature.ts' }, // 50kB + { title: 'Small Feature', includeInputs: '**/small-feature.ts' }, // 10kB + { title: 'Tiny Feature', includeInputs: '**/tiny-feature.ts' } // 2kB + ], + pruning: { + enabled: true, + minSize: 25000 // 25kB threshold + } +} +``` + +**Table Result:** + +| Group | Modules | Size | +| -------------- | ------- | ------ | +| Large Feature | 1 | 100 kB | +| Medium Feature | 1 | 50 kB | +| Rest | - | 262 kB | + +_Small and Tiny features were moved to Rest due to minSize threshold_ + +--- diff --git a/packages/plugin-bundle-stats/docs/tree.md b/packages/plugin-bundle-stats/docs/tree.md new file mode 100644 index 0000000..59ad55f --- /dev/null +++ b/packages/plugin-bundle-stats/docs/tree.md @@ -0,0 +1,458 @@ +### Dependency Tree + +The dependency tree provides users with a quick understanding of the dependencies graph of selected artifacts. It serves as a replacement for opening bundle stats in the browser to search for respective files. + +**Types** + +```ts +export type ViewMode = 'all' | 'onlyMatching'; + +export type GeneralViewConfig = { + enabled: boolean; + mode: ViewMode; +}; + +export type DependencyTreeConfig = GeneralViewConfig & { + groups: GroupingRule[] | false; + pruning: PruningConfig; +}; + +export interface GroupingRule { + includeInputs: string | string[]; + excludeInputs?: string | string[]; + title?: string; + icon?: string; + numSegments?: number; +} + +export interface PruningConfig { + maxChildren?: number; + maxDepth?: number; + startDepth?: number; + minSize?: number; + pathLength?: number | false; +} +``` + +**Example Configuration** + +```ts +const treeConfig: DependencyTreeConfig = { + mode: 'all', + groups: [ + { + title: 'Angular Router', + include: ['node_modules/@angular/router/**'], + exclude: ['**/*.spec.ts'], + icon: '🅰️', + numSegments: 3, + }, + ], + pruning: { + maxChildren: 3, + maxDepth: 2, + startDepth: 1, + minSize: 10_000, + pathLength: 50, + }, +}; +``` + +--- + +> All examples target this stats data structure. +> +> **Example Stats** +> +> ``` +> stats.json +> └── outputs +> └── dist/index.js 400kB +> ├── inputs +> │ ├── src/index.ts 50kB +> │ ├── src/lib/feature-1.ts 100kB +> │ └── src/lib/utils/format.ts 75kB +> └── imports +> └── dist/chunks/vendor.js +> ``` + +--- + +#### Mode: `all` + +Shows complete dependency tree including all outputs, inputs, and imports with full bundler overhead. + +**Tree Configuration** + +```ts +{ + mode: 'all'; +} +``` + +**Tree Result:** + +```txt +example-group +├── dist/index.js +│ ├── src/index.ts +│ ├── src/lib/feature-1.ts +│ └── src/lib/utils/format.ts +├── dist/chunks/vendor.js +│ └── node_modules/@angular/router/index.ts +└── dist/styles.css +``` + +#### Mode: `onlyMatching` + +Shows only the bytes that match selection patterns, excluding bundler overhead. + +**Tree Configuration** + +```ts +{ + mode: 'onlyMatching'; +} +``` + +**Tree Result:** + +```txt +example-group +├── dist/index.js +│ ├── src/index.ts +│ ├── src/lib/feature-1.ts +│ └── src/lib/utils/format.ts +├── dist/chunks/vendor.js +│ └── node_modules/@angular/router/index.ts +└── dist/styles.css +``` + +--- + +#### Grouping - Disabled + +**Tree Result:** + +```txt +example-group +└── entry-2.js + ├── node_modules/@angular/router/provider.ts + ├── node_modules/@angular/router/service.ts + │ └── node_modules/@angular/router/utils.ts + └── node_modules/lodash/chunk.js +``` + +#### Grouping - Basic + +**Grouping Configuration** + +```ts +{ + groups: [ + { + title: 'Angular Router', + include: ['node_modules/@angular/router/**'], + exclude: ['**/*.spec.ts'], + icon: '🅰️', + }, + ]; +} +``` + +**Tree Result:** + +```txt +example-group +└── entry-2.js + ├── 🅰️ Angular Router + │ ├── node_modules/@angular/router/provider.ts + │ ├── node_modules/@angular/router/service.ts + │ └── node_modules/@angular/router/utils.ts + └── node_modules/lodash/chunk.js +``` + +#### Grouping - Include/Exclude + +GroupingRule supports flexible pattern matching with include/exclude logic: + +- **`include`**: Patterns to match files for inclusion in the group +- **`exclude`**: Patterns to exclude from the group (optional) +- **Pattern precedence**: Files matching both include and exclude will be excluded + +**Advanced Grouping Configuration** + +```ts +{ + groups: [ + { + title: 'React Components', + include: ['**/components/**/*.tsx', '**/components/**/*.jsx'], + exclude: ['**/*.test.*', '**/*.spec.*'], + icon: '⚛️', + }, + { + title: 'Node Modules', + include: ['node_modules/**'], + exclude: ['node_modules/**/*.d.ts'], + icon: '📦', + }, + ]; +} +``` + +#### Grouping - NumSegments + +The `numSegments` property controls how files are grouped by their path structure. + +**Without numSegments:** + +```txt +example-group +└── entry.js + ├── src/components/ui/Button.tsx + ├── src/components/ui/Modal.tsx + ├── src/components/forms/Input.tsx + └── src/components/forms/Select.tsx +``` + +**Grouping Configuration** + +```ts +{ + groups: [ + { + title: 'Components', + include: ['**/components/**'], + numSegments: 2, + }, + ]; +} +``` + +**With numSegments:** + +```txt +example-group +└── entry.js + └── Components + ├── ui + │ ├── Button.tsx + │ └── Modal.tsx + └── forms + ├── Input.tsx + └── Select.tsx +``` + +--- + +#### Pruning - MaxChildren + +**Unpruned:** + +```txt +example-group +├── index.js +│ ├── src/app.ts +│ ├── src/components/Header.ts +│ ├── src/components/Footer.ts +│ ├── src/utils/math.ts +│ └── src/main.css +├── vendor.js +│ ├── node_modules/react.ts +│ ├── node_modules/react-dom.ts +│ └── node_modules/lodash.js +└── logo.svg +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + maxChildren: 3, + maxDepth: 2 + } +} +``` + +**Pruned Result:** + +```txt +example-group +├── index.js +│ ├── src/app.ts +│ ├── src/components/Header.ts +│ └── … 3 more inputs +├── vendor.js +│ ├── node_modules/react.ts +│ └── … 2 more inputs +└── logo.svg +``` + +#### Pruning - MinSize + +**With small files:** + +```txt +example-group 840 kB 10 files +└── index.js 840 kB 9 files + ├── src/app.js 400 kB + ├── src/large-1.js 200 kB + ├── src/medium-1.js 100 kB + ├── src/small-1.js 30 kB + ├── src/small-2.js 25 kB + ├── src/small-3.js 20 kB + └── … 4 more files 65 kB +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + minSize: 50_000; + } +} +``` + +**Pruned Result:** + +```txt +example-group 840 kB 10 files +└── index.js 840 kB 9 files + ├── src/app.js 400 kB + ├── src/large-1.js 200 kB + ├── src/medium-1.js 100 kB + └── … 6 more files 140 kB +``` + +--- + +#### Pruning - StartDepth + +Controls the depth at which the tree analysis begins, useful for skipping top-level wrapper nodes. + +**Without startDepth:** + +```txt +example-group +└── main-bundle + └── app-core + ├── src/components/Button.tsx + ├── src/components/Modal.tsx + └── src/utils/helpers.ts +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + startDepth: 2; + } +} +``` + +**With startDepth:** + +```txt +example-group +├── src/components/Button.tsx +├── src/components/Modal.tsx +└── src/utils/helpers.ts +``` + +#### Pruning - PathLength + +Controls how long file paths can be before truncation, or disables truncation entirely. + +**Full path:** + +```txt +example-group +└── src/lib/utils/helper/format/left-pad.js +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + pathLength: 30; + } +} +``` + +**Shortened path:** + +```txt +example-group +└── src/.../left-pad.js +``` + +**Disable truncation:** + +```ts +{ + pruning: { + pathLength: false; + } +} +``` + +--- + +#### Formatting - Size + +**Raw bytes:** + +```txt +example-group 537170 +└── main.js 300000 +``` + +**Formatted:** + +```txt +example-group 537.17 kB +└── main.js 300 kB +``` + +#### Formatting - Pluralization + +**Unpluralized:** + +```txt +example-group 3 +├── main.js 1 +└── utils.js 2 +``` + +**Pluralized:** + +```txt +example-group 3 modules +├── main.js 1 module +└── utils.js 2 modules +``` + +#### Formatting - RedundantInfo + +**With redundancy:** + +```txt +example-group 300 kB 3 modules +└── index.js 100 kB 1 module + ├── src/app.js 100 kB 1 module + └── … 2 more inputs 200 kB 2 modules +``` + +**Cleaned up:** + +```txt +example-group 300 kB 3 modules +└── index.js 100 kB + ├── src/app.js + └── … 2 more inputs 200 kB +``` diff --git a/packages/plugin-bundle-stats/eslint.config.js b/packages/plugin-bundle-stats/eslint.config.js new file mode 100644 index 0000000..7815170 --- /dev/null +++ b/packages/plugin-bundle-stats/eslint.config.js @@ -0,0 +1,59 @@ +import tseslint from 'typescript-eslint'; +import baseConfig from '../../eslint.config.js'; + +export default tseslint.config( + ...baseConfig, + { + files: ['**/*.ts'], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, + rules: { + // Temporarily disable rules to accept bad code quality :) + 'functional/immutable-data': 'off', // 112 occurrences + 'functional/no-loop-statements': 'off', // 74 occurrences + 'functional/no-let': 'off', // 31 occurrences + '@typescript-eslint/no-magic-numbers': 'off', // 22 occurrences + '@typescript-eslint/no-non-null-assertion': 'off', // 17 occurrences + // Increase limits for max-lines and complexity rules + 'max-lines': [ + 'warn', + { max: 800, skipBlankLines: true, skipComments: true }, + ], + 'max-lines-per-function': [ + 'warn', + { max: 600, skipBlankLines: true, skipComments: true }, + ], + complexity: ['warn', { max: 30 }], + 'max-depth': ['warn', { max: 6 }], + 'no-console': [ + 'warn', + { allow: ['error', 'warn', 'info', 'time', 'timeEnd'] }, + ], + }, + }, + { + files: ['**/*.test.ts', '**/*.spec.ts'], + rules: { + // More relaxed rules for test files + 'max-lines': [ + 'warn', + { max: 1000, skipBlankLines: true, skipComments: true }, + ], + 'max-lines-per-function': [ + 'warn', + { max: 800, skipBlankLines: true, skipComments: true }, + ], + 'vitest/no-conditional-expect': 'off', + }, + }, + { + files: ['**/*.json'], + rules: { + '@nx/dependency-checks': 'error', + }, + }, +); diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.editorconfig b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.editorconfig new file mode 100644 index 0000000..f166060 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.editorconfig @@ -0,0 +1,17 @@ +# Editor configuration, see https://editorconfig.org +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 2 +insert_final_newline = true +trim_trailing_whitespace = true + +[*.ts] +quote_type = single +ij_typescript_use_double_quotes = false + +[*.md] +max_line_length = off +trim_trailing_whitespace = false diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.gitignore b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/.gitignore new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/README.md b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/README.md new file mode 100644 index 0000000..765156f --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/README.md @@ -0,0 +1,68 @@ +# Angular Minimal App + +This is a minimal Angular application used for testing bundle statistics. + +## Prerequisites + +- Node.js (version 18 or higher) +- npm or yarn package manager + +## Installation + +Install the dependencies: + +```bash +npm install +``` + +## How to Build the App + +### Development Build + +For development with live reload: + +```bash +npm run start +``` + +This will start the development server at `http://localhost:4200`. + +### Production Build + +For a production-optimized build: + +```bash +npm run build +``` + +The build artifacts will be stored in the `dist/` directory. + +### Build with Bundle Statistics + +To build with bundle statistics (useful for analyzing bundle size): + +```bash +npm run build:stats +``` + +This generates a `stats.json` file along with the build output, which can be used for bundle analysis. + +### Development Build with Watch Mode + +For development with automatic rebuilding on file changes: + +```bash +npm run watch +``` + +## Testing + +Run unit tests: + +```bash +npm run test +``` + +## Build Output + +The built application will be available in the `dist/angular-minimal/` directory after running any build command. diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/angular.json b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/angular.json new file mode 100644 index 0000000..c3992b9 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/angular.json @@ -0,0 +1,87 @@ +{ + "$schema": "./node_modules/@angular/cli/lib/config/schema.json", + "version": 1, + "newProjectRoot": "projects", + "projects": { + "angular-minimal": { + "projectType": "application", + "schematics": {}, + "root": "", + "sourceRoot": "src", + "prefix": "app", + "architect": { + "build": { + "builder": "@angular-devkit/build-angular:application", + "options": { + "outputPath": "dist/angular-minimal", + "index": "src/index.html", + "browser": "src/main.ts", + "polyfills": ["zone.js"], + "tsConfig": "tsconfig.app.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": ["src/styles.css"], + "scripts": [] + }, + "configurations": { + "production": { + "budgets": [ + { + "type": "initial", + "maximumWarning": "500kB", + "maximumError": "1MB" + }, + { + "type": "anyComponentStyle", + "maximumWarning": "4kB", + "maximumError": "8kB" + } + ], + "outputHashing": "all" + }, + "development": { + "optimization": false, + "extractLicenses": false, + "sourceMap": true + } + }, + "defaultConfiguration": "production" + }, + "serve": { + "builder": "@angular-devkit/build-angular:dev-server", + "configurations": { + "production": { + "buildTarget": "angular-minimal:build:production" + }, + "development": { + "buildTarget": "angular-minimal:build:development" + } + }, + "defaultConfiguration": "development" + }, + "extract-i18n": { + "builder": "@angular-devkit/build-angular:extract-i18n" + }, + "test": { + "builder": "@angular-devkit/build-angular:karma", + "options": { + "polyfills": ["zone.js", "zone.js/testing"], + "tsConfig": "tsconfig.spec.json", + "assets": [ + { + "glob": "**/*", + "input": "public" + } + ], + "styles": ["src/styles.css"], + "scripts": [] + } + } + } + } + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package-lock.json b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package-lock.json new file mode 100644 index 0000000..988bfd8 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package-lock.json @@ -0,0 +1,14866 @@ +{ + "name": "angular-minimal", + "version": "0.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "angular-minimal", + "version": "0.0.0", + "dependencies": { + "@angular/animations": "^19.1.0", + "@angular/common": "^19.1.0", + "@angular/compiler": "^19.1.0", + "@angular/core": "^19.1.0", + "@angular/forms": "^19.1.0", + "@angular/platform-browser": "^19.1.0", + "@angular/platform-browser-dynamic": "^19.1.0", + "@angular/router": "^19.1.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.1.5", + "@angular/cli": "^19.1.5", + "@angular/compiler-cli": "^19.1.0", + "@types/jasmine": "~5.1.0", + "jasmine-core": "~5.5.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.7.2" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@angular-devkit/architect": { + "version": "0.1902.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/architect/-/architect-0.1902.15.tgz", + "integrity": "sha512-RbqhStc6ZoRv57ZqLB36VOkBkAdU3nNezCvIs0AJV5V4+vLPMrb0hpIB0sF+9yMlMjWsolnRsj0/Fil+zQG3bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.15", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/architect/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/build-angular": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-angular/-/build-angular-19.2.15.tgz", + "integrity": "sha512-mqudAcyrSp/E7ZQdQoHfys0/nvQuwyJDaAzj3qL3HUStuUzb5ULNOj2f6sFBo+xYo+/WT8IzmzDN9DCqDgvFaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1902.15", + "@angular-devkit/build-webpack": "0.1902.15", + "@angular-devkit/core": "19.2.15", + "@angular/build": "19.2.15", + "@babel/core": "7.26.10", + "@babel/generator": "7.26.10", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-transform-async-generator-functions": "7.26.8", + "@babel/plugin-transform-async-to-generator": "7.25.9", + "@babel/plugin-transform-runtime": "7.26.10", + "@babel/preset-env": "7.26.9", + "@babel/runtime": "7.26.10", + "@discoveryjs/json-ext": "0.6.3", + "@ngtools/webpack": "19.2.15", + "@vitejs/plugin-basic-ssl": "1.2.0", + "ansi-colors": "4.1.3", + "autoprefixer": "10.4.20", + "babel-loader": "9.2.1", + "browserslist": "^4.21.5", + "copy-webpack-plugin": "12.0.2", + "css-loader": "7.1.2", + "esbuild-wasm": "0.25.4", + "fast-glob": "3.3.3", + "http-proxy-middleware": "3.0.5", + "istanbul-lib-instrument": "6.0.3", + "jsonc-parser": "3.3.1", + "karma-source-map-support": "1.4.0", + "less": "4.2.2", + "less-loader": "12.2.0", + "license-webpack-plugin": "4.0.2", + "loader-utils": "3.3.1", + "mini-css-extract-plugin": "2.9.2", + "open": "10.1.0", + "ora": "5.4.1", + "picomatch": "4.0.2", + "piscina": "4.8.0", + "postcss": "8.5.2", + "postcss-loader": "8.1.1", + "resolve-url-loader": "5.0.0", + "rxjs": "7.8.1", + "sass": "1.85.0", + "sass-loader": "16.0.5", + "semver": "7.7.1", + "source-map-loader": "5.0.0", + "source-map-support": "0.5.21", + "terser": "5.39.0", + "tree-kill": "1.2.2", + "tslib": "2.8.1", + "webpack": "5.98.0", + "webpack-dev-middleware": "7.4.2", + "webpack-dev-server": "5.2.2", + "webpack-merge": "6.0.1", + "webpack-subresource-integrity": "5.1.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "esbuild": "0.25.4" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", + "@angular/localize": "^19.0.0 || ^19.2.0-next.0", + "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", + "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", + "@angular/ssr": "^19.2.15", + "@web/test-runner": "^0.20.0", + "browser-sync": "^3.0.2", + "jest": "^29.5.0", + "jest-environment-jsdom": "^29.5.0", + "karma": "^6.3.0", + "ng-packagr": "^19.0.0 || ^19.2.0-next.0", + "protractor": "^7.0.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.5 <5.9" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "@web/test-runner": { + "optional": true + }, + "browser-sync": { + "optional": true + }, + "jest": { + "optional": true + }, + "jest-environment-jsdom": { + "optional": true + }, + "karma": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "protractor": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/build-angular/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/build-webpack": { + "version": "0.1902.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/build-webpack/-/build-webpack-0.1902.15.tgz", + "integrity": "sha512-pIfZeizWsViXx8bsMoBLZw7Tl7uFf7bM7hAfmNwk0bb0QGzx5k1BiW6IKWyaG+Dg6U4UCrlNpIiut2b78HwQZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.1902.15", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "webpack": "^5.30.0", + "webpack-dev-server": "^5.0.2" + } + }, + "node_modules/@angular-devkit/build-webpack/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/core": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-19.2.15.tgz", + "integrity": "sha512-pU2RZYX6vhd7uLSdLwPnuBcr0mXJSjp3EgOXKsrlQFQZevc+Qs+2JdXgIElnOT/aDqtRtriDmLlSbtdE8n3ZbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "8.17.1", + "ajv-formats": "3.0.1", + "jsonc-parser": "3.3.1", + "picomatch": "4.0.2", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^4.0.0" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@angular-devkit/core/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular-devkit/schematics": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-19.2.15.tgz", + "integrity": "sha512-kNOJ+3vekJJCQKWihNmxBkarJzNW09kP5a9E1SRNiQVNOUEeSwcRR0qYotM65nx821gNzjjhJXnAZ8OazWldrg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.15", + "jsonc-parser": "3.3.1", + "magic-string": "0.30.17", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular-devkit/schematics/node_modules/rxjs": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz", + "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/@angular/animations": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/animations/-/animations-19.2.14.tgz", + "integrity": "sha512-xhl8fLto5HHJdVj8Nb6EoBEiTAcXuWDYn1q5uHcGxyVH3kiwENWy/2OQXgCr2CuWo2e6hNUGzSLf/cjbsMNqEA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.2.14", + "@angular/core": "19.2.14" + } + }, + "node_modules/@angular/build": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/build/-/build-19.2.15.tgz", + "integrity": "sha512-iE4fp4d5ALu702uoL6/YkjM2JlGEXZ5G+RVzq3W2jg/Ft6ISAQnRKB6mymtetDD6oD7i87e8uSu9kFVNBauX2w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "2.3.0", + "@angular-devkit/architect": "0.1902.15", + "@babel/core": "7.26.10", + "@babel/helper-annotate-as-pure": "7.25.9", + "@babel/helper-split-export-declaration": "7.24.7", + "@babel/plugin-syntax-import-attributes": "7.26.0", + "@inquirer/confirm": "5.1.6", + "@vitejs/plugin-basic-ssl": "1.2.0", + "beasties": "0.3.2", + "browserslist": "^4.23.0", + "esbuild": "0.25.4", + "fast-glob": "3.3.3", + "https-proxy-agent": "7.0.6", + "istanbul-lib-instrument": "6.0.3", + "listr2": "8.2.5", + "magic-string": "0.30.17", + "mrmime": "2.0.1", + "parse5-html-rewriting-stream": "7.0.0", + "picomatch": "4.0.2", + "piscina": "4.8.0", + "rollup": "4.34.8", + "sass": "1.85.0", + "semver": "7.7.1", + "source-map-support": "0.5.21", + "vite": "6.2.7", + "watchpack": "2.4.2" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "optionalDependencies": { + "lmdb": "3.2.6" + }, + "peerDependencies": { + "@angular/compiler": "^19.0.0 || ^19.2.0-next.0", + "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", + "@angular/localize": "^19.0.0 || ^19.2.0-next.0", + "@angular/platform-server": "^19.0.0 || ^19.2.0-next.0", + "@angular/service-worker": "^19.0.0 || ^19.2.0-next.0", + "@angular/ssr": "^19.2.15", + "karma": "^6.4.0", + "less": "^4.2.0", + "ng-packagr": "^19.0.0 || ^19.2.0-next.0", + "postcss": "^8.4.0", + "tailwindcss": "^2.0.0 || ^3.0.0 || ^4.0.0", + "typescript": ">=5.5 <5.9" + }, + "peerDependenciesMeta": { + "@angular/localize": { + "optional": true + }, + "@angular/platform-server": { + "optional": true + }, + "@angular/service-worker": { + "optional": true + }, + "@angular/ssr": { + "optional": true + }, + "karma": { + "optional": true + }, + "less": { + "optional": true + }, + "ng-packagr": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tailwindcss": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/vite": { + "version": "6.2.7", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.2.7.tgz", + "integrity": "sha512-qg3LkeuinTrZoJHHF94coSaTfIPyBYoywp+ys4qu20oSJFbKMYoIJo0FWJT9q6Vp49l6z9IsJRbHdcGtiKbGoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.25.0", + "postcss": "^8.5.3", + "rollup": "^4.30.1" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/@angular/build/node_modules/vite/node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/@angular/cli": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@angular/cli/-/cli-19.2.15.tgz", + "integrity": "sha512-YRIpARHWSOnWkHusUWTQgeUrPWMjWvtQrOkjWc6stF36z2KUzKMEng6EzUvH6sZolNSwVwOFpODEP0ut4aBkvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/architect": "0.1902.15", + "@angular-devkit/core": "19.2.15", + "@angular-devkit/schematics": "19.2.15", + "@inquirer/prompts": "7.3.2", + "@listr2/prompt-adapter-inquirer": "2.0.18", + "@schematics/angular": "19.2.15", + "@yarnpkg/lockfile": "1.1.0", + "ini": "5.0.0", + "jsonc-parser": "3.3.1", + "listr2": "8.2.5", + "npm-package-arg": "12.0.2", + "npm-pick-manifest": "10.0.0", + "pacote": "20.0.0", + "resolve": "1.22.10", + "semver": "7.7.1", + "symbol-observable": "4.0.0", + "yargs": "17.7.2" + }, + "bin": { + "ng": "bin/ng.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@angular/common": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/common/-/common-19.2.14.tgz", + "integrity": "sha512-NcNklcuyqaTjOVGf7aru8APX9mjsnZ01gFZrn47BxHozhaR0EMRrotYQTdi8YdVjPkeYFYanVntSLfhyobq/jg==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/core": "19.2.14", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/compiler": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/compiler/-/compiler-19.2.14.tgz", + "integrity": "sha512-ZqJDYOdhgKpVGNq3+n/Gbxma8DVYElDsoRe0tvNtjkWBVdaOxdZZUqmJ3kdCBsqD/aqTRvRBu0KGo9s2fCChkA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + } + }, + "node_modules/@angular/compiler-cli": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/compiler-cli/-/compiler-cli-19.2.14.tgz", + "integrity": "sha512-e9/h86ETjoIK2yTLE9aUeMCKujdg/du2pq7run/aINjop4RtnNOw+ZlSTUa6R65lP5CVwDup1kPytpAoifw8cA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/core": "7.26.9", + "@jridgewell/sourcemap-codec": "^1.4.14", + "chokidar": "^4.0.0", + "convert-source-map": "^1.5.1", + "reflect-metadata": "^0.2.0", + "semver": "^7.0.0", + "tslib": "^2.3.0", + "yargs": "^17.2.1" + }, + "bin": { + "ng-xi18n": "bundles/src/bin/ng_xi18n.js", + "ngc": "bundles/src/bin/ngc.js", + "ngcc": "bundles/ngcc/index.js" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/compiler": "19.2.14", + "typescript": ">=5.5 <5.9" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.9.tgz", + "integrity": "sha512-lWBYIrF7qK5+GjY5Uy+/hEgp8OJWOD/rpy74GplYRhEauvbHDeFB8t5hPOZxCZ0Oxf4Cc36tK51/l3ymJysrKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.9", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.9", + "@babel/parser": "^7.26.9", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.9", + "@babel/types": "^7.26.9", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@angular/compiler-cli/node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@angular/core": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/core/-/core-19.2.14.tgz", + "integrity": "sha512-EVErpW9tGqJ/wNcAN3G/ErH8pHCJ8mM1E6bsJ8UJIpDTZkpqqYjBMtZS9YWH5n3KwUd1tAkAB2w8FK125AjDUQ==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "rxjs": "^6.5.3 || ^7.4.0", + "zone.js": "~0.15.0" + } + }, + "node_modules/@angular/forms": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/forms/-/forms-19.2.14.tgz", + "integrity": "sha512-hWtDOj2B0AuRTf+nkMJeodnFpDpmEK9OIhIv1YxcRe73ooaxrIdjgugkElO8I9Tj0E4/7m117ezhWDUkbqm1zA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.2.14", + "@angular/core": "19.2.14", + "@angular/platform-browser": "19.2.14", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@angular/platform-browser": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-19.2.14.tgz", + "integrity": "sha512-hzkT5nmA64oVBQl6PRjdL4dIFT1n7lfM9rm5cAoS+6LUUKRgiE2d421Kpn/Hz3jaCJfo+calMIdtSMIfUJBmww==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/animations": "19.2.14", + "@angular/common": "19.2.14", + "@angular/core": "19.2.14" + }, + "peerDependenciesMeta": { + "@angular/animations": { + "optional": true + } + } + }, + "node_modules/@angular/platform-browser-dynamic": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/platform-browser-dynamic/-/platform-browser-dynamic-19.2.14.tgz", + "integrity": "sha512-Hfz0z1KDQmIdnFXVFCwCPykuIsHPkr1uW2aY396eARwZ6PK8i0Aadcm1ZOnpd3MR1bMyDrJo30VRS5kx89QWvA==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.2.14", + "@angular/compiler": "19.2.14", + "@angular/core": "19.2.14", + "@angular/platform-browser": "19.2.14" + } + }, + "node_modules/@angular/router": { + "version": "19.2.14", + "resolved": "https://registry.npmjs.org/@angular/router/-/router-19.2.14.tgz", + "integrity": "sha512-cBTWY9Jx7YhbmDYDb7Hqz4Q7UNIMlKTkdKToJd2pbhIXyoS+kHVQrySmyca+jgvYMjWnIjsAEa3dpje12D4mFw==", + "license": "MIT", + "dependencies": { + "tslib": "^2.3.0" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0" + }, + "peerDependencies": { + "@angular/common": "19.2.14", + "@angular/core": "19.2.14", + "@angular/platform-browser": "19.2.14", + "rxjs": "^6.5.3 || ^7.4.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz", + "integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-validator-identifier": "^7.27.1", + "js-tokens": "^4.0.0", + "picocolors": "^1.1.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz", + "integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.26.10.tgz", + "integrity": "sha512-vMqyb7XCDMPvJFFOaT9kxtiRh42GwlZEg1/uIgtZshS5a/8OaduUfCi7kynKgc3Tw/6Uo2D+db9qBttghhmxwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.26.2", + "@babel/generator": "^7.26.10", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-module-transforms": "^7.26.0", + "@babel/helpers": "^7.26.10", + "@babel/parser": "^7.26.10", + "@babel/template": "^7.26.9", + "@babel/traverse": "^7.26.10", + "@babel/types": "^7.26.10", + "convert-source-map": "^2.0.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.3", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.26.10.tgz", + "integrity": "sha512-rRHT8siFIXQrAYOYqZQVsAr8vJ+cBNqcVAY6m5V8/4QqzaPl+zDBe6cLEPRDuNOUf3ww8RfJVlOyQMoSI+5Ang==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.26.10", + "@babel/types": "^7.26.10", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz", + "integrity": "sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz", + "integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.2", + "@babel/helper-validator-option": "^7.27.1", + "browserslist": "^4.24.0", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-class-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.27.1.tgz", + "integrity": "sha512-QwGAmuvM17btKU5VqXfb+Giw4JcN0hjuufz3DYnpeVDvZLAObloM77bhMXiqry3Iio+Ai4phVRDwl6WU10+r5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/traverse": "^7.27.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-class-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.27.1.tgz", + "integrity": "sha512-uVDC72XVf8UbrH5qQTc18Agb8emwjTiZrQE11Nv3CuBEZmVvTwwE9CBUEvHku06gQCAyYf8Nv6ja1IN+6LMbxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "regexpu-core": "^6.2.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-create-regexp-features-plugin/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-define-polyfill-provider": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.5.tgz", + "integrity": "sha512-uJnGFcPsWQK8fvjgGP5LZUZZsYGIoPeRjSF5PGwrelYgq7Q15/Ft9NGFp1zglwgIv//W0uG4BevRuSJRyylZPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "debug": "^4.4.1", + "lodash.debounce": "^4.0.8", + "resolve": "^1.22.10" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/helper-globals": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz", + "integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-member-expression-to-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.27.1.tgz", + "integrity": "sha512-E5chM8eWjTp/aNoVpcbfM7mLxu9XGLWYise2eBKGQomAk/Mb4XoxyqXTZbuTohbsl8EKqdlMhnDI2CCLfcs9wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz", + "integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.27.3.tgz", + "integrity": "sha512-dSOvYwvyLsWBeIRyOeHXp5vPj5l1I011r52FM1+r1jCERv+aFXYk4whgQccYEGYxK2H3ZAIA8nuPkQ0HaUo3qg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-optimise-call-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.27.1.tgz", + "integrity": "sha512-URMGH08NzYFhubNSGJrpUEphGKQwMQYBySzat5cAByY1/YgIRkULnIy3tAMeszlL/so2HbeilYloUmSpd7GdVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.27.1.tgz", + "integrity": "sha512-1gn1Up5YXka3YYAHGKpbideQ5Yjf1tDa9qYcgysz+cNCXukyLl6DjPXhD3VRwSb8c0J9tA4b2+rHEZtc6R0tlw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.27.1.tgz", + "integrity": "sha512-7fiA521aVw8lSPeI4ZOD3vRFkoqkJcS+z4hFo82bFSH/2tNd6eJ5qCVMS5OzDmZh/kaHQeBaeyxK6wljcPtveA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-wrap-function": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-remap-async-to-generator/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-replace-supers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.27.1.tgz", + "integrity": "sha512-7EHz6qDZc8RYS5ElPoShMheWvEgERonFCs7IAonWLLUTXW59DP14bCZt89/GKyreYn8g3S83m21FelHKbeDCKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-member-expression-to-functions": "^7.27.1", + "@babel/helper-optimise-call-expression": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-skip-transparent-expression-wrappers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.27.1.tgz", + "integrity": "sha512-Tub4ZKEXqbPjXgWLl2+3JpQAYBJ8+ikpQ2Ocj/q/r0LwE3UhENh7EUabyHjz2kCEsrRY83ew2DQdHluuiDQFzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", + "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", + "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz", + "integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-wrap-function": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.27.1.tgz", + "integrity": "sha512-NFJK2sHUvrjo8wAU/nQTWU890/zB2jj0qBcCbZbbf+005cAsv6tMjXz31fBign6M5ov1o0Bllu+9nbqkfsjjJQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.1", + "@babel/traverse": "^7.27.1", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.27.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.27.6.tgz", + "integrity": "sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/template": "^7.27.2", + "@babel/types": "^7.27.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.0.tgz", + "integrity": "sha512-jVZGvOxOuNSsuQuLRTh13nU0AogFlw32w/MT+LV6D3sP5WdbW61E77RnkbaO2dUvmPAYrBDJXGn5gGS6tH4j8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.28.0" + }, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-firefox-class-in-computed-class-key": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.27.1.tgz", + "integrity": "sha512-QPG3C9cCVRQLxAVwmefEmwdTanECuUBMQZ/ym5kiw3XKCGA7qkuQLcjWWHcrD/GKbn/WmJwaezfuuAOcyKlRPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-class-field-initializer-scope": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.27.1.tgz", + "integrity": "sha512-qNeq3bCKnGgLkEXUuFry6dPlGfCdQNZbn7yUAPCInwAJHMU7THJfrBSozkcWq5sNM6RcF3S8XyQL2A52KNR9IA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.27.1.tgz", + "integrity": "sha512-g4L7OYun04N1WyqMNjldFwlfPCLVkgB54A/YCXICZYBsvJJE3kByKv9c9+R/nAfmIfjl2rKYLNyMHboYbZaWaA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.27.1.tgz", + "integrity": "sha512-oO02gcONcD5O1iTLi/6frMJBIwWEHceWGSGqrpCmEL8nogiS6J9PBlE48CaK20/Jx1LuRml9aDftLgdjXT8+Cw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1", + "@babel/plugin-transform-optional-chaining": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.13.0" + } + }, + "node_modules/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.27.1.tgz", + "integrity": "sha512-6BpaYGDavZqkI6yT+KSPdpZFfpnd68UKXbcjI9pJ13pvHhPrCKWOOLp+ysvMeA+DxnhuPpgIaRpxRxo5A9t5jw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-proposal-private-property-in-object": { + "version": "7.21.0-placeholder-for-preset-env.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz", + "integrity": "sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-assertions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.27.1.tgz", + "integrity": "sha512-UT/Jrhw57xg4ILHLFnzFpPDlMbcdEicaAtjPQpbj9wa8T4r5KVWCimHcL/460g8Ht0DMxDyjsLgiWSkVjnwPFg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-attributes": { + "version": "7.26.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz", + "integrity": "sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-unicode-sets-regex": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz", + "integrity": "sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.18.6", + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-arrow-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.27.1.tgz", + "integrity": "sha512-8Z4TGic6xW70FKThA5HYEKKyBpOOsucTOD1DjU3fZxDg+K3zBJcXMFnt/4yQiZnf5+MiOMSXQ9PaEK/Ilh1DeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-generator-functions": { + "version": "7.26.8", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.26.8.tgz", + "integrity": "sha512-He9Ej2X7tNf2zdKMAGOsmg2MrFc+hfoAhd3po4cWfo/NWjzEAKa0oQruj1ROVUdl0e6fb6/kE/G3SSxE0lRJOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-remap-async-to-generator": "^7.25.9", + "@babel/traverse": "^7.26.8" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-async-to-generator": { + "version": "7.25.9", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz", + "integrity": "sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.25.9", + "@babel/helper-remap-async-to-generator": "^7.25.9" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoped-functions": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.27.1.tgz", + "integrity": "sha512-cnqkuOtZLapWYZUYM5rVIdv1nXYuFVIltZ6ZJ7nIj585QsjKM5dhL2Fu/lICXZ1OyIAFc7Qy+bvDAtTXqGrlhg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-block-scoping": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.28.0.tgz", + "integrity": "sha512-gKKnwjpdx5sER/wl0WN0efUBFzF/56YZO0RJrSYP4CljXnP31ByY7fol89AzomdlLNzI36AvOTmYHsnZTCkq8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.27.1.tgz", + "integrity": "sha512-D0VcalChDMtuRvJIu3U/fwWjf8ZMykz5iZsg77Nuj821vCKI3zCyRLwRdWbsuJ/uRwZhZ002QtCqIkwC/ZkvbA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-class-static-block": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.27.1.tgz", + "integrity": "sha512-s734HmYU78MVzZ++joYM+NkJusItbdRcbm+AGRgJCt3iA+yux0QpD9cBVdz3tKyrjVYWRl7j0mHSmv4lhV0aoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0" + } + }, + "node_modules/@babel/plugin-transform-classes": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.28.0.tgz", + "integrity": "sha512-IjM1IoJNw72AZFlj33Cu8X0q2XK/6AaVC3jQu+cgQ5lThWD5ajnuUAml80dqRmOhmPkTH8uAwnpMu9Rvj0LTRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.3", + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-globals": "^7.28.0", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-classes/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-computed-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.27.1.tgz", + "integrity": "sha512-lj9PGWvMTVksbWiDT2tW68zGS/cyo4AkZ/QTp0sQT0mjPopCmrSkzxeXkznjqBxzDI6TclZhOJbBmbBLjuOZUw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/template": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-destructuring": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.28.0.tgz", + "integrity": "sha512-v1nrSMBiKcodhsyJ4Gf+Z0U/yawmJDBOTpEB3mcQY52r9RIyPneGyAS/yM6seP/8I+mWI3elOMtT5dB8GJVs+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-dotall-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.27.1.tgz", + "integrity": "sha512-gEbkDVGRvjj7+T1ivxrfgygpT7GUd4vmODtYpbs0gZATdkX8/iSnOtZSxiZnsgm1YjTgjI6VKBGSJJevkrclzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-keys": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.27.1.tgz", + "integrity": "sha512-MTyJk98sHvSs+cvZ4nOauwTTG1JeonDjSGvGGUNHreGQns+Mpt6WX/dVzWBHgg+dYZhkC4X+zTDfkTU+Vy9y7Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-duplicate-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-hkGcueTEzuhB30B3eJCbCYeCaaEQOmQR0AdvzpD4LoN0GXMWzzGSuRrxR2xTnCrvNbVwK9N6/jQ92GSLfiZWoQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-dynamic-import": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.27.1.tgz", + "integrity": "sha512-MHzkWQcEmjzzVW9j2q8LGjwGWpG2mjwaaB0BNQwst3FIjqsg8Ct/mIZlvSPJvfi9y2AC8mi/ktxbFVL9pZ1I4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-exponentiation-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.27.1.tgz", + "integrity": "sha512-uspvXnhHvGKf2r4VVtBpeFnuDWsJLQ6MF6lGJLC89jBR1uoVeqM416AZtTuhTezOfgHicpJQmoD5YUakO/YmXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-export-namespace-from": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.27.1.tgz", + "integrity": "sha512-tQvHWSZ3/jH2xuq/vZDy0jNn+ZdXJeM8gHvX4lnJmsc3+50yPlWdZXIc5ay+umX+2/tJIqHqiEqcJvxlmIvRvQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-for-of": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.27.1.tgz", + "integrity": "sha512-BfbWFFEJFQzLCQ5N8VocnCtA8J1CLkNTe2Ms2wocj75dd6VpiqS5Z5quTYcUoo4Yq+DN0rtikODccuv7RU81sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-function-name": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.27.1.tgz", + "integrity": "sha512-1bQeydJF9Nr1eBCMMbC+hdwmRlsv5XYOMu03YSWFwNs0HsAmtSxxF1fyuYPqemVldVyFmlCU7w8UE14LupUSZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-json-strings": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.27.1.tgz", + "integrity": "sha512-6WVLVJiTjqcQauBhn1LkICsR2H+zm62I3h9faTDKt1qP4jn2o72tSvqMwtGFKGTpojce0gJs+76eZ2uCHRZh0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.27.1.tgz", + "integrity": "sha512-0HCFSepIpLTkLcsi86GG3mTUzxV5jpmbv97hTETW3yzrAij8aqlD36toB1D0daVFJM8NK6GvKO0gslVQmm+zZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-logical-assignment-operators": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.27.1.tgz", + "integrity": "sha512-SJvDs5dXxiae4FbSL1aBJlG4wvl594N6YEVVn9e3JGulwioy6z3oPjx/sQBO3Y4NwUu5HNix6KJ3wBZoewcdbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-member-expression-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.27.1.tgz", + "integrity": "sha512-hqoBX4dcZ1I33jCSWcXrP+1Ku7kdqXf1oeah7ooKOIiAdKQ+uqftgCFNOSzA5AMS2XIHEYeGFg4cKRCdpxzVOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-amd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.27.1.tgz", + "integrity": "sha512-iCsytMg/N9/oFq6n+gFTvUYDZQOMK5kEdeYxmxt91fcJGycfxVP9CnrxoliM0oumFERba2i8ZtwRUCMhvP1LnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-commonjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.27.1.tgz", + "integrity": "sha512-OJguuwlTYlN0gBZFRPqwOGNWssZjfIUdS7HMYtN8c1KmwpwHFBwTeFZrg9XZa+DFTitWOW5iTAG7tyCUPsCCyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-systemjs": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.27.1.tgz", + "integrity": "sha512-w5N1XzsRbc0PQStASMksmUeqECuzKuTJer7kFagK8AXgpCMkeDMO5S+aaFb7A51ZYDF7XI34qsTX+fkHiIm5yA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1", + "@babel/traverse": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-modules-umd": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.27.1.tgz", + "integrity": "sha512-iQBE/xC5BV1OxJbp6WG7jq9IWiD+xxlZhLrdwpPkTX3ydmXdvoCpyfJN7acaIBZaOqTfr76pgzqBJflNbeRK+w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-transforms": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.27.1.tgz", + "integrity": "sha512-SstR5JYy8ddZvD6MhV0tM/j16Qds4mIpJTOd1Yu9J9pJjH93bxHECF7pgtc28XvkzTD6Pxcm/0Z73Hvk7kb3Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-new-target": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.27.1.tgz", + "integrity": "sha512-f6PiYeqXQ05lYq3TIfIDu/MtliKUbNwkGApPUvyo6+tc7uaR4cPjPe7DFPr15Uyycg2lZU6btZ575CuQoYh7MQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-nullish-coalescing-operator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.27.1.tgz", + "integrity": "sha512-aGZh6xMo6q9vq1JGcw58lZ1Z0+i0xB2x0XaauNIUXd6O1xXc3RwoWEBlsTQrY4KQ9Jf0s5rgD6SiNkaUdJegTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-numeric-separator": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.27.1.tgz", + "integrity": "sha512-fdPKAcujuvEChxDBJ5c+0BTaS6revLV7CJL08e4m3de8qJfNIuCc2nc7XJYOjBoTMJeqSmwXJ0ypE14RCjLwaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-rest-spread": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.28.0.tgz", + "integrity": "sha512-9VNGikXxzu5eCiQjdE4IZn8sb9q7Xsk5EXLDBKUYg1e/Tve8/05+KJEtcxGxAgCY5t/BpKQM+JEL/yT4tvgiUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-compilation-targets": "^7.27.2", + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/plugin-transform-destructuring": "^7.28.0", + "@babel/plugin-transform-parameters": "^7.27.7", + "@babel/traverse": "^7.28.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-object-super": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.27.1.tgz", + "integrity": "sha512-SFy8S9plRPbIcxlJ8A6mT/CxFdJx/c04JEctz4jf8YZaVS2px34j7NXRrlGlHkN/M2gnpL37ZpGRGVFLd3l8Ng==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-replace-supers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-catch-binding": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.27.1.tgz", + "integrity": "sha512-txEAEKzYrHEX4xSZN4kJ+OfKXFVSWKB2ZxM9dpcE3wT7smwkNmXo5ORRlVzMVdJbD+Q8ILTgSD7959uj+3Dm3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-optional-chaining": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.27.1.tgz", + "integrity": "sha512-BQmKPPIuc8EkZgNKsv0X4bPmOoayeu4F1YCwx2/CfmDSXDbp7GnzlUH+/ul5VGfRg1AoFPsrIThlEBj2xb4CAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-parameters": { + "version": "7.27.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.27.7.tgz", + "integrity": "sha512-qBkYTYCb76RRxUM6CcZA5KRu8K4SM8ajzVeUgVdMVO9NN9uI/GaVmBg/WKJJGnNokV9SY8FxNOVWGXzqzUidBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-methods": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.27.1.tgz", + "integrity": "sha512-10FVt+X55AjRAYI9BrdISN9/AQWHqldOeZDUoLyif1Kn05a56xVBXb8ZouL8pZ9jem8QpXaOt8TS7RHUIS+GPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.27.1.tgz", + "integrity": "sha512-5J+IhqTi1XPa0DXF83jYOaARrX+41gOewWbkPyjMNRDqgOCqdffGh8L3f/Ek5utaEBZExjSAzcyjmV9SSAWObQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.27.1", + "@babel/helper-create-class-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-private-property-in-object/node_modules/@babel/helper-annotate-as-pure": { + "version": "7.27.3", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.27.3.tgz", + "integrity": "sha512-fXSwMQqitTGeHLBC08Eq5yXz2m37E4pJX1qAU1+2cNedz/ifv/bVXft90VeSav5nFO61EcNgwr0aJxbyPaWBPg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.27.3" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/plugin-transform-property-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.27.1.tgz", + "integrity": "sha512-oThy3BCuCha8kDZ8ZkgOg2exvPYUlprMukKQXI1r1pJ47NCvxfkEy8vK+r/hT9nF0Aa4H1WUPZZjHTFtAhGfmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regenerator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.28.0.tgz", + "integrity": "sha512-LOAozRVbqxEVjSKfhGnuLoE4Kz4Oc5UJzuvFUhSsQzdCdaAQu06mG8zDv2GFSerM62nImUZ7K92vxnQcLSDlCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-regexp-modifiers": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.27.1.tgz", + "integrity": "sha512-TtEciroaiODtXvLZv4rmfMhkCv8jx3wgKpL68PuiPh2M4fvz5jhsA7697N1gMvkvr/JTF13DrFYyEbY9U7cVPA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/plugin-transform-reserved-words": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.27.1.tgz", + "integrity": "sha512-V2ABPHIJX4kC7HegLkYoDpfg9PVmuWy/i6vUM5eGK22bx4YVFD3M5F0QQnWQoDs6AGsUWTVOopBiMFQgHaSkVw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.26.10.tgz", + "integrity": "sha512-NWaL2qG6HRpONTnj4JvDU6th4jYeZOJgu3QhmFTCihib0ermtOJqktA5BduGm3suhhVe9EMP9c9+mfJ/I9slqw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-module-imports": "^7.25.9", + "@babel/helper-plugin-utils": "^7.26.5", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-runtime/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/plugin-transform-shorthand-properties": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.27.1.tgz", + "integrity": "sha512-N/wH1vcn4oYawbJ13Y/FxcQrWk63jhfNa7jef0ih7PHSIHX2LB7GWE1rkPrOnka9kwMxb6hMl19p7lidA+EHmQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-spread": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.27.1.tgz", + "integrity": "sha512-kpb3HUqaILBJcRFVhFUs6Trdd4mkrzcGXss+6/mxUd273PfbWqSDHRzMT2234gIg2QYfAjvXLSquP1xECSg09Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1", + "@babel/helper-skip-transparent-expression-wrappers": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-sticky-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.27.1.tgz", + "integrity": "sha512-lhInBO5bi/Kowe2/aLdBAawijx+q1pQzicSgnkB6dUPc1+RC8QmJHKf2OjvU+NZWitguJHEaEmbV6VWEouT58g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-template-literals": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.27.1.tgz", + "integrity": "sha512-fBJKiV7F2DxZUkg5EtHKXQdbsbURW3DZKQUWphDum0uRP6eHGGa/He9mc0mypL680pb+e/lDIthRohlv8NCHkg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-typeof-symbol": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.27.1.tgz", + "integrity": "sha512-RiSILC+nRJM7FY5srIyc4/fGIwUhyDuuBSdWn4y6yT6gm652DpCHZjIipgn6B7MQ1ITOUnAKWixEUjQRIBIcLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-escapes": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.27.1.tgz", + "integrity": "sha512-Ysg4v6AmF26k9vpfFuTZg8HRfVWzsh1kVfowA23y9j/Gu6dOuahdUVhkLqpObp3JIv27MLSii6noRnuKN8H0Mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-property-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.27.1.tgz", + "integrity": "sha512-uW20S39PnaTImxp39O5qFlHLS9LJEmANjMG7SxIhap8rCHqu0Ik+tLEPX5DKmHn6CsWQ7j3lix2tFOa5YtL12Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.27.1.tgz", + "integrity": "sha512-xvINq24TRojDuyt6JGtHmkVkrfVV3FPT16uytxImLeBZqW3/H52yN+kM1MGuyPkIQxrzKwPHs5U/MP3qKyzkGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-transform-unicode-sets-regex": { + "version": "7.27.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.27.1.tgz", + "integrity": "sha512-EtkOujbc4cgvb0mlpQefi4NTPBzhSIevblFevACNLUspmrALgmEBdL/XfnyyITfd8fKBZrZys92zOWcik7j9Tw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-create-regexp-features-plugin": "^7.27.1", + "@babel/helper-plugin-utils": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/preset-env": { + "version": "7.26.9", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.26.9.tgz", + "integrity": "sha512-vX3qPGE8sEKEAZCWk05k3cpTAE3/nOYca++JA+Rd0z2NCNzabmYvEiSShKzm10zdquOIAVXsy2Ei/DTW34KlKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.26.8", + "@babel/helper-compilation-targets": "^7.26.5", + "@babel/helper-plugin-utils": "^7.26.5", + "@babel/helper-validator-option": "^7.25.9", + "@babel/plugin-bugfix-firefox-class-in-computed-class-key": "^7.25.9", + "@babel/plugin-bugfix-safari-class-field-initializer-scope": "^7.25.9", + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.25.9", + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.25.9", + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly": "^7.25.9", + "@babel/plugin-proposal-private-property-in-object": "7.21.0-placeholder-for-preset-env.2", + "@babel/plugin-syntax-import-assertions": "^7.26.0", + "@babel/plugin-syntax-import-attributes": "^7.26.0", + "@babel/plugin-syntax-unicode-sets-regex": "^7.18.6", + "@babel/plugin-transform-arrow-functions": "^7.25.9", + "@babel/plugin-transform-async-generator-functions": "^7.26.8", + "@babel/plugin-transform-async-to-generator": "^7.25.9", + "@babel/plugin-transform-block-scoped-functions": "^7.26.5", + "@babel/plugin-transform-block-scoping": "^7.25.9", + "@babel/plugin-transform-class-properties": "^7.25.9", + "@babel/plugin-transform-class-static-block": "^7.26.0", + "@babel/plugin-transform-classes": "^7.25.9", + "@babel/plugin-transform-computed-properties": "^7.25.9", + "@babel/plugin-transform-destructuring": "^7.25.9", + "@babel/plugin-transform-dotall-regex": "^7.25.9", + "@babel/plugin-transform-duplicate-keys": "^7.25.9", + "@babel/plugin-transform-duplicate-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-dynamic-import": "^7.25.9", + "@babel/plugin-transform-exponentiation-operator": "^7.26.3", + "@babel/plugin-transform-export-namespace-from": "^7.25.9", + "@babel/plugin-transform-for-of": "^7.26.9", + "@babel/plugin-transform-function-name": "^7.25.9", + "@babel/plugin-transform-json-strings": "^7.25.9", + "@babel/plugin-transform-literals": "^7.25.9", + "@babel/plugin-transform-logical-assignment-operators": "^7.25.9", + "@babel/plugin-transform-member-expression-literals": "^7.25.9", + "@babel/plugin-transform-modules-amd": "^7.25.9", + "@babel/plugin-transform-modules-commonjs": "^7.26.3", + "@babel/plugin-transform-modules-systemjs": "^7.25.9", + "@babel/plugin-transform-modules-umd": "^7.25.9", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.25.9", + "@babel/plugin-transform-new-target": "^7.25.9", + "@babel/plugin-transform-nullish-coalescing-operator": "^7.26.6", + "@babel/plugin-transform-numeric-separator": "^7.25.9", + "@babel/plugin-transform-object-rest-spread": "^7.25.9", + "@babel/plugin-transform-object-super": "^7.25.9", + "@babel/plugin-transform-optional-catch-binding": "^7.25.9", + "@babel/plugin-transform-optional-chaining": "^7.25.9", + "@babel/plugin-transform-parameters": "^7.25.9", + "@babel/plugin-transform-private-methods": "^7.25.9", + "@babel/plugin-transform-private-property-in-object": "^7.25.9", + "@babel/plugin-transform-property-literals": "^7.25.9", + "@babel/plugin-transform-regenerator": "^7.25.9", + "@babel/plugin-transform-regexp-modifiers": "^7.26.0", + "@babel/plugin-transform-reserved-words": "^7.25.9", + "@babel/plugin-transform-shorthand-properties": "^7.25.9", + "@babel/plugin-transform-spread": "^7.25.9", + "@babel/plugin-transform-sticky-regex": "^7.25.9", + "@babel/plugin-transform-template-literals": "^7.26.8", + "@babel/plugin-transform-typeof-symbol": "^7.26.7", + "@babel/plugin-transform-unicode-escapes": "^7.25.9", + "@babel/plugin-transform-unicode-property-regex": "^7.25.9", + "@babel/plugin-transform-unicode-regex": "^7.25.9", + "@babel/plugin-transform-unicode-sets-regex": "^7.25.9", + "@babel/preset-modules": "0.1.6-no-external-plugins", + "babel-plugin-polyfill-corejs2": "^0.4.10", + "babel-plugin-polyfill-corejs3": "^0.11.0", + "babel-plugin-polyfill-regenerator": "^0.6.1", + "core-js-compat": "^3.40.0", + "semver": "^6.3.1" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/preset-env/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/preset-modules": { + "version": "0.1.6-no-external-plugins", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz", + "integrity": "sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.26.10", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.26.10.tgz", + "integrity": "sha512-2WJMeRQPHKSPemqk/awGrAiuFfzBmOIPXKizAsVhWH9YJqLZ0H+HS4c8loHGgW6utJ3E/ejXQUsiGaQy2NZ9Fw==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerator-runtime": "^0.14.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.27.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz", + "integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/parser": "^7.27.2", + "@babel/types": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.0.tgz", + "integrity": "sha512-mGe7UK5wWyh0bKRfupsUchrQGqvDbZDbKJw+kcRGSmdHVYrv+ltd0pnpDTVpiTqnaBru9iEvA8pz8W46v0Amwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.27.1", + "@babel/generator": "^7.28.0", + "@babel/helper-globals": "^7.28.0", + "@babel/parser": "^7.28.0", + "@babel/template": "^7.27.2", + "@babel/types": "^7.28.0", + "debug": "^4.3.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/@babel/generator": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.0.tgz", + "integrity": "sha512-lJjzvrbEeWrhB4P3QBsH7tey117PjLZnDbLiQEKjQ/fNJTjuq4HSqgFA+UNSwZT8D7dxxbnuSBMsa1lrWzKlQg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.28.0", + "@babel/types": "^7.28.0", + "@jridgewell/gen-mapping": "^0.3.12", + "@jridgewell/trace-mapping": "^0.3.28", + "jsesc": "^3.0.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.28.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.0.tgz", + "integrity": "sha512-jYnje+JyZG5YThjHiF28oT4SIZLnYOcSBb6+SDaFIyzDVSkXQmQQYclJ2R+YxcdmK0AX6x1E5OQNtuh3jHDrUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-string-parser": "^7.27.1", + "@babel/helper-validator-identifier": "^7.27.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@colors/colors": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz", + "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.6.3.tgz", + "integrity": "sha512-4B4OijXeVNOPZlYA2oEwWOTkzyltLao+xbotHQeqN++Rv27Y6s818+n2Qkp8q+Fxhn0t/5lA5X1Mxktud8eayQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.17.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.4.tgz", + "integrity": "sha512-1VCICWypeQKhVbE9oW/sJaAmjLxhVqacdkvPLEjwlttjfwENRSClS8EjBz0KzRyFSCPDIkuXW34Je/vk7zdB7Q==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.4.tgz", + "integrity": "sha512-QNdQEps7DfFwE3hXiU4BZeOV68HHzYwGd0Nthhd3uCkkEKK7/R6MTgM0P7H7FAs5pU/DIWsviMmEGxEoxIZ+ZQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.4.tgz", + "integrity": "sha512-bBy69pgfhMGtCnwpC/x5QhfxAz/cBgQ9enbtwjf6V9lnPI/hMyT9iWpR1arm0l3kttTr4L0KSLpKmLp/ilKS9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.4.tgz", + "integrity": "sha512-TVhdVtQIFuVpIIR282btcGC2oGQoSfZfmBdTip2anCaVYcqWlZXGcdcKIUklfX2wj0JklNYgz39OBqh2cqXvcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.4.tgz", + "integrity": "sha512-Y1giCfM4nlHDWEfSckMzeWNdQS31BQGs9/rouw6Ub91tkK79aIMTH3q9xHvzH8d0wDru5Ci0kWB8b3up/nl16g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.4.tgz", + "integrity": "sha512-CJsry8ZGM5VFVeyUYB3cdKpd/H69PYez4eJh1W/t38vzutdjEjtP7hB6eLKBoOdxcAlCtEYHzQ/PJ/oU9I4u0A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.4.tgz", + "integrity": "sha512-yYq+39NlTRzU2XmoPW4l5Ifpl9fqSk0nAJYM/V/WUGPEFfek1epLHJIkTQM6bBs1swApjO5nWgvr843g6TjxuQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.4.tgz", + "integrity": "sha512-0FgvOJ6UUMflsHSPLzdfDnnBBVoCDtBTVyn/MrWloUNvq/5SFmh13l3dvgRPkDihRxb77Y17MbqbCAa2strMQQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.4.tgz", + "integrity": "sha512-kro4c0P85GMfFYqW4TWOpvmF8rFShbWGnrLqlzp4X1TNWjRY3JMYUfDCtOxPKOIY8B0WC8HN51hGP4I4hz4AaQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.4.tgz", + "integrity": "sha512-+89UsQTfXdmjIvZS6nUnOOLoXnkUTB9hR5QAeLrQdzOSWZvNSAXAtcRDHWtqAUtAmv7ZM1WPOOeSxDzzzMogiQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.4.tgz", + "integrity": "sha512-yTEjoapy8UP3rv8dB0ip3AfMpRbyhSN3+hY8mo/i4QXFeDxmiYbEKp3ZRjBKcOP862Ua4b1PDfwlvbuwY7hIGQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.4.tgz", + "integrity": "sha512-NeqqYkrcGzFwi6CGRGNMOjWGGSYOpqwCjS9fvaUlX5s3zwOtn1qwg1s2iE2svBe4Q/YOG1q6875lcAoQK/F4VA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.4.tgz", + "integrity": "sha512-IcvTlF9dtLrfL/M8WgNI/qJYBENP3ekgsHbYUIzEzq5XJzzVEV/fXY9WFPfEEXmu3ck2qJP8LG/p3Q8f7Zc2Xg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.4.tgz", + "integrity": "sha512-HOy0aLTJTVtoTeGZh4HSXaO6M95qu4k5lJcH4gxv56iaycfz1S8GO/5Jh6X4Y1YiI0h7cRyLi+HixMR+88swag==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.4.tgz", + "integrity": "sha512-i8JUDAufpz9jOzo4yIShCTcXzS07vEgWzyX3NH2G7LEFVgrLEhjwL3ajFE4fZI3I4ZgiM7JH3GQ7ReObROvSUA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.4.tgz", + "integrity": "sha512-jFnu+6UbLlzIjPQpWCNh5QtrcNfMLjgIavnwPQAfoGx4q17ocOU9MsQ2QVvFxwQoWpZT8DvTLooTvmOQXkO51g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.4.tgz", + "integrity": "sha512-6e0cvXwzOnVWJHq+mskP8DNSrKBr1bULBvnFLpc1KY+d+irZSgZ02TGse5FsafKS5jg2e4pbvK6TPXaF/A6+CA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.4.tgz", + "integrity": "sha512-vUnkBYxZW4hL/ie91hSqaSNjulOnYXE1VSLusnvHg2u3jewJBz3YzB9+oCw8DABeVqZGg94t9tyZFoHma8gWZQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.4.tgz", + "integrity": "sha512-XAg8pIQn5CzhOB8odIcAm42QsOfa98SBeKUdo4xa8OvX8LbMZqEtgeWE9P/Wxt7MlG2QqvjGths+nq48TrUiKw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.4.tgz", + "integrity": "sha512-Ct2WcFEANlFDtp1nVAXSNBPDxyU+j7+tId//iHXU2f/lN5AmO4zLyhDcpR5Cz1r08mVxzt3Jpyt4PmXQ1O6+7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.4.tgz", + "integrity": "sha512-xAGGhyOQ9Otm1Xu8NT1ifGLnA6M3sJxZ6ixylb+vIUVzvvd6GOALpwQrYrtlPouMqd/vSbgehz6HaVk4+7Afhw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.4.tgz", + "integrity": "sha512-Mw+tzy4pp6wZEK0+Lwr76pWLjrtjmJyUB23tHKqEDP74R3q95luY/bXqXZeYl4NYlvwOqoRKlInQialgCKy67Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.4.tgz", + "integrity": "sha512-AVUP428VQTSddguz9dO9ngb+E5aScyg7nOeJDrF1HPYu555gmza3bDGMPhmVXL8svDSoqPCsCPjb265yG/kLKQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.4.tgz", + "integrity": "sha512-i1sW+1i+oWvQzSgfRcxxG2k4I9n3O9NRqy8U+uugaT2Dy7kLO9Y7wI72haOahxceMX8hZAzgGou1FhndRldxRg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.4.tgz", + "integrity": "sha512-nOT2vZNw6hJ+z43oP1SPea/G/6AbN6X+bGNhNuq8NtRHy4wsMhw765IKLNmnjek7GvjWBYQ8Q5VBoYTFg9y1UQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/checkbox": { + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.9.tgz", + "integrity": "sha512-DBJBkzI5Wx4jFaYm221LHvAhpKYkhVS0k9plqHwaHhofGNxvYB7J3Bz8w+bFJ05zaMb0sZNHo4KdmENQFlNTuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/confirm": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.6.tgz", + "integrity": "sha512-6ZXYK3M1XmaVBZX6FCfChgtponnL0R6I7k8Nu+kaoNkT828FVZTcca1MqmWQipaW2oNREQl5AaPCUOOCVNdRMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.7", + "@inquirer/type": "^3.0.4" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/core": { + "version": "10.1.14", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.1.14.tgz", + "integrity": "sha512-Ma+ZpOJPewtIYl6HZHZckeX1STvDnHTCB2GVINNUlSEn2Am6LddWwfPkIGY0IUFVjUUrr/93XlBwTK6mfLjf0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "cli-width": "^4.1.0", + "mute-stream": "^2.0.0", + "signal-exit": "^4.1.0", + "wrap-ansi": "^6.2.0", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/editor": { + "version": "4.2.14", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.14.tgz", + "integrity": "sha512-yd2qtLl4QIIax9DTMZ1ZN2pFrrj+yL3kgIWxm34SS6uwCr0sIhsNyudUjAo5q3TqI03xx4SEBkUJqZuAInp9uA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/type": "^3.0.7", + "external-editor": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/expand": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.16.tgz", + "integrity": "sha512-oiDqafWzMtofeJyyGkb1CTPaxUkjIcSxePHHQCfif8t3HV9pHcw1Kgdw3/uGpDvaFfeTluwQtWiqzPVjAqS3zA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/figures": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.12.tgz", + "integrity": "sha512-MJttijd8rMFcKJC8NYmprWr6hD3r9Gd9qUC0XwPNwoEPWSMVJwA2MlXxF+nhZZNMY+HXsWa+o7KY2emWYIn0jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@inquirer/input": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.2.0.tgz", + "integrity": "sha512-opqpHPB1NjAmDISi3uvZOTrjEEU5CWVu/HBkDby8t93+6UxYX0Z7Ps0Ltjm5sZiEbWenjubwUkivAEYQmy9xHw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/number": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.16.tgz", + "integrity": "sha512-kMrXAaKGavBEoBYUCgualbwA9jWUx2TjMA46ek+pEKy38+LFpL9QHlTd8PO2kWPUgI/KB+qi02o4y2rwXbzr3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/type": "^3.0.7" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/password": { + "version": "4.0.16", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.16.tgz", + "integrity": "sha512-g8BVNBj5Zeb5/Y3cSN+hDUL7CsIFDIuVxb9EPty3lkxBaYpjL5BNRKSYOF9yOLe+JOcKFd+TSVeADQ4iSY7rbg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/prompts": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.3.2.tgz", + "integrity": "sha512-G1ytyOoHh5BphmEBxSwALin3n1KGNYB6yImbICcRQdzXfOGbuJ9Jske/Of5Sebk339NSGGNfUshnzK8YWkTPsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/checkbox": "^4.1.2", + "@inquirer/confirm": "^5.1.6", + "@inquirer/editor": "^4.2.7", + "@inquirer/expand": "^4.0.9", + "@inquirer/input": "^4.1.6", + "@inquirer/number": "^3.0.9", + "@inquirer/password": "^4.0.9", + "@inquirer/rawlist": "^4.0.9", + "@inquirer/search": "^3.0.9", + "@inquirer/select": "^4.0.9" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/rawlist": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.4.tgz", + "integrity": "sha512-5GGvxVpXXMmfZNtvWw4IsHpR7RzqAR624xtkPd1NxxlV5M+pShMqzL4oRddRkg8rVEOK9fKdJp1jjVML2Lr7TQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/search": { + "version": "3.0.16", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.16.tgz", + "integrity": "sha512-POCmXo+j97kTGU6aeRjsPyuCpQQfKcMXdeTMw708ZMtWrj5aykZvlUxH4Qgz3+Y1L/cAVZsSpA+UgZCu2GMOMg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/select": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.4.tgz", + "integrity": "sha512-unTppUcTjmnbl/q+h8XeQDhAqIOmwWYWNyiiP2e3orXrg6tOaa5DHXja9PChCSbChOsktyKgOieRZFnajzxoBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/core": "^10.1.14", + "@inquirer/figures": "^1.0.12", + "@inquirer/type": "^3.0.7", + "ansi-escapes": "^4.3.2", + "yoctocolors-cjs": "^2.1.2" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@inquirer/type": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.7.tgz", + "integrity": "sha512-PfunHQcjwnju84L+ycmcMKB/pTPIngjUJvfnRhKY6FKPuYXlM4aQCb/nIdTFR6BEhMjFvngzvng/vBAJMZpLSA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@types/node": ">=18" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", + "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@jsonjoy.com/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-q6XAnWQDIMA3+FTiOYajoYqySkO+JSat0ytXGSuRdq9uXE7o92gzuQwQM14xaCRlBLGq3v5miDGC4vkVTn54xA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/json-pack": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.2.0.tgz", + "integrity": "sha512-io1zEbbYcElht3tdlqEOFxZ0dMTYrHz9iMf0gqn1pPjZFTCgM5R4R5IMA20Chb2UPYYsxjzs8CgZ7Nb5n2K2rA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/base64": "^1.1.1", + "@jsonjoy.com/util": "^1.1.2", + "hyperdyperid": "^1.2.0", + "thingies": "^1.20.0" + }, + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@jsonjoy.com/util": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.6.0.tgz", + "integrity": "sha512-sw/RMbehRhN68WRtcKCpQOPfnH6lLP4GJfqzi3iYej8tnzpZUDr6UkZYJjcjjC0FWEJOJbyM3PTIwxucUmDG2A==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.5.tgz", + "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@listr2/prompt-adapter-inquirer": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/@listr2/prompt-adapter-inquirer/-/prompt-adapter-inquirer-2.0.18.tgz", + "integrity": "sha512-0hz44rAcrphyXcA8IS7EJ2SCoaBZD2u5goE8S/e+q/DL+dOGpqpcLidVOFeLG3VgML62SXmfRLAhWt0zL1oW4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@inquirer/type": "^1.5.5" + }, + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@inquirer/prompts": ">= 3 < 8" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/@inquirer/type": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-1.5.5.tgz", + "integrity": "sha512-MzICLu4yS7V8AA61sANROZ9vT1H3ooca5dSmI1FjZkzq7o/koMsRfQSzRtFo+F3Ao4Sf1C0bpLKejpKB/+j6MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "mute-stream": "^1.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/@listr2/prompt-adapter-inquirer/node_modules/mute-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-1.0.0.tgz", + "integrity": "sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@lmdb/lmdb-darwin-arm64": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-3.2.6.tgz", + "integrity": "sha512-yF/ih9EJJZc72psFQbwnn8mExIWfTnzWJg+N02hnpXtDPETYLmQswIMBn7+V88lfCaFrMozJsUvcEQIkEPU0Gg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-darwin-x64": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-3.2.6.tgz", + "integrity": "sha512-5BbCumsFLbCi586Bb1lTWQFkekdQUw8/t8cy++Uq251cl3hbDIGEwD9HAwh8H6IS2F6QA9KdKmO136LmipRNkg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-3.2.6.tgz", + "integrity": "sha512-+6XgLpMb7HBoWxXj+bLbiiB4s0mRRcDPElnRS3LpWRzdYSe+gFk5MT/4RrVNqd2MESUDmb53NUXw1+BP69bjiQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-arm64": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-3.2.6.tgz", + "integrity": "sha512-l5VmJamJ3nyMmeD1ANBQCQqy7do1ESaJQfKPSm2IG9/ADZryptTyCj8N6QaYgIWewqNUrcbdMkJajRQAt5Qjfg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-linux-x64": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-3.2.6.tgz", + "integrity": "sha512-nDYT8qN9si5+onHYYaI4DiauDMx24OAiuZAUsEqrDy+ja/3EbpXPX/VAkMV8AEaQhy3xc4dRC+KcYIvOFefJ4Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@lmdb/lmdb-win32-x64": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-3.2.6.tgz", + "integrity": "sha512-XlqVtILonQnG+9fH2N3Aytria7P/1fwDgDhl29rde96uH2sLB8CHORIf2PfuLVzFQJ7Uqp8py9AYwr3ZUCFfWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", + "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", + "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", + "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", + "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", + "integrity": "sha512-cvwNfbP07pKUfq1uH+S6KJ7dT9K8WOE4ZiAcsrSes+UY55E/0jLYc+vq+DO7jlmqRb5zAggExKm0H7O/CBaesg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", + "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@napi-rs/nice": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice/-/nice-1.0.4.tgz", + "integrity": "sha512-Sqih1YARrmMoHlXGgI9JrrgkzxcaaEso0AH+Y7j8NHonUs+xe4iDsgC3IBIDNdzEewbNpccNN6hip+b5vmyRLw==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 10" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "optionalDependencies": { + "@napi-rs/nice-android-arm-eabi": "1.0.4", + "@napi-rs/nice-android-arm64": "1.0.4", + "@napi-rs/nice-darwin-arm64": "1.0.4", + "@napi-rs/nice-darwin-x64": "1.0.4", + "@napi-rs/nice-freebsd-x64": "1.0.4", + "@napi-rs/nice-linux-arm-gnueabihf": "1.0.4", + "@napi-rs/nice-linux-arm64-gnu": "1.0.4", + "@napi-rs/nice-linux-arm64-musl": "1.0.4", + "@napi-rs/nice-linux-ppc64-gnu": "1.0.4", + "@napi-rs/nice-linux-riscv64-gnu": "1.0.4", + "@napi-rs/nice-linux-s390x-gnu": "1.0.4", + "@napi-rs/nice-linux-x64-gnu": "1.0.4", + "@napi-rs/nice-linux-x64-musl": "1.0.4", + "@napi-rs/nice-win32-arm64-msvc": "1.0.4", + "@napi-rs/nice-win32-ia32-msvc": "1.0.4", + "@napi-rs/nice-win32-x64-msvc": "1.0.4" + } + }, + "node_modules/@napi-rs/nice-android-arm-eabi": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm-eabi/-/nice-android-arm-eabi-1.0.4.tgz", + "integrity": "sha512-OZFMYUkih4g6HCKTjqJHhMUlgvPiDuSLZPbPBWHLjKmFTv74COzRlq/gwHtmEVaR39mJQ6ZyttDl2HNMUbLVoA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-android-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-android-arm64/-/nice-android-arm64-1.0.4.tgz", + "integrity": "sha512-k8u7cjeA64vQWXZcRrPbmwjH8K09CBnNaPnI9L1D5N6iMPL3XYQzLcN6WwQonfcqCDv5OCY3IqX89goPTV4KMw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-arm64/-/nice-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-GsLdQvUcuVzoyzmtjsThnpaVEizAqH5yPHgnsBmq3JdVoVZHELFo7PuJEdfOH1DOHi2mPwB9sCJEstAYf3XCJA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-darwin-x64/-/nice-darwin-x64-1.0.4.tgz", + "integrity": "sha512-1y3gyT3e5zUY5SxRl3QDtJiWVsbkmhtUHIYwdWWIQ3Ia+byd/IHIEpqAxOGW1nhhnIKfTCuxBadHQb+yZASVoA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-freebsd-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-freebsd-x64/-/nice-freebsd-x64-1.0.4.tgz", + "integrity": "sha512-06oXzESPRdXUuzS8n2hGwhM2HACnDfl3bfUaSqLGImM8TA33pzDXgGL0e3If8CcFWT98aHows5Lk7xnqYNGFeA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm-gnueabihf": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm-gnueabihf/-/nice-linux-arm-gnueabihf-1.0.4.tgz", + "integrity": "sha512-CgklZ6g8WL4+EgVVkxkEvvsi2DSLf9QIloxWO0fvQyQBp6VguUSX3eHLeRpqwW8cRm2Hv/Q1+PduNk7VK37VZw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-gnu": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-gnu/-/nice-linux-arm64-gnu-1.0.4.tgz", + "integrity": "sha512-wdAJ7lgjhAlsANUCv0zi6msRwq+D4KDgU+GCCHssSxWmAERZa2KZXO0H2xdmoJ/0i03i6YfK/sWaZgUAyuW2oQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-arm64-musl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-arm64-musl/-/nice-linux-arm64-musl-1.0.4.tgz", + "integrity": "sha512-4b1KYG+sriufhFrpUS9uNOEYYJqSfcbnwGx6uGX7JjrH8tELG90cOpCawz5THNIwlS3DhLgnCOcn0+4p6z26QA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-ppc64-gnu": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-ppc64-gnu/-/nice-linux-ppc64-gnu-1.0.4.tgz", + "integrity": "sha512-iaf3vMRgr23oe1PUaKpxaH3DS0IMN0+N9iEiWVwYPm/U15vZFYdqVegGfN2PzrZLUl5lc8ZxbmEKDfuqslhAMA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-riscv64-gnu": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-riscv64-gnu/-/nice-linux-riscv64-gnu-1.0.4.tgz", + "integrity": "sha512-UXoREY6Yw6rHrGuTwQgBxpfjK34t6mTjibE9/cXbefL9AuUCJ9gEgwNKZiONuR5QGswChqo9cnthjdKkYyAdDg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-s390x-gnu": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-s390x-gnu/-/nice-linux-s390x-gnu-1.0.4.tgz", + "integrity": "sha512-eFbgYCRPmsqbYPAlLYU5hYTNbogmIDUvknilehHsFhCH1+0/kN87lP+XaLT0Yeq4V/rpwChSd9vlz4muzFArtw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-gnu": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-gnu/-/nice-linux-x64-gnu-1.0.4.tgz", + "integrity": "sha512-4T3E6uTCwWT6IPnwuPcWVz3oHxvEp/qbrCxZhsgzwTUBEwu78EGNXGdHfKJQt3soth89MLqZJw+Zzvnhrsg1mQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-linux-x64-musl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-linux-x64-musl/-/nice-linux-x64-musl-1.0.4.tgz", + "integrity": "sha512-NtbBkAeyBPLvCBkWtwkKXkNSn677eaT0cX3tygq+2qVv71TmHgX4gkX6o9BXjlPzdgPGwrUudavCYPT9tzkEqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-arm64-msvc": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-arm64-msvc/-/nice-win32-arm64-msvc-1.0.4.tgz", + "integrity": "sha512-vubOe3i+YtSJGEk/++73y+TIxbuVHi+W8ZzrRm2eETCjCRwNlgbfToQZ85dSA+4iBB/NJRGNp+O4hfdbbttZWA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-ia32-msvc": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-ia32-msvc/-/nice-win32-ia32-msvc-1.0.4.tgz", + "integrity": "sha512-BMOVrUDZeg1RNRKVlh4eyLv5djAAVLiSddfpuuQ47EFjBcklg0NUeKMFKNrKQR4UnSn4HAiACLD7YK7koskwmg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@napi-rs/nice-win32-x64-msvc": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@napi-rs/nice-win32-x64-msvc/-/nice-win32-x64-msvc-1.0.4.tgz", + "integrity": "sha512-kCNk6HcRZquhw/whwh4rHsdPyOSCQCgnVDVik+Y9cuSVTDy3frpiCJTScJqPPS872h4JgZKkr/+CwcwttNEo9Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10" + } + }, + "node_modules/@ngtools/webpack": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-19.2.15.tgz", + "integrity": "sha512-H37nop/wWMkSgoU2VvrMzanHePdLRRrX52nC5tT2ZhH3qP25+PrnMyw11PoLDLv3iWXC68uB1AiKNIT+jiQbuQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "@angular/compiler-cli": "^19.0.0 || ^19.2.0-next.0", + "typescript": ">=5.5 <5.9", + "webpack": "^5.54.0" + } + }, + "node_modules/@nodelib/fs.scandir": { + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.stat": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nodelib/fs.walk": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@npmcli/agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/agent/-/agent-3.0.0.tgz", + "integrity": "sha512-S79NdEgDQd/NGCay6TCoVzXSj74skRZIKJcpJjC5lOq34SZzyI6MqtiiWoiVWoVrTcGjNeC4ipbh1VIHlpfF5Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "agent-base": "^7.1.0", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.1", + "lru-cache": "^10.0.1", + "socks-proxy-agent": "^8.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/agent/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/fs": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-4.0.0.tgz", + "integrity": "sha512-/xGlezI6xfGO9NwuJlnwz/K14qD1kCSAGtacBHnGzeAIuJGazcp45KP5NuyARXoKb7cwulAGWVsbeSxdG/cb0Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@npmcli/git/-/git-6.0.3.tgz", + "integrity": "sha512-GUYESQlxZRAdhs3UhbB6pVRNUELQOHXwK9ruDkwmCv2aZ5y0SApQzUJCg02p3A7Ue2J5hxvlk1YI53c00NmRyQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/promise-spawn": "^8.0.0", + "ini": "^5.0.0", + "lru-cache": "^10.0.1", + "npm-pick-manifest": "^10.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "semver": "^7.3.5", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/git/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/git/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/@npmcli/git/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/installed-package-contents": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-3.0.0.tgz", + "integrity": "sha512-fkxoPuFGvxyrH+OQzyTkX2LUEamrF4jZSmxjAtPPHHGO0dqsQ8tTKjnIS8SAnPHdk2I03BDtSMR5K/4loKg79Q==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-bundled": "^4.0.0", + "npm-normalize-package-bin": "^4.0.0" + }, + "bin": { + "installed-package-contents": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/node-gyp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/node-gyp/-/node-gyp-4.0.0.tgz", + "integrity": "sha512-+t5DZ6mO/QFh78PByMq1fGSAub/agLJZDRfJRMeOSNCt8s9YVlTjmGpIPwPhvXTGUIJk+WszlT0rQa1W33yzNA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/@npmcli/package-json/-/package-json-6.2.0.tgz", + "integrity": "sha512-rCNLSB/JzNvot0SEyXqWZ7tX2B5dD2a1br2Dp0vSYVo5jh8Z0EZ7lS9TsZ1UtziddB1UfNUaMCc538/HztnJGA==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "glob": "^10.2.2", + "hosted-git-info": "^8.0.0", + "json-parse-even-better-errors": "^4.0.0", + "proc-log": "^5.0.0", + "semver": "^7.5.3", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/package-json/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/package-json/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/promise-spawn": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@npmcli/promise-spawn/-/promise-spawn-8.0.2.tgz", + "integrity": "sha512-/bNJhjc+o6qL+Dwz/bqfTQClkEO5nTQ1ZEcdCkAQjhkZMHIh22LPG7fNh1enJP1NKWDqYiiABnjFCY7E0zHYtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/promise-spawn/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/redact": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@npmcli/redact/-/redact-3.2.2.tgz", + "integrity": "sha512-7VmYAmk4csGv08QzrDKScdzn11jHPFGyqJW39FyPgPuAp3zIaUmuCo1yxw9aGs+NEJuTGQ9Gwqpt93vtJubucg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/run-script/-/run-script-9.1.0.tgz", + "integrity": "sha512-aoNSbxtkePXUlbZB+anS1LqsJdctG5n3UVhfU47+CDdwMi6uNTBMF9gPcQRnqghQd2FGzcwwIFBruFMxjhBewg==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/node-gyp": "^4.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "node-gyp": "^11.0.0", + "proc-log": "^5.0.0", + "which": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@npmcli/run-script/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/@npmcli/run-script/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@parcel/watcher": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher/-/watcher-2.5.1.tgz", + "integrity": "sha512-dfUnCxiN9H4ap84DvD2ubjw+3vUNpstxa0TneY/Paat8a3R4uQZDLSvWjmznAY/DoahqTHl9V46HF/Zs3F29pg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^1.0.3", + "is-glob": "^4.0.3", + "micromatch": "^4.0.5", + "node-addon-api": "^7.0.0" + }, + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "@parcel/watcher-android-arm64": "2.5.1", + "@parcel/watcher-darwin-arm64": "2.5.1", + "@parcel/watcher-darwin-x64": "2.5.1", + "@parcel/watcher-freebsd-x64": "2.5.1", + "@parcel/watcher-linux-arm-glibc": "2.5.1", + "@parcel/watcher-linux-arm-musl": "2.5.1", + "@parcel/watcher-linux-arm64-glibc": "2.5.1", + "@parcel/watcher-linux-arm64-musl": "2.5.1", + "@parcel/watcher-linux-x64-glibc": "2.5.1", + "@parcel/watcher-linux-x64-musl": "2.5.1", + "@parcel/watcher-win32-arm64": "2.5.1", + "@parcel/watcher-win32-ia32": "2.5.1", + "@parcel/watcher-win32-x64": "2.5.1" + } + }, + "node_modules/@parcel/watcher-android-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.5.1.tgz", + "integrity": "sha512-KF8+j9nNbUN8vzOFDpRMsaKBHZ/mcjEjMToVMJOhTozkDonQFFrRcfdLWn6yWKCmJKmdVxSgHiYvTCef4/qcBA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz", + "integrity": "sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-darwin-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.5.1.tgz", + "integrity": "sha512-1ZXDthrnNmwv10A0/3AJNZ9JGlzrF82i3gNQcWOzd7nJ8aj+ILyW1MTxVk35Db0u91oD5Nlk9MBiujMlwmeXZg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-freebsd-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.5.1.tgz", + "integrity": "sha512-SI4eljM7Flp9yPuKi8W0ird8TI/JK6CSxju3NojVI6BjHsTyK7zxA9urjVjEKJ5MBYC+bLmMcbAWlZ+rFkLpJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.5.1.tgz", + "integrity": "sha512-RCdZlEyTs8geyBkkcnPWvtXLY44BCeZKmGYRtSgtwwnHR4dxfHRG3gR99XdMEdQ7KeiDdasJwwvNSF5jKtDwdA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-musl/-/watcher-linux-arm-musl-2.5.1.tgz", + "integrity": "sha512-6E+m/Mm1t1yhB8X412stiKFG3XykmgdIOqhjWj+VL8oHkKABfu/gjFj8DvLrYVHSBNC+/u5PeNrujiSQ1zwd1Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.5.1.tgz", + "integrity": "sha512-LrGp+f02yU3BN9A+DGuY3v3bmnFUggAITBGriZHUREfNEzZh/GO06FF5u2kx8x+GBEUYfyTGamol4j3m9ANe8w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-arm64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.5.1.tgz", + "integrity": "sha512-cFOjABi92pMYRXS7AcQv9/M1YuKRw8SZniCDw0ssQb/noPkRzA+HBDkwmyOJYp5wXcsTrhxO0zq1U11cK9jsFg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-glibc": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.5.1.tgz", + "integrity": "sha512-GcESn8NZySmfwlTsIur+49yDqSny2IhPeZfXunQi48DMugKeZ7uy1FX83pO0X22sHntJ4Ub+9k34XQCX+oHt2A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-linux-x64-musl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.5.1.tgz", + "integrity": "sha512-n0E2EQbatQ3bXhcH2D1XIAANAcTZkQICBPVaxMeaCVBtOpBZpWJuf7LwyWPSBDITb7In8mqQgJ7gH8CILCURXg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-arm64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.5.1.tgz", + "integrity": "sha512-RFzklRvmc3PkjKjry3hLF9wD7ppR4AKcWNzH7kXR7GUe0Igb3Nz8fyPwtZCSquGrhU5HhUNDr/mKBqj7tqA2Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-ia32": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.5.1.tgz", + "integrity": "sha512-c2KkcVN+NJmuA7CGlaGD1qJh1cLfDnQsHjE89E60vUEMlqduHGCdCLJCID5geFVM0dOtA3ZiIO8BoEQmzQVfpQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher-win32-x64": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz", + "integrity": "sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/@parcel/watcher/node_modules/detect-libc": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", + "integrity": "sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "bin": { + "detect-libc": "bin/detect-libc.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@parcel/watcher/node_modules/node-addon-api": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-7.1.1.tgz", + "integrity": "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.34.8.tgz", + "integrity": "sha512-q217OSE8DTp8AFHuNHXo0Y86e1wtlfVrXiAlwkIvGRQv9zbc6mE3sjIVfwI8sYUyNxwOg0j/Vm1RKM04JcWLJw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.34.8.tgz", + "integrity": "sha512-Gigjz7mNWaOL9wCggvoK3jEIUUbGul656opstjaUSGC3eT0BM7PofdAJaBfPFWWkXNVAXbaQtC99OCg4sJv70Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.34.8.tgz", + "integrity": "sha512-02rVdZ5tgdUNRxIUrFdcMBZQoaPMrxtwSb+/hOfBdqkatYHR3lZ2A2EGyHq2sGOd0Owk80oV3snlDASC24He3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.34.8.tgz", + "integrity": "sha512-qIP/elwR/tq/dYRx3lgwK31jkZvMiD6qUtOycLhTzCvrjbZ3LjQnEM9rNhSGpbLXVJYQ3rq39A6Re0h9tU2ynw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.34.8.tgz", + "integrity": "sha512-IQNVXL9iY6NniYbTaOKdrlVP3XIqazBgJOVkddzJlqnCpRi/yAeSOa8PLcECFSQochzqApIOE1GHNu3pCz+BDA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.34.8.tgz", + "integrity": "sha512-TYXcHghgnCqYFiE3FT5QwXtOZqDj5GmaFNTNt3jNC+vh22dc/ukG2cG+pi75QO4kACohZzidsq7yKTKwq/Jq7Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.34.8.tgz", + "integrity": "sha512-A4iphFGNkWRd+5m3VIGuqHnG3MVnqKe7Al57u9mwgbyZ2/xF9Jio72MaY7xxh+Y87VAHmGQr73qoKL9HPbXj1g==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.34.8.tgz", + "integrity": "sha512-S0lqKLfTm5u+QTxlFiAnb2J/2dgQqRy/XvziPtDd1rKZFXHTyYLoVL58M/XFwDI01AQCDIevGLbQrMAtdyanpA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.34.8.tgz", + "integrity": "sha512-jpz9YOuPiSkL4G4pqKrus0pn9aYwpImGkosRKwNi+sJSkz+WU3anZe6hi73StLOQdfXYXC7hUfsQlTnjMd3s1A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.34.8.tgz", + "integrity": "sha512-KdSfaROOUJXgTVxJNAZ3KwkRc5nggDk+06P6lgi1HLv1hskgvxHUKZ4xtwHkVYJ1Rep4GNo+uEfycCRRxht7+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.34.8.tgz", + "integrity": "sha512-NyF4gcxwkMFRjgXBM6g2lkT58OWztZvw5KkV2K0qqSnUEqCVcqdh2jN4gQrTn/YUpAcNKyFHfoOZEer9nwo6uQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.34.8.tgz", + "integrity": "sha512-LMJc999GkhGvktHU85zNTDImZVUCJ1z/MbAJTnviiWmmjyckP5aQsHtcujMjpNdMZPT2rQEDBlJfubhs3jsMfw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.34.8.tgz", + "integrity": "sha512-xAQCAHPj8nJq1PI3z8CIZzXuXCstquz7cIOL73HHdXiRcKk8Ywwqtx2wrIy23EcTn4aZ2fLJNBB8d0tQENPCmw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.44.2.tgz", + "integrity": "sha512-e6vEbgaaqz2yEHqtkPXa28fFuBGmUJ0N2dOJK8YUfijejInt9gfCSA7YDdJ4nYlv67JfP3+PSWFX4IVw/xRIPg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.34.8.tgz", + "integrity": "sha512-DdePVk1NDEuc3fOe3dPPTb+rjMtuFw89gw6gVWxQFAuEqqSdDKnrwzZHrUYdac7A7dXl9Q2Vflxpme15gUWQFA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.34.8.tgz", + "integrity": "sha512-8y7ED8gjxITUltTUEJLQdgpbPh1sUQ0kMTmufRF/Ns5tI9TNMNlhWtmPKKHCU0SilX+3MJkZ0zERYYGIVBYHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.34.8.tgz", + "integrity": "sha512-SCXcP0ZpGFIe7Ge+McxY5zKxiEI5ra+GT3QRxL0pMMtxPfpyLAKleZODi1zdRHkz5/BhueUrYtYVgubqe9JBNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.34.8.tgz", + "integrity": "sha512-YHYsgzZgFJzTRbth4h7Or0m5O74Yda+hLin0irAIobkLQFRQd1qWmnoVfwmKm9TXIZVAD0nZ+GEb2ICicLyCnQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.34.8.tgz", + "integrity": "sha512-r3NRQrXkHr4uWy5TOjTpTYojR9XmF0j/RYgKCef+Ag46FWUTltm5ziticv8LdNsDMehjJ543x/+TJAek/xBA2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.34.8.tgz", + "integrity": "sha512-U0FaE5O1BCpZSeE6gBl3c5ObhePQSfk9vDRToMmTkbhCOgW4jqvtS5LGyQ76L1fH8sM0keRp4uDTsbjiUyjk0g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@schematics/angular": { + "version": "19.2.15", + "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-19.2.15.tgz", + "integrity": "sha512-dz/eoFQKG09POSygpEDdlCehFIMo35HUM2rVV8lx9PfQEibpbGwl1NNQYEbqwVjTyCyD/ILyIXCWPE+EfTnG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@angular-devkit/core": "19.2.15", + "@angular-devkit/schematics": "19.2.15", + "jsonc-parser": "3.3.1" + }, + "engines": { + "node": "^18.19.1 || ^20.11.1 || >=22.0.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@sigstore/bundle": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/bundle/-/bundle-3.1.0.tgz", + "integrity": "sha512-Mm1E3/CmDDCz3nDhFKTuYdB47EdRFRQMOE/EAbiG1MJW77/w1b3P7Qx7JSrVJs8PfwOLOVcKQCHErIwCTyPbag==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/core": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sigstore/core/-/core-2.0.0.tgz", + "integrity": "sha512-nYxaSb/MtlSI+JWcwTHQxyNmWeWrUXJJ/G4liLrGG7+tS4vAz6LF3xRXqLH6wPIVUoZQel2Fs4ddLx4NCpiIYg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/protobuf-specs": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/@sigstore/protobuf-specs/-/protobuf-specs-0.4.3.tgz", + "integrity": "sha512-fk2zjD9117RL9BjqEwF7fwv7Q/P9yGsMV4MUJZ/DocaQJ6+3pKr+syBq1owU5Q5qGw5CUbXzm+4yJ2JVRDQeSA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/sign": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sigstore/sign/-/sign-3.1.0.tgz", + "integrity": "sha512-knzjmaOHOov1Ur7N/z4B1oPqZ0QX5geUfhrVaqVlu+hl0EAoL4o+l0MSULINcD5GCWe3Z0+YJO8ues6vFlW0Yw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "make-fetch-happen": "^14.0.2", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/tuf": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/tuf/-/tuf-3.1.1.tgz", + "integrity": "sha512-eFFvlcBIoGwVkkwmTi/vEQFSva3xs5Ot3WmBcjgjVdiaoelBLQaQ/ZBfhlG0MnG0cmTYScPpk7eDdGDWUcFUmg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/protobuf-specs": "^0.4.1", + "tuf-js": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sigstore/verify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@sigstore/verify/-/verify-2.1.1.tgz", + "integrity": "sha512-hVJD77oT67aowHxwT4+M6PGOp+E2LtLdTK3+FC0lBO9T7sYwItDMXZ7Z07IDCvR1M717a4axbIWckrW67KMP/w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@sindresorhus/merge-streams": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz", + "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@socket.io/component-emitter": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@tufjs/canonical-json": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@tufjs/canonical-json/-/canonical-json-2.0.0.tgz", + "integrity": "sha512-yVtV8zsdo8qFHe+/3kw81dSLyF7D576A5cCFCi4X7B39tWT7SekaEFUnvnWJHz+9qO7qJTah1JbrDjWKqFtdWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^16.14.0 || >=18.0.0" + } + }, + "node_modules/@tufjs/models": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@tufjs/models/-/models-3.0.1.tgz", + "integrity": "sha512-UUYHISyhCU3ZgN8yaear3cGATHb3SMuKHsQ/nVbHXcmnBf+LzQ/cQfhNG+rfaSHgqGKNEm2cOCLVLELStUQ1JA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/canonical-json": "2.0.0", + "minimatch": "^9.0.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/@tufjs/models/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@tufjs/models/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.6", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.6.tgz", + "integrity": "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.13", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.13.tgz", + "integrity": "sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.38", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.38.tgz", + "integrity": "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz", + "integrity": "sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/cors": { + "version": "2.8.19", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz", + "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", + "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/express": { + "version": "4.17.23", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", + "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.33", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.19.6", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", + "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*", + "@types/send": "*" + } + }, + "node_modules/@types/http-errors": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@types/http-errors/-/http-errors-2.0.5.tgz", + "integrity": "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/http-proxy": { + "version": "1.17.16", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.16.tgz", + "integrity": "sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/jasmine": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/@types/jasmine/-/jasmine-5.1.8.tgz", + "integrity": "sha512-u7/CnvRdh6AaaIzYjCgUuVbREFgulhX05Qtf6ZtW+aOcjCKKVvKgpkPYJBFTZSHtFBYimzU4zP0V2vrEsq9Wcg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/mime": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", + "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.0.12", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.12.tgz", + "integrity": "sha512-LtOrbvDf5ndC9Xi+4QZjVL0woFymF/xSTKZKPgrrl7H7XoeDvnD+E2IclKVDyaK9UM756W/3BXqSU+JEHopA9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@types/node-forge": { + "version": "1.3.12", + "resolved": "https://registry.npmjs.org/@types/node-forge/-/node-forge-1.3.12.tgz", + "integrity": "sha512-a0ToKlRVnUw3aXKQq2F+krxZKq7B8LEQijzPn5RdFAMatARD2JX9o8FBpMXOOrjob0uc13aN+V/AXniOXW4d9A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/qs": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", + "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/range-parser": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.7.tgz", + "integrity": "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/retry": { + "version": "0.12.2", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.2.tgz", + "integrity": "sha512-XISRgDJ2Tc5q4TRqvgJtzsRkFYNJzZrhTdtMoGVBttwzzQJkPnS3WWTFc7kuDRoPtPakl+T+OfdEUjYJj7Jbow==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/send": { + "version": "0.17.5", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", + "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/serve-index": { + "version": "1.9.4", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.4.tgz", + "integrity": "sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.8", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", + "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.36", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz", + "integrity": "sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/ws": { + "version": "8.18.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.18.1.tgz", + "integrity": "sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.2.0.tgz", + "integrity": "sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.21.3" + }, + "peerDependencies": { + "vite": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/@yarnpkg/lockfile": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz", + "integrity": "sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/abbrev": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-3.0.1.tgz", + "integrity": "sha512-AO2ac6pjRB3SJmGJo+v5/aK6Omggp6fsLrs6wN9bd35ulu4cCwaAU9+7ZhXjeqHVkaHThLuzH0nZr0YpCDhygg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/accepts": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", + "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/accepts/node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/adjust-sourcemap-loader": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz", + "integrity": "sha512-OXwN5b9pCUXNQHJpwwD2qP40byEmSgzj8B4ydSN0uMNYWiFmJ6x6KwUllMmfk8Rwu/HJDFR7U8ubsWBoN0Xp0A==", + "dev": true, + "license": "MIT", + "dependencies": { + "loader-utils": "^2.0.0", + "regex-parser": "^2.2.11" + }, + "engines": { + "node": ">=8.9" + } + }, + "node_modules/adjust-sourcemap-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/agent-base": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz", + "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", + "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "license": "Apache-2.0", + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/anymatch": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "dev": true, + "license": "ISC", + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true, + "license": "Python-2.0" + }, + "node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/autoprefixer": { + "version": "10.4.20", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.20.tgz", + "integrity": "sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.3", + "caniuse-lite": "^1.0.30001646", + "fraction.js": "^4.3.7", + "normalize-range": "^0.1.2", + "picocolors": "^1.0.1", + "postcss-value-parser": "^4.2.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/babel-loader": { + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-9.2.1.tgz", + "integrity": "sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-cache-dir": "^4.0.0", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 14.15.0" + }, + "peerDependencies": { + "@babel/core": "^7.12.0", + "webpack": ">=5" + } + }, + "node_modules/babel-plugin-polyfill-corejs2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.14.tgz", + "integrity": "sha512-Co2Y9wX854ts6U8gAAPXfn0GmAyctHuK8n0Yhfjd6t30g7yvKjspvvOo9yG+z52PZRgFErt7Ka2pYnXCjLKEpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/compat-data": "^7.27.7", + "@babel/helper-define-polyfill-provider": "^0.6.5", + "semver": "^6.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-corejs2/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/babel-plugin-polyfill-corejs3": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.11.1.tgz", + "integrity": "sha512-yGCqvBT4rwMczo28xkH/noxJ6MZ4nJfkVYdoDaC/utLtWrXxv27HVrzAeSbqR8SxDsp46n0YF47EbHoixy6rXQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.3", + "core-js-compat": "^3.40.0" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/babel-plugin-polyfill-regenerator": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.6.5.tgz", + "integrity": "sha512-ISqQ2frbiNU9vIJkzg7dlPpznPZ4jOiUQ1uSmB0fEHeowtN3COYRsXr/xexn64NpU13P06jc/L5TgiJXOgrbEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/helper-define-polyfill-provider": "^0.6.5" + }, + "peerDependencies": { + "@babel/core": "^7.4.0 || ^8.0.0-0 <8.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/base64id": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", + "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^4.5.0 || >= 5.9" + } + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw==", + "dev": true, + "license": "MIT" + }, + "node_modules/beasties": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/beasties/-/beasties-0.3.2.tgz", + "integrity": "sha512-p4AF8uYzm9Fwu8m/hSVTCPXrRBPmB34hQpHsec2KOaR9CZmgoU8IOv4Cvwq4hgz2p4hLMNbsdNl5XeA6XbAQwA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "htmlparser2": "^10.0.0", + "picocolors": "^1.1.1", + "postcss": "^8.4.49", + "postcss-media-query-parser": "^0.2.3" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/body-parser": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", + "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "content-type": "~1.0.5", + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "on-finished": "2.4.1", + "qs": "6.13.0", + "raw-body": "2.5.2", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/bonjour-service": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.3.0.tgz", + "integrity": "sha512-3YuAUiSkWykd+2Azjgyxei8OWf8thdn8AITIog2M4UICzoqfjlqr64WIjEXZllf/W6vK1goqleSR6brGomxQqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.5" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==", + "dev": true, + "license": "ISC" + }, + "node_modules/brace-expansion": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", + "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cacache": { + "version": "19.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-19.0.1.tgz", + "integrity": "sha512-hdsUxulXCi5STId78vRVYEtDAjq99ICAUktLTeTYsLoTE6Z8dS0c8pWNCxwdrk9YfJeobDZc2Y186hD/5ZQgFQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/fs": "^4.0.0", + "fs-minipass": "^3.0.0", + "glob": "^10.2.2", + "lru-cache": "^10.0.1", + "minipass": "^7.0.3", + "minipass-collect": "^2.0.1", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "p-map": "^7.0.2", + "ssri": "^12.0.0", + "tar": "^7.4.3", + "unique-filename": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/cacache/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/cacache/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "license": "ISC", + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/cacache/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/cacache/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/cacache/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/call-bound": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", + "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true, + "license": "MIT" + }, + "node_modules/chokidar": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", + "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/cli-cursor": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz", + "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-spinners": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz", + "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-width": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-4.1.0.tgz", + "integrity": "sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">= 12" + } + }, + "node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/clone-deep/node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true, + "license": "ISC" + }, + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/compression": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.8.0.tgz", + "integrity": "sha512-k6WLKfunuqCYD3t6AsuPGvQWaKwuLLh2/xHNcX4qE+vIfDNXpSqnrhwA7O53R7WVQUnt8dVAIW+YHr7xTgOgGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "compressible": "~2.0.18", + "debug": "2.6.9", + "negotiator": "~0.6.4", + "on-headers": "~1.0.2", + "safe-buffer": "5.2.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/compression/node_modules/negotiator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.4.tgz", + "integrity": "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true, + "license": "MIT" + }, + "node_modules/connect": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/connect/-/connect-3.7.0.tgz", + "integrity": "sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "finalhandler": "1.1.2", + "parseurl": "~1.3.3", + "utils-merge": "1.0.1" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/connect-history-api-fallback": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz", + "integrity": "sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8" + } + }, + "node_modules/connect/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/connect/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/content-disposition": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", + "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-type": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cookie": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/copy-anything": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", + "integrity": "sha512-1j20GZTsvKNkc4BY3NpMOM8tt///wY3FpIzozTOFO2ffuZcV61nojHXVKIy3WM+7ADCy5FVhdZYHYDdgTU0yJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-what": "^3.14.1" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-webpack-plugin": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/copy-webpack-plugin/-/copy-webpack-plugin-12.0.2.tgz", + "integrity": "sha512-SNwdBeHyII+rWvee/bTnAYyO8vfVdcSTud4EIb6jcZ8inLeWucJE0DnxXQBjlQ5zlteuuvooGQy3LIyGxhvlOA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-glob": "^3.3.2", + "glob-parent": "^6.0.1", + "globby": "^14.0.0", + "normalize-path": "^3.0.0", + "schema-utils": "^4.2.0", + "serialize-javascript": "^6.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + } + }, + "node_modules/core-js-compat": { + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.44.0.tgz", + "integrity": "sha512-JepmAj2zfl6ogy34qfWtcE7nHKAJnKsQFRn++scjVS2bZFllwptzw61BZcZFYBPpUznLfAvh0LGhxKppk04ClA==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.25.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/cosmiconfig": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/cross-spawn/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/css-loader": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-7.1.2.tgz", + "integrity": "sha512-6WvYYn7l/XEGN8Xu2vWFt9nVzrCn39vKyTEFf/ExEyoksJjjSZV/0/35XPlMbpnr6VGhZIUg5yJrL8tGfes/FA==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.33", + "postcss-modules-extract-imports": "^3.1.0", + "postcss-modules-local-by-default": "^4.0.5", + "postcss-modules-scope": "^3.2.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "webpack": "^5.27.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/css-select": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz", + "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-what": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz", + "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true, + "license": "MIT", + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/custom-event": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/custom-event/-/custom-event-1.0.1.tgz", + "integrity": "sha512-GAj5FOq0Hd+RsCGVJxZuKaIDXDf3h6GQoNEjFgbLLI/trgtavwUbSnZ5pVfg27DVCaWjIohryS0JFwIJyT2cMg==", + "dev": true, + "license": "MIT" + }, + "node_modules/date-format": { + "version": "4.0.14", + "resolved": "https://registry.npmjs.org/date-format/-/date-format-4.0.14.tgz", + "integrity": "sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/debug": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", + "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/default-browser": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz", + "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz", + "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/defaults": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz", + "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/detect-libc": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", + "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true, + "license": "MIT" + }, + "node_modules/di": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/di/-/di-0.0.1.tgz", + "integrity": "sha512-uJaamHkagcZtHPqCIHZxnFrXlunQXgBOsZSUOWwFw31QJCAbyTBoHMW75YOTur5ZNx8pIeAKgf6GWIgaqqiLhA==", + "dev": true, + "license": "MIT" + }, + "node_modules/dns-packet": { + "version": "5.6.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", + "integrity": "sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dom-serialize": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/dom-serialize/-/dom-serialize-2.2.1.tgz", + "integrity": "sha512-Yra4DbvoW7/Z6LBN560ZwXMjoNOSAN2wRsKFGc4iBeso+mpIA6qj1vfdf9HpMaKAqG6wXTy+1SYEzmNpKXOSsQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "custom-event": "~1.0.0", + "ent": "~2.2.0", + "extend": "^3.0.0", + "void-elements": "^2.0.0" + } + }, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz", + "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true, + "license": "MIT" + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "dev": true, + "license": "MIT" + }, + "node_modules/electron-to-chromium": { + "version": "1.5.180", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.180.tgz", + "integrity": "sha512-ED+GEyEh3kYMwt2faNmgMB0b8O5qtATGgR4RmRsIp4T6p7B8vdMbIedYndnvZfsaXvSzegtpfqRMDNCjjiSduA==", + "dev": true, + "license": "ISC" + }, + "node_modules/emoji-regex": { + "version": "10.4.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz", + "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==", + "dev": true, + "license": "MIT" + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/engine.io": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.6.4.tgz", + "integrity": "sha512-ZCkIjSYNDyGn0R6ewHDtXgns/Zre/NT6Agvq1/WobF7JXgFff4SeDroKiCO3fNJreU9YG429Sc81o4w5ok/W5g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/cors": "^2.8.12", + "@types/node": ">=10.0.0", + "accepts": "~1.3.4", + "base64id": "2.0.0", + "cookie": "~0.7.2", + "cors": "~2.8.5", + "debug": "~4.3.1", + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/engine.io-parser": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.3.tgz", + "integrity": "sha512-HqD3yTBfnBxIrbnM1DoD6Pcq8NECnh8d4As1Qgh0z5Gg3jRRIqijury0CL3ghu/edArpUYiYqQiDUQBIs4np3Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/engine.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ent": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ent/-/ent-2.2.2.tgz", + "integrity": "sha512-kKvD1tO6BM+oK9HzCPpUdRb4vKFQY/FPTFmurMvh6LlN68VMrdj77w8yp51/kDbpkFOS9J8w5W6zIzgM2H8/hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.3", + "es-errors": "^1.3.0", + "punycode": "^1.4.1", + "safe-regex-test": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/environment": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz", + "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true, + "license": "MIT" + }, + "node_modules/errno": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.8.tgz", + "integrity": "sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "prr": "~1.0.1" + }, + "bin": { + "errno": "cli.js" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/esbuild": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.4.tgz", + "integrity": "sha512-8pgjLUcUjcgDg+2Q4NYXnPbo/vncAY4UmyaCm0jZevERqCHZIaWwdJHkf8XQtu4AxSKCdvrUbT0XUr1IdZzI8Q==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.25.4", + "@esbuild/android-arm": "0.25.4", + "@esbuild/android-arm64": "0.25.4", + "@esbuild/android-x64": "0.25.4", + "@esbuild/darwin-arm64": "0.25.4", + "@esbuild/darwin-x64": "0.25.4", + "@esbuild/freebsd-arm64": "0.25.4", + "@esbuild/freebsd-x64": "0.25.4", + "@esbuild/linux-arm": "0.25.4", + "@esbuild/linux-arm64": "0.25.4", + "@esbuild/linux-ia32": "0.25.4", + "@esbuild/linux-loong64": "0.25.4", + "@esbuild/linux-mips64el": "0.25.4", + "@esbuild/linux-ppc64": "0.25.4", + "@esbuild/linux-riscv64": "0.25.4", + "@esbuild/linux-s390x": "0.25.4", + "@esbuild/linux-x64": "0.25.4", + "@esbuild/netbsd-arm64": "0.25.4", + "@esbuild/netbsd-x64": "0.25.4", + "@esbuild/openbsd-arm64": "0.25.4", + "@esbuild/openbsd-x64": "0.25.4", + "@esbuild/sunos-x64": "0.25.4", + "@esbuild/win32-arm64": "0.25.4", + "@esbuild/win32-ia32": "0.25.4", + "@esbuild/win32-x64": "0.25.4" + } + }, + "node_modules/esbuild-wasm": { + "version": "0.25.4", + "resolved": "https://registry.npmjs.org/esbuild-wasm/-/esbuild-wasm-0.25.4.tgz", + "integrity": "sha512-2HlCS6rNvKWaSKhWaG/YIyRsTsL3gUrMP2ToZMBIjw9LM7vVcIs+rz8kE2vExvTJgvM8OKPqNpcHawY/BQc/qQ==", + "dev": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true, + "license": "MIT" + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/exponential-backoff": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.2.tgz", + "integrity": "sha512-8QxYTVXUkuy7fIIoitQkPwGonB8F3Zj8eEO8Sqg9Zv/bkI7RJAzowee4gr81Hak/dUTpA2Z7VfQgoijjPNlUZA==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/express": { + "version": "4.21.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", + "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.3", + "content-disposition": "0.5.4", + "content-type": "~1.0.4", + "cookie": "0.7.1", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "2.0.0", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "1.3.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "merge-descriptors": "1.0.3", + "methods": "~1.1.2", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.12", + "proxy-addr": "~2.0.7", + "qs": "6.13.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.2.1", + "send": "0.19.0", + "serve-static": "1.16.2", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" + } + }, + "node_modules/express/node_modules/cookie": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", + "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/finalhandler": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", + "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "on-finished": "2.4.1", + "parseurl": "~1.3.3", + "statuses": "2.0.1", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true, + "license": "MIT" + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "license": "MIT", + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-glob": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", + "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.2", + "merge2": "^1.3.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastq": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", + "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fdir": { + "version": "6.4.6", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", + "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/finalhandler/node_modules/on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-cache-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-4.0.0.tgz", + "integrity": "sha512-9ZonPT4ZAK4a+1pUPVPZJapbi7O5qbbJPdYw/NOQWZZbVLdDTYM3A4R9z/DpAM08IDaFGsvPgiGZ82WEwUDWjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "common-path-prefix": "^3.0.0", + "pkg-dir": "^7.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/find-up": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-6.3.0.tgz", + "integrity": "sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^7.1.0", + "path-exists": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/flatted": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", + "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "dev": true, + "license": "ISC" + }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/foreground-child": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz", + "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==", + "dev": true, + "license": "ISC", + "dependencies": { + "cross-spawn": "^7.0.6", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fraction.js": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz", + "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + }, + "funding": { + "type": "patreon", + "url": "https://github.com/sponsors/rawify" + } + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-minipass": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-3.0.3.tgz", + "integrity": "sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true, + "license": "ISC" + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-east-asian-width": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.3.0.tgz", + "integrity": "sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/globby": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-14.1.0.tgz", + "integrity": "sha512-0Ia46fDOaT7k4og1PDW4YbodWWr3scS2vAr2lTbsplOt2WkKp0vQbkI9wKis/T5LV/dqPjO3bpS/z6GTJB82LA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@sindresorhus/merge-streams": "^2.1.0", + "fast-glob": "^3.3.3", + "ignore": "^7.0.3", + "path-type": "^6.0.0", + "slash": "^5.1.0", + "unicorn-magic": "^0.3.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true, + "license": "MIT" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-8.1.0.tgz", + "integrity": "sha512-Rw/B2DNQaPBICNXEm8balFz9a6WpZrkCGpcWFpy7nCj+NyhSdqXipmfvtmWt9xGfp0wZnBxB+iVpLmQMYt47Tw==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^10.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/hpack.js/node_modules/readable-stream": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", + "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/hpack.js/node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true, + "license": "MIT" + }, + "node_modules/hpack.js/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true, + "license": "MIT" + }, + "node_modules/htmlparser2": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.0.0.tgz", + "integrity": "sha512-TwAZM+zE5Tq3lrEHvOlvwgj1XLWQCtaaibSN11Q+gGBAS7Y1uZSWwXXRe4iF6OXnaq1riyQAPFOBtYc77Mxq0g==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.1", + "entities": "^6.0.0" + } + }, + "node_modules/htmlparser2/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/http-cache-semantics": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", + "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.10.tgz", + "integrity": "sha512-Pysuw9XpUq5dVc/2SMHpuTY01RFl8fttgcyunjL7eEMhGM3cI4eOmiCycJDVCo/7O7ClfQD3SaI6ftDzqOXYMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/http-proxy-agent": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/http-proxy-middleware": { + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz", + "integrity": "sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.15", + "debug": "^4.3.6", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.3", + "is-plain-object": "^5.0.0", + "micromatch": "^4.0.8" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/https-proxy-agent": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", + "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/hyperdyperid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", + "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.18" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/ignore": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", + "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/ignore-walk": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-7.0.0.tgz", + "integrity": "sha512-T4gbf83A4NH95zvhVYZc+qWocBBGlpzUXLPGurJggw/WIOwicfXJChLDP/iBZnN5WqROSu5Bm3hhle4z8a8YGQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minimatch": "^9.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ignore-walk/node_modules/brace-expansion": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", + "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/ignore-walk/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/image-size": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.5.5.tgz", + "integrity": "sha512-6TDAlDPZxUFCv+fuOkIoXT/V/f3Qbq8e37p+YOiYrUv3v9cc3/6x78VdfPgFVaB9dZYeLUfKgHRebpkm/oP2VQ==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "image-size": "bin/image-size.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/immutable": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.1.3.tgz", + "integrity": "sha512-+chQdDfvscSF1SJqv2gn4SRO2ZyS3xL3r7IW/wWEEzrzLisnOlKiQu5ytC/BVNcS15C39WT2Hg/bjKjDMcu+zg==", + "dev": true, + "license": "MIT" + }, + "node_modules/import-fresh": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz", + "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ini": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-5.0.0.tgz", + "integrity": "sha512-+N0ngpO3e7cRUWOJAS7qw0IZIVc6XPrW4MlFBdD066F2L4k1L6ker3hLqSq7iXxU5tgS4WGkIUElWn5vogAEnw==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ipaddr.js": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", + "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/is-network-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-network-error/-/is-network-error-1.1.0.tgz", + "integrity": "sha512-tUdRRAnhT+OtCZR/LxZelH/C7QtjtFrTu5tXCA8pl55eTUElUHT+GPYV8MBMBvea/j+NxQqVt3LbWMRir7Gx9g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", + "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-regex": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", + "integrity": "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "gopd": "^1.2.0", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-what": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-3.14.1.tgz", + "integrity": "sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA==", + "dev": true, + "license": "MIT" + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.3.tgz", + "integrity": "sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^4.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jackspeak": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", + "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/jasmine-core": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-5.5.0.tgz", + "integrity": "sha512-NHOvoPO6o9gVR6pwqEACTEpbgcH+JJ6QDypyymGbSUIFIFsMMbBJ/xsFNud8MSClfnWclXd7RQlAZBz7yVo5TQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "1.21.7", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz", + "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "bin/jiti.js" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsesc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", + "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-4.0.0.tgz", + "integrity": "sha512-lR4MXjGNgkJc7tkQ97kb2nuEMnNCyU//XYVH0MKTGcXEiSudQ5MKGKen3C5QubYy0vmq+JGitUg92uuywGEwIA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "license": "MIT", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==", + "dev": true, + "engines": [ + "node >= 0.2.0" + ], + "license": "MIT" + }, + "node_modules/karma": { + "version": "6.4.4", + "resolved": "https://registry.npmjs.org/karma/-/karma-6.4.4.tgz", + "integrity": "sha512-LrtUxbdvt1gOpo3gxG+VAJlJAEMhbWlM4YrFQgql98FwF7+K8K12LYO4hnDdUkNjeztYrOXEMqgTajSWgmtI/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@colors/colors": "1.5.0", + "body-parser": "^1.19.0", + "braces": "^3.0.2", + "chokidar": "^3.5.1", + "connect": "^3.7.0", + "di": "^0.0.1", + "dom-serialize": "^2.2.1", + "glob": "^7.1.7", + "graceful-fs": "^4.2.6", + "http-proxy": "^1.18.1", + "isbinaryfile": "^4.0.8", + "lodash": "^4.17.21", + "log4js": "^6.4.1", + "mime": "^2.5.2", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.5", + "qjobs": "^1.2.0", + "range-parser": "^1.2.1", + "rimraf": "^3.0.2", + "socket.io": "^4.7.2", + "source-map": "^0.6.1", + "tmp": "^0.2.1", + "ua-parser-js": "^0.7.30", + "yargs": "^16.1.1" + }, + "bin": { + "karma": "bin/karma" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/karma-chrome-launcher": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/karma-chrome-launcher/-/karma-chrome-launcher-3.2.0.tgz", + "integrity": "sha512-rE9RkUPI7I9mAxByQWkGJFXfFD6lE4gC5nPuZdobf/QdTEJI6EU4yIay/cfU/xV4ZxlM5JiTv7zWYgA64NpS5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "which": "^1.2.1" + } + }, + "node_modules/karma-coverage": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/karma-coverage/-/karma-coverage-2.2.1.tgz", + "integrity": "sha512-yj7hbequkQP2qOSb20GuNSIyE//PgJWHwC2IydLE6XRtsnaflv+/OSGNssPjobYUlhVVagy99TQpqUt3vAUG7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "istanbul-lib-coverage": "^3.2.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.1", + "istanbul-reports": "^3.0.5", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/karma-coverage/node_modules/istanbul-lib-instrument": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma-coverage/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/karma-jasmine": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine/-/karma-jasmine-5.1.0.tgz", + "integrity": "sha512-i/zQLFrfEpRyQoJF9fsCdTMOF5c2dK7C7OmsuKg2D0YSsuZSfQDiLuaiktbuio6F2wiCsZSnSnieIQ0ant/uzQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "jasmine-core": "^4.1.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "karma": "^6.0.0" + } + }, + "node_modules/karma-jasmine-html-reporter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/karma-jasmine-html-reporter/-/karma-jasmine-html-reporter-2.1.0.tgz", + "integrity": "sha512-sPQE1+nlsn6Hwb5t+HHwyy0A1FNCVKuL1192b+XNauMYWThz2kweiBVW1DqloRpVvZIJkIoHVB7XRpK78n1xbQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "jasmine-core": "^4.0.0 || ^5.0.0", + "karma": "^6.0.0", + "karma-jasmine": "^5.0.0" + } + }, + "node_modules/karma-jasmine/node_modules/jasmine-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/jasmine-core/-/jasmine-core-4.6.1.tgz", + "integrity": "sha512-VYz/BjjmC3klLJlLwA4Kw8ytk0zDSmbbDLNs794VnWmkcCB7I9aAL/D48VNQtmITyPvea2C3jdUMfc3kAoy0PQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma-source-map-support": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", + "integrity": "sha512-RsBECncGO17KAoJCYXjv+ckIz+Ii9NCi+9enk+rq6XC81ezYkb4/RHE6CTXdA7IOJqoF3wcaLfVG0CPmE5ca6A==", + "dev": true, + "license": "MIT", + "dependencies": { + "source-map-support": "^0.5.5" + } + }, + "node_modules/karma/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/karma/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/karma/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/karma/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/karma/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/karma/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/karma/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/karma/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/karma/node_modules/tmp": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz", + "integrity": "sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "node_modules/karma/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/karma/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/karma/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/launch-editor": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/launch-editor/-/launch-editor-2.10.0.tgz", + "integrity": "sha512-D7dBRJo/qcGX9xlvt/6wUYzQxjh5G1RvZPgPv8vi4KRU99DVQL/oW7tnVOCCTm2HGeo3C5HvGE5Yrh6UBoZ0vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picocolors": "^1.0.0", + "shell-quote": "^1.8.1" + } + }, + "node_modules/less": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/less/-/less-4.2.2.tgz", + "integrity": "sha512-tkuLHQlvWUTeQ3doAqnHbNn8T6WX1KA8yvbKG9x4VtKtIjHsVKQZCH11zRgAfbDAXC2UNIg/K9BYAAcEzUIrNg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "copy-anything": "^2.0.1", + "parse-node-version": "^1.0.1", + "tslib": "^2.3.0" + }, + "bin": { + "lessc": "bin/lessc" + }, + "engines": { + "node": ">=6" + }, + "optionalDependencies": { + "errno": "^0.1.1", + "graceful-fs": "^4.1.2", + "image-size": "~0.5.0", + "make-dir": "^2.1.0", + "mime": "^1.4.1", + "needle": "^3.1.0", + "source-map": "~0.6.0" + } + }, + "node_modules/less-loader": { + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/less-loader/-/less-loader-12.2.0.tgz", + "integrity": "sha512-MYUxjSQSBUQmowc0l5nPieOYwMzGPUaTzB6inNW/bdPEG9zOL3eAAD1Qw5ZxSPk7we5dMojHwNODYMV1hq4EVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "less": "^3.5.0 || ^4.0.0", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/less/node_modules/make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "pify": "^4.0.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/less/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "optional": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/less/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/less/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/license-webpack-plugin": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz", + "integrity": "sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw==", + "dev": true, + "license": "ISC", + "dependencies": { + "webpack-sources": "^3.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-sources": { + "optional": true + } + } + }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2": { + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.5.tgz", + "integrity": "sha512-iyAZCeyD+c1gPyE9qpFu8af0Y+MRtmKOncdGoA2S5EY8iFq99dmmvkNnHiWo+pj0s7yH7l3KPIgee77tKpXPWQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.1.0", + "rfdc": "^1.4.1", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/listr2/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/listr2/node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, + "node_modules/listr2/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/lmdb": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-3.2.6.tgz", + "integrity": "sha512-SuHqzPl7mYStna8WRotY8XX/EUZBjjv3QyKIByeCLFfC9uXT/OIHByEcA07PzbMfQAM0KYJtLgtpMRlIe5dErQ==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "msgpackr": "^1.11.2", + "node-addon-api": "^6.1.0", + "node-gyp-build-optional-packages": "5.2.2", + "ordered-binary": "^1.5.3", + "weak-lru-cache": "^1.2.2" + }, + "bin": { + "download-lmdb-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@lmdb/lmdb-darwin-arm64": "3.2.6", + "@lmdb/lmdb-darwin-x64": "3.2.6", + "@lmdb/lmdb-linux-arm": "3.2.6", + "@lmdb/lmdb-linux-arm64": "3.2.6", + "@lmdb/lmdb-linux-x64": "3.2.6", + "@lmdb/lmdb-win32-x64": "3.2.6" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-3.3.1.tgz", + "integrity": "sha512-FMJTLMXfCLMLfJxcX9PFqX5qD88Z5MRGaZCVzfuqeZSPsyiBzs+pahDQjbIWz2QIzPZz0NX9Zy4FX3lmK6YHIg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/locate-path": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz", + "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^6.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true, + "license": "MIT" + }, + "node_modules/lodash.debounce": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", + "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==", + "dev": true, + "license": "MIT" + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz", + "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-escapes": "^7.0.0", + "cli-cursor": "^5.0.0", + "slice-ansi": "^7.1.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.0.0.tgz", + "integrity": "sha512-GdYO7a61mR0fOlAsvC9/rIHf7L96sBc6dEWzeOu+KAea5bZyQRPIpojrVoI4AXGJS/ycu/fBTdLrUkA4ODrvjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "environment": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/log-update/node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/log4js": { + "version": "6.9.1", + "resolved": "https://registry.npmjs.org/log4js/-/log4js-6.9.1.tgz", + "integrity": "sha512-1somDdy9sChrr9/f4UlzhdaGfDR2c/SaD2a4T7qEkG4jTS57/B3qmnjLYePwQ8cqWnUHZI0iAKxMBpCZICiZ2g==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "flatted": "^3.2.7", + "rfdc": "^1.3.0", + "streamroller": "^3.1.5" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^3.0.2" + } + }, + "node_modules/magic-string": { + "version": "0.30.17", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", + "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0" + } + }, + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^7.5.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-fetch-happen": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-14.0.3.tgz", + "integrity": "sha512-QMjGbFTP0blj97EeidG5hk/QhKQ3T4ICckQGLgz38QF7Vgbk6e6FTARN8KhKxyBbWn8R0HU+bnw8aSoFPD4qtQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/agent": "^3.0.0", + "cacache": "^19.0.1", + "http-cache-semantics": "^4.1.1", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^1.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "ssri": "^12.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "4.17.2", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.17.2.tgz", + "integrity": "sha512-NgYhCOWgovOXSzvYgUW0LQ7Qy72rWQMGGFJDoWg4G30RHd3z77VbYdtJ4fembJXBy8pMIUA31XNAupobOQlwdg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@jsonjoy.com/json-pack": "^1.0.3", + "@jsonjoy.com/util": "^1.3.0", + "tree-dump": "^1.0.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">= 4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/mimic-function": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz", + "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.2.tgz", + "integrity": "sha512-GJuACcS//jtq4kCtd5ii/M0SZf7OZRH+BxdqXZHaJfb8TJiVl+NgQRPwiYt2EuqeSkNydn/7vP+bcE27C5mb9w==", + "dev": true, + "license": "MIT", + "dependencies": { + "schema-utils": "^4.0.0", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-collect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-2.0.1.tgz", + "integrity": "sha512-D7V8PO9oaz7PWGLbCACuI1qEOsq7UKfLotx/C0Aet43fCUB/wfQ7DYeq2oR/svFJGYDHPr38SHATeaj/ZoKHKw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/minipass-fetch": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-4.0.1.tgz", + "integrity": "sha512-j7U11C5HXigVuutxebFadoYBbd7VSdZWggSe64NVdvWNBqGAiXPL2QVCehjmw7lY1oF9gOllYbORh+hiNgfPgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.0.3", + "minipass-sized": "^1.0.3", + "minizlib": "^3.0.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-flush/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-pipeline/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/minizlib": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.2.tgz", + "integrity": "sha512-oG62iEk+CYt5Xj2YqI5Xi9xWUeZhDI8jjQmC5oThVH5JGCTgIjr7ciJDzC7MBzYd//WvR1OTmP5Q38Q8ShQtVA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^7.1.2" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mrmime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.1.tgz", + "integrity": "sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/msgpackr": { + "version": "1.11.4", + "resolved": "https://registry.npmjs.org/msgpackr/-/msgpackr-1.11.4.tgz", + "integrity": "sha512-uaff7RG9VIC4jacFW9xzL3jc0iM32DNHe4jYVycBcjUePT/Klnfj7pqtWJt9khvDFizmjN2TlYniYmSS2LIaZg==", + "dev": true, + "license": "MIT", + "optional": true, + "optionalDependencies": { + "msgpackr-extract": "^3.0.2" + } + }, + "node_modules/msgpackr-extract": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/msgpackr-extract/-/msgpackr-extract-3.0.3.tgz", + "integrity": "sha512-P0efT1C9jIdVRefqjzOQ9Xml57zpOXnIuS+csaB4MdZbTdmGDLo8XhzBG1N7aO11gKDDkJvBLULeFTo46wwreA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.2.2" + }, + "bin": { + "download-msgpackr-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.3", + "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.3" + } + }, + "node_modules/multicast-dns": { + "version": "7.2.5", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.5.tgz", + "integrity": "sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg==", + "dev": true, + "license": "MIT", + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/mute-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-2.0.0.tgz", + "integrity": "sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/needle": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/needle/-/needle-3.3.1.tgz", + "integrity": "sha512-6k0YULvhpw+RoLNiQCRKOl09Rv1dPLr8hHnVjHqdolKwDrdNyk+Hmrthi4lIGPPz3r39dLx0hsF5s40sZ3Us4Q==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.3", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/negotiator": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", + "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-addon-api": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-6.1.0.tgz", + "integrity": "sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "license": "(BSD-3-Clause OR GPL-2.0)", + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-11.2.0.tgz", + "integrity": "sha512-T0S1zqskVUSxcsSTkAsLc7xCycrRYmtDHadDinzocrThjyQCn5kMlEBSj6H4qDbgsIOSLmmlRIeb0lZXj+UArA==", + "dev": true, + "license": "MIT", + "dependencies": { + "env-paths": "^2.2.0", + "exponential-backoff": "^3.1.1", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^14.0.3", + "nopt": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "tar": "^7.4.3", + "tinyglobby": "^0.2.12", + "which": "^5.0.0" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.2.2.tgz", + "integrity": "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, + "node_modules/node-gyp/node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/isexe": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", + "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=16" + } + }, + "node_modules/node-gyp/node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/node-gyp/node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "dev": true, + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/node-gyp/node_modules/which": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/which/-/which-5.0.0.tgz", + "integrity": "sha512-JEdGzHwwkrbWoGOlIHqQ5gtprKGOenpDHpxE9zVR1bWbOtYRyPPHMe9FaP6x61CmNaTThSkb0DAJte5jD+DmzQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^3.1.1" + }, + "bin": { + "node-which": "bin/which.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/node-gyp/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/nopt": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-8.1.0.tgz", + "integrity": "sha512-ieGu42u/Qsa4TFktmaKEwM6MQH0pOWnaB3htzh0JRtx84+Mebc0cbZYN5bC+6WTZ4+77xrL9Pn5m7CV6VIkV7A==", + "dev": true, + "license": "ISC", + "dependencies": { + "abbrev": "^3.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-bundled": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-4.0.0.tgz", + "integrity": "sha512-IxaQZDMsqfQ2Lz37VvyyEtKLe8FsRZuysmedy/N06TU1RyVppYKXrO4xIhR0F+7ubIBox6Q7nir6fQI3ej39iA==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-normalize-package-bin": "^4.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-install-checks": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/npm-install-checks/-/npm-install-checks-7.1.1.tgz", + "integrity": "sha512-u6DCwbow5ynAX5BdiHQ9qvexme4U3qHW3MWe5NqH+NeBm0LbiH6zvGjNNew1fY+AZZUtVHbOPF3j7mJxbUzpXg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "semver": "^7.1.1" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-normalize-package-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-4.0.0.tgz", + "integrity": "sha512-TZKxPvItzai9kN9H/TkmCtx/ZN/hvr3vUycjlfmH0ootY9yFBzNOpiXAdIn1Iteqsvk4lQn6B5PTrt+n6h8k/w==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-package-arg": { + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-12.0.2.tgz", + "integrity": "sha512-f1NpFjNI9O4VbKMOlA5QoBq/vSQPORHcTZ2feJpFkTHJ9eQkdlmZEKSjcAhxTGInC7RlEyScT9ui67NaOsjFWA==", + "dev": true, + "license": "ISC", + "dependencies": { + "hosted-git-info": "^8.0.0", + "proc-log": "^5.0.0", + "semver": "^7.3.5", + "validate-npm-package-name": "^6.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-packlist": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-9.0.0.tgz", + "integrity": "sha512-8qSayfmHJQTx3nJWYbbUmflpyarbLMBc6LCAjYsiGtXxDB68HaZpb8re6zeaLGxZzDuMdhsg70jryJe+RrItVQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "ignore-walk": "^7.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-pick-manifest": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-10.0.0.tgz", + "integrity": "sha512-r4fFa4FqYY8xaM7fHecQ9Z2nE9hgNfJR+EmoKv0+chvzWkBcORX3r0FpTByP+CbOVJDladMXnPQGVN8PBLGuTQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "npm-install-checks": "^7.1.0", + "npm-normalize-package-bin": "^4.0.0", + "npm-package-arg": "^12.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/npm-registry-fetch": { + "version": "18.0.2", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-18.0.2.tgz", + "integrity": "sha512-LeVMZBBVy+oQb5R6FDV9OlJCcWDU+al10oKpe+nsvcHnG24Z3uM3SvJYKfGJlfGjVU8v9liejCrUR/M5HO5NEQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/redact": "^3.0.0", + "jsonparse": "^1.3.1", + "make-fetch-happen": "^14.0.0", + "minipass": "^7.0.2", + "minipass-fetch": "^4.0.0", + "minizlib": "^3.0.1", + "npm-package-arg": "^12.0.0", + "proc-log": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-inspect": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", + "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true, + "license": "MIT" + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "dev": true, + "license": "MIT", + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz", + "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-function": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz", + "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ora/node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ora/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ordered-binary": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ordered-binary/-/ordered-binary-1.6.0.tgz", + "integrity": "sha512-IQh2aMfMIDbPjI/8a3Edr+PiOpcsB7yo8NdW7aHWVaoR/pcDldunMvnnwbk/auPGqmKeAdxtZl7MHX/QmPwhvQ==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz", + "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "yocto-queue": "^1.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz", + "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-7.0.3.tgz", + "integrity": "sha512-VkndIv2fIB99swvQoA65bm+fsmt6UNdGeIB0oxBs+WhAhdh08QA04JXpI7rbB9r08/nkbysKoya9rtDERYOYMA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-6.2.1.tgz", + "integrity": "sha512-hEt02O4hUct5wtwg4H4KcWgDdm+l1bOaEy/hWzd8xtXB9BqxTWBBhb+2ImAtH4Cv4rPjV76xN3Zumqk3k3AhhQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/retry": "0.12.2", + "is-network-error": "^1.0.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/package-json-from-dist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", + "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", + "dev": true, + "license": "BlueOak-1.0.0" + }, + "node_modules/pacote": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-20.0.0.tgz", + "integrity": "sha512-pRjC5UFwZCgx9kUFDVM9YEahv4guZ1nSLqwmWiLUnDbGsjs+U5w7z6Uc8HNR1a6x8qnu5y9xtGE6D1uAuYz+0A==", + "dev": true, + "license": "ISC", + "dependencies": { + "@npmcli/git": "^6.0.0", + "@npmcli/installed-package-contents": "^3.0.0", + "@npmcli/package-json": "^6.0.0", + "@npmcli/promise-spawn": "^8.0.0", + "@npmcli/run-script": "^9.0.0", + "cacache": "^19.0.0", + "fs-minipass": "^3.0.0", + "minipass": "^7.0.2", + "npm-package-arg": "^12.0.0", + "npm-packlist": "^9.0.0", + "npm-pick-manifest": "^10.0.0", + "npm-registry-fetch": "^18.0.0", + "proc-log": "^5.0.0", + "promise-retry": "^2.0.1", + "sigstore": "^3.0.0", + "ssri": "^12.0.0", + "tar": "^6.1.11" + }, + "bin": { + "pacote": "bin/index.js" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "license": "MIT", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse-json/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/parse-node-version": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz", + "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-html-rewriting-stream": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-html-rewriting-stream/-/parse5-html-rewriting-stream-7.0.0.tgz", + "integrity": "sha512-mazCyGWkmCRWDI15Zp+UiCqMp/0dgEmkZRvhlsqqKYr4SsVm/TvnSpD9fCvqCA2zoWJcfRym846ejWBBHRiYEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^4.3.0", + "parse5": "^7.0.0", + "parse5-sax-parser": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-sax-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/parse5-sax-parser/-/parse5-sax-parser-7.0.0.tgz", + "integrity": "sha512-5A+v2SNsq8T6/mG3ahcz8ZtQ0OUFTatxPbeidoMB7tkJSGDY3tdfl4MHovtLQHkEn5CGxijNWRQHhRQ6IRpXKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-scurry": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", + "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "lru-cache": "^10.2.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + }, + "engines": { + "node": ">=16 || 14 >=14.18" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/path-scurry/node_modules/lru-cache": { + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", + "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/path-to-regexp": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", + "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/path-type": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-6.0.0.tgz", + "integrity": "sha512-Vj7sf++t5pBD637NSfkxpHSMfWaeig5+DKWLhcqIYx6mWQz5hdJTGDVMQiJcw1ZYkhs7AazKDGpRVji1LJCZUQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/piscina": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/piscina/-/piscina-4.8.0.tgz", + "integrity": "sha512-EZJb+ZxDrQf3dihsUL7p42pjNyrNIFJCrRHPMgxu/svsj+P3xS3fuEWp7k2+rfsavfl1N0G29b1HGs7J0m8rZA==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "@napi-rs/nice": "^1.0.1" + } + }, + "node_modules/pkg-dir": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-7.0.0.tgz", + "integrity": "sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^6.3.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/postcss": { + "version": "8.5.2", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.2.tgz", + "integrity": "sha512-MjOadfU3Ys9KYoX0AdkBlFEF1Vx37uCCeN4ZHnmwm9FfpbsGWMZeBLMmmpY+6Ocqod7mkdZ0DT31OlbsFrLlkA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.8", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-loader": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-8.1.1.tgz", + "integrity": "sha512-0IeqyAsG6tYiDRCYKQJLAmgQr47DX6N7sFSWvQxt6AcupX8DIdmykuk/o/tx0Lze3ErGHJEp5OSRxrelC6+NdQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "cosmiconfig": "^9.0.0", + "jiti": "^1.20.0", + "semver": "^7.5.4" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "postcss": "^7.0.0 || ^8.0.1", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/postcss-media-query-parser": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", + "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.1.0.tgz", + "integrity": "sha512-k3kNe0aNFQDAZGbin48pL2VNidTF0w4/eASDsxlyspobzU3wZQLOGj7L9gfRe0Jo9/4uud09DsjFNH7winGv8Q==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.2.0.tgz", + "integrity": "sha512-5kcJm/zk+GJDSfw+V/42fJ5fhjL5YbFDl8nVdXkJPLLW+Vf9mTD5Xe0wqIaDnLuL2U6cDNpTr+UQ+v2HWIBhzw==", + "dev": true, + "license": "MIT", + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^7.0.0", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.2.1.tgz", + "integrity": "sha512-m9jZstCVaqGjTAuny8MdgE88scJnCiQSlSrOWcTQgM2t32UBe+MUmFSO5t7VMSfAf/FJKImAxBav8ooCHJXCJA==", + "dev": true, + "license": "ISC", + "dependencies": { + "postcss-selector-parser": "^7.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-selector-parser": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-7.1.0.tgz", + "integrity": "sha512-8sLjZwK0R+JlxlYcTuVnyT2v+htpdrjDOKuMcOVdYjt52Lh8hWRYpxBPoKx/Zg+bcjc3wx6fmQevMmUztS/ccA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/proc-log": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-5.0.0.tgz", + "integrity": "sha512-Azwzvl90HaF0aCz1JrDdXQykFakSSNPaPoiZ9fm5qJIMHioDZEi7OAdRwSm6rSoPtY3Qutnm3L7ogmg3dc+wbQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true, + "license": "MIT" + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "license": "MIT", + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/qjobs": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/qjobs/-/qjobs-1.2.0.tgz", + "integrity": "sha512-8YOJEHtxpySA3fFDyCRxA+UUV+fA+rTWnuWvylOK/NCjhY+b4ocCtmu8TtsWb+mYeU+GCHf/S66KZF/AsteKHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.9" + } + }, + "node_modules/qs": { + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", + "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "dev": true, + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/readdirp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", + "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "node_modules/reflect-metadata": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/reflect-metadata/-/reflect-metadata-0.2.2.tgz", + "integrity": "sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/regenerate": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", + "integrity": "sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A==", + "dev": true, + "license": "MIT" + }, + "node_modules/regenerate-unicode-properties": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz", + "integrity": "sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regenerator-runtime": { + "version": "0.14.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz", + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==", + "dev": true, + "license": "MIT" + }, + "node_modules/regex-parser": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.3.1.tgz", + "integrity": "sha512-yXLRqatcCuKtVHsWrNg0JL3l1zGfdXeEvDa0bdu4tCDQw0RpMDZsqbkyRTUnKMR0tXF627V2oEWjBEaEdqTwtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/regexpu-core": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-6.2.0.tgz", + "integrity": "sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA==", + "dev": true, + "license": "MIT", + "dependencies": { + "regenerate": "^1.4.2", + "regenerate-unicode-properties": "^10.2.0", + "regjsgen": "^0.8.0", + "regjsparser": "^0.12.0", + "unicode-match-property-ecmascript": "^2.0.0", + "unicode-match-property-value-ecmascript": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/regjsgen": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.8.0.tgz", + "integrity": "sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/regjsparser": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.12.0.tgz", + "integrity": "sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~3.0.2" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", + "dev": true, + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-url-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz", + "integrity": "sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg==", + "dev": true, + "license": "MIT", + "dependencies": { + "adjust-sourcemap-loader": "^4.0.0", + "convert-source-map": "^1.7.0", + "loader-utils": "^2.0.0", + "postcss": "^8.2.14", + "source-map": "0.6.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/resolve-url-loader/node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "license": "MIT", + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "node_modules/resolve-url-loader/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/restore-cursor": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz", + "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==", + "dev": true, + "license": "MIT", + "dependencies": { + "onetime": "^7.0.0", + "signal-exit": "^4.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", + "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", + "dev": true, + "license": "MIT", + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "dev": true, + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/rollup": { + "version": "4.34.8", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.34.8.tgz", + "integrity": "sha512-489gTVMzAYdiZHFVA/ig/iYFllCcWFHMvUHI1rpFmkoUtRlQxqh6/yiNqnYibjMZ2b/+FUQwldG+aLsEt6bglQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.6" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.34.8", + "@rollup/rollup-android-arm64": "4.34.8", + "@rollup/rollup-darwin-arm64": "4.34.8", + "@rollup/rollup-darwin-x64": "4.34.8", + "@rollup/rollup-freebsd-arm64": "4.34.8", + "@rollup/rollup-freebsd-x64": "4.34.8", + "@rollup/rollup-linux-arm-gnueabihf": "4.34.8", + "@rollup/rollup-linux-arm-musleabihf": "4.34.8", + "@rollup/rollup-linux-arm64-gnu": "4.34.8", + "@rollup/rollup-linux-arm64-musl": "4.34.8", + "@rollup/rollup-linux-loongarch64-gnu": "4.34.8", + "@rollup/rollup-linux-powerpc64le-gnu": "4.34.8", + "@rollup/rollup-linux-riscv64-gnu": "4.34.8", + "@rollup/rollup-linux-s390x-gnu": "4.34.8", + "@rollup/rollup-linux-x64-gnu": "4.34.8", + "@rollup/rollup-linux-x64-musl": "4.34.8", + "@rollup/rollup-win32-arm64-msvc": "4.34.8", + "@rollup/rollup-win32-ia32-msvc": "4.34.8", + "@rollup/rollup-win32-x64-msvc": "4.34.8", + "fsevents": "~2.3.2" + } + }, + "node_modules/run-applescript": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz", + "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/rxjs": { + "version": "7.8.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.2.tgz", + "integrity": "sha512-dhKf903U/PQZY6boNNtAGdWbG85WAbjT/1xYoZIC7FAY0yWapOBQVsVrDl58W86//e1VpMNBtRV4MaXfdMySFA==", + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.1.0.tgz", + "integrity": "sha512-x/+Cz4YrimQxQccJf5mKEbIa1NzeCRNI5Ecl/ekmlYaampdNLPalVyIcCZNNH3MvmqBugV5TMYZXv0ljslUlaw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "is-regex": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sass": { + "version": "1.85.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.85.0.tgz", + "integrity": "sha512-3ToiC1xZ1Y8aU7+CkgCI/tqyuPXEmYGJXO7H4uqp0xkLXUqp88rQQ4j1HmP37xSJLbCJPaIiv+cT1y+grssrww==", + "dev": true, + "license": "MIT", + "dependencies": { + "chokidar": "^4.0.0", + "immutable": "^5.0.2", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=14.0.0" + }, + "optionalDependencies": { + "@parcel/watcher": "^2.4.1" + } + }, + "node_modules/sass-loader": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-16.0.5.tgz", + "integrity": "sha512-oL+CMBXrj6BZ/zOq4os+UECPL+bWqt6OAC6DWS8Ln8GZRcMDjlJ4JC3FBDuHJdYaFWIdKNIBYmtZtK2MaMkNIw==", + "dev": true, + "license": "MIT", + "dependencies": { + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "@rspack/core": "0.x || 1.x", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@rspack/core": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "webpack": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "dev": true, + "license": "ISC", + "optional": true + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/schema-utils/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg==", + "dev": true, + "license": "MIT" + }, + "node_modules/selfsigned": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.4.1.tgz", + "integrity": "sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node-forge": "^1.3.0", + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz", + "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/send": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", + "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true, + "license": "MIT" + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/serve-static": { + "version": "1.16.2", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", + "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "dev": true, + "license": "MIT", + "dependencies": { + "encodeurl": "~2.0.0", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.19.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-static/node_modules/encodeurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", + "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true, + "license": "ISC" + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/shell-quote": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.8.3.tgz", + "integrity": "sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", + "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-list": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", + "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-map": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", + "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/side-channel-weakmap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", + "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/sigstore": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/sigstore/-/sigstore-3.1.0.tgz", + "integrity": "sha512-ZpzWAFHIFqyFE56dXqgX/DkDRZdz+rRcjoIk/RQU4IX0wiCv1l8S7ZrXDHcCc+uaf+6o7w3h2l3g6GYG5TKN9Q==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@sigstore/bundle": "^3.1.0", + "@sigstore/core": "^2.0.0", + "@sigstore/protobuf-specs": "^0.4.0", + "@sigstore/sign": "^3.1.0", + "@sigstore/tuf": "^3.1.0", + "@sigstore/verify": "^2.1.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/slash": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", + "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socket.io": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.8.1.tgz", + "integrity": "sha512-oZ7iUCxph8WYRHHcjBEc9unw3adt5CmSNlppj/5Q4k2RIrhl8Z5yY2Xr4j9zj0+wzVZ0bxmYoGSzKJnRl6A4yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.6.0", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" + }, + "engines": { + "node": ">=10.2.0" + } + }, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "~4.3.4", + "ws": "~8.17.1" + } + }, + "node_modules/socket.io-adapter/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "dev": true, + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/socket.io-parser/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/socket.io/node_modules/debug": { + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", + "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "dev": true, + "license": "MIT", + "dependencies": { + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/socks-proxy-agent": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz", + "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "^4.3.4", + "socks": "^2.8.3" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-loader": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/source-map-loader/-/source-map-loader-5.0.0.tgz", + "integrity": "sha512-k2Dur7CbSLcAH73sBcIkV5xjPV4SzqO1NJ7+XaQl8if3VODDUj3FNchNGpqgJSKbvUfJuhVdv8K2Eu8/TNl2eA==", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.72.1" + } + }, + "node_modules/source-map-loader/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.21", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.21.tgz", + "integrity": "sha512-Bvg/8F5XephndSK3JffaRqdT+gyhfqIPwDHpX80tJrF8QQRYMo8sNMeaZ2Dp5+jhwKnUmIOyFFQfHRkjJm5nXg==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "license": "MIT", + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/ssri": { + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-12.0.0.tgz", + "integrity": "sha512-S7iGNosepx9RadX82oimUkvr0Ct7IjJbEbs4mJcTxst8um95J3sDYU1RBEOvdu6oL1Wek2ODI5i4MAw+dZ6cAQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^7.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/streamroller": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-3.1.5.tgz", + "integrity": "sha512-KFxaM7XT+irxvdqSP1LGLgNWbYN7ay5owZ3r/8t77p+EtSUAfUgtl7be3xtqtOmGUl9K9YPO2ca8133RlTjvKw==", + "dev": true, + "license": "MIT", + "dependencies": { + "date-format": "^4.0.14", + "debug": "^4.3.4", + "fs-extra": "^8.1.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string-width": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", + "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "dev": true, + "license": "ISC", + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^5.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "license": "ISC", + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/fs-minipass/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-5.0.0.tgz", + "integrity": "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "license": "MIT", + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/tar/node_modules/minizlib/node_modules/minipass": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.3.6.tgz", + "integrity": "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, + "node_modules/terser": { + "version": "5.39.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.39.0.tgz", + "integrity": "sha512-LBAhFyLho16harJoWMg/nZsQYgTrg5jXOn2nCYjRUcZZEdE3qa2zb8QEDRUGVZBW4rlazf2fxkg8tztybTaqWw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/thingies": { + "version": "1.21.0", + "resolved": "https://registry.npmjs.org/thingies/-/thingies-1.21.0.tgz", + "integrity": "sha512-hsqsJsFMsV+aD4s3CWKk85ep/3I9XzYV/IXaSouJMYIoDlgyi11cBhsqYe9/geRfB0YIikBQg6raRaM+nIMP9g==", + "dev": true, + "license": "Unlicense", + "engines": { + "node": ">=10.18" + }, + "peerDependencies": { + "tslib": "^2" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyglobby": { + "version": "0.2.14", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", + "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.4.4", + "picomatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "license": "MIT", + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6" + } + }, + "node_modules/tree-dump": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.0.3.tgz", + "integrity": "sha512-il+Cv80yVHFBwokQSfd4bldvr1Md951DpgAGfmhydt04L+YzHgubm2tQ7zueWDcGENKHq0ZvGFR/hjvNXilHEg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=10.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/streamich" + }, + "peerDependencies": { + "tslib": "2" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "license": "0BSD" + }, + "node_modules/tuf-js": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tuf-js/-/tuf-js-3.1.0.tgz", + "integrity": "sha512-3T3T04WzowbwV2FDiGXBbr81t64g1MUGGJRgT4x5o97N+8ArdhVCAF9IxFrxuSJmM3E5Asn7nKHkao0ibcZXAg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@tufjs/models": "3.0.1", + "debug": "^4.4.1", + "make-fetch-happen": "^14.0.3" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/type-fest": { + "version": "0.21.3", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", + "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typed-assert": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/typed-assert/-/typed-assert-1.0.9.tgz", + "integrity": "sha512-KNNZtayBCtmnNmbo5mG47p1XsCyrx6iVqomjcZnec/1Y5GGARaxPs6r49RnSPeUP3YjNYiU9sQHAtY4BBvnZwg==", + "dev": true, + "license": "MIT" + }, + "node_modules/typescript": { + "version": "5.7.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz", + "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/ua-parser-js": { + "version": "0.7.40", + "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.40.tgz", + "integrity": "sha512-us1E3K+3jJppDBa3Tl0L3MOJiGhe1C6P0+nIvQAFYbxlMAx0h81eOwLmU57xgqToduDDPx3y5QsdjPfDu+FgOQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/ua-parser-js" + }, + { + "type": "paypal", + "url": "https://paypal.me/faisalman" + }, + { + "type": "github", + "url": "https://github.com/sponsors/faisalman" + } + ], + "license": "MIT", + "bin": { + "ua-parser-js": "script/cli.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/unicode-canonical-property-names-ecmascript": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", + "integrity": "sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-ecmascript": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz", + "integrity": "sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "unicode-canonical-property-names-ecmascript": "^2.0.0", + "unicode-property-aliases-ecmascript": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-match-property-value-ecmascript": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz", + "integrity": "sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicode-property-aliases-ecmascript": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", + "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/unicorn-magic": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz", + "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unique-filename": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-4.0.0.tgz", + "integrity": "sha512-XSnEewXmQ+veP7xX2dS5Q4yZAvO40cBN2MWkJ7D/6sW4Dg6wYBNwM1Vrnz1FhH5AdeLIlUXRI9e28z1YZi71NQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "unique-slug": "^5.0.0" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/unique-slug": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-5.0.0.tgz", + "integrity": "sha512-9OdaqO5kwqR+1kVgHAhsp5vPNU0hnxRa26rBFNfNgM7M6pNtgzeBn3s/xbyCQL3dcjzOatcef6UUHpB/6MaETg==", + "dev": true, + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", + "dev": true, + "license": "MIT" + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.1.tgz", + "integrity": "sha512-OaI//3H0J7ZkR1OqlhGA8cA+Cbk/2xFOQpJOt5+s27/ta9eZwpeervh4Mxh4w0im/kdgktowaqVNR7QOrUd7Yg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/vite": { + "version": "6.3.5", + "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz", + "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "esbuild": "^0.25.0", + "fdir": "^6.4.4", + "picomatch": "^4.0.2", + "postcss": "^8.5.3", + "rollup": "^4.34.9", + "tinyglobby": "^0.2.13" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || ^20.0.0 || >=22.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", + "jiti": ">=1.21.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.2.tgz", + "integrity": "sha512-g0dF8P1e2QYPOj1gu7s/3LVP6kze9A7m6x0BZ9iTdXK8N5c2V7cpBKHV3/9A4Zd8xxavdhK0t4PnqjkqVmUc9Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-android-arm64": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.44.2.tgz", + "integrity": "sha512-Yt5MKrOosSbSaAK5Y4J+vSiID57sOvpBNBR6K7xAaQvk3MkcNVV0f9fE20T+41WYN8hDn6SGFlFrKudtx4EoxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.44.2.tgz", + "integrity": "sha512-EsnFot9ZieM35YNA26nhbLTJBHD0jTwWpPwmRVDzjylQT6gkar+zenfb8mHxWpRrbn+WytRRjE0WKsfaxBkVUA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-darwin-x64": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.44.2.tgz", + "integrity": "sha512-dv/t1t1RkCvJdWWxQ2lWOO+b7cMsVw5YFaS04oHpZRWehI1h0fV1gF4wgGCTyQHHjJDfbNpwOi6PXEafRBBezw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.44.2.tgz", + "integrity": "sha512-W4tt4BLorKND4qeHElxDoim0+BsprFTwb+vriVQnFFtT/P6v/xO5I99xvYnVzKWrK6j7Hb0yp3x7V5LUbaeOMg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.44.2.tgz", + "integrity": "sha512-tdT1PHopokkuBVyHjvYehnIe20fxibxFCEhQP/96MDSOcyjM/shlTkZZLOufV3qO6/FQOSiJTBebhVc12JyPTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.44.2.tgz", + "integrity": "sha512-+xmiDGGaSfIIOXMzkhJ++Oa0Gwvl9oXUeIiwarsdRXSe27HUIvjbSIpPxvnNsRebsNdUo7uAiQVgBD1hVriwSQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.44.2.tgz", + "integrity": "sha512-bDHvhzOfORk3wt8yxIra8N4k/N0MnKInCW5OGZaeDYa/hMrdPaJzo7CSkjKZqX4JFUWjUGm88lI6QJLCM7lDrA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.44.2.tgz", + "integrity": "sha512-NMsDEsDiYghTbeZWEGnNi4F0hSbGnsuOG+VnNvxkKg0IGDvFh7UVpM/14mnMwxRxUf9AdAVJgHPvKXf6FpMB7A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.44.2.tgz", + "integrity": "sha512-lb5bxXnxXglVq+7imxykIp5xMq+idehfl+wOgiiix0191av84OqbjUED+PRC5OA8eFJYj5xAGcpAZ0pF2MnW+A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.44.2.tgz", + "integrity": "sha512-Yl5Rdpf9pIc4GW1PmkUGHdMtbx0fBLE1//SxDmuf3X0dUC57+zMepow2LK0V21661cjXdTn8hO2tXDdAWAqE5g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.44.2.tgz", + "integrity": "sha512-03vUDH+w55s680YYryyr78jsO1RWU9ocRMaeV2vMniJJW/6HhoTBwyyiiTPVHNWLnhsnwcQ0oH3S9JSBEKuyqw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.44.2.tgz", + "integrity": "sha512-iYtAqBg5eEMG4dEfVlkqo05xMOk6y/JXIToRca2bAWuqjrJYJlx/I7+Z+4hSrsWU8GdJDFPL4ktV3dy4yBSrzg==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.44.2.tgz", + "integrity": "sha512-evFOtkmVdY3udE+0QKrV5wBx7bKI0iHz5yEVx5WqDJkxp9YQefy4Mpx3RajIVcM6o7jxTvVd/qpC1IXUhGc1Mw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.44.2.tgz", + "integrity": "sha512-/bXb0bEsWMyEkIsUL2Yt5nFB5naLAwyOWMEviQfQY1x3l5WsLKgvZf66TM7UTfED6erckUVUJQ/jJ1FSpm3pRQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.44.2.tgz", + "integrity": "sha512-3D3OB1vSSBXmkGEZR27uiMRNiwN08/RVAcBKwhUYPaiZ8bcvdeEwWPvbnXvvXHY+A/7xluzcN+kaiOFNiOZwWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.44.2.tgz", + "integrity": "sha512-VfU0fsMK+rwdK8mwODqYeM2hDrF2WiHaSmCBrS7gColkQft95/8tphyzv2EupVxn3iE0FI78wzffoULH1G+dkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.44.2.tgz", + "integrity": "sha512-+qMUrkbUurpE6DVRjiJCNGZBGo9xM4Y0FXU5cjgudWqIBWbcLkjE3XprJUsOFgC6xjBClwVa9k6O3A7K3vxb5Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.44.2.tgz", + "integrity": "sha512-3+QZROYfJ25PDcxFF66UEk8jGWigHJeecZILvkPkyQN7oc5BvFo4YEXFkOs154j3FTMp9mn9Ky8RCOwastduEA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true + }, + "node_modules/vite/node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT", + "peer": true + }, + "node_modules/vite/node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "peer": true, + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/vite/node_modules/rollup": { + "version": "4.44.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.44.2.tgz", + "integrity": "sha512-PVoapzTwSEcelaWGth3uR66u7ZRo6qhPHc0f2uRO9fX6XDVNrIiGYS0Pj9+R8yIIYSD/mCx2b16Ws9itljKSPg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.44.2", + "@rollup/rollup-android-arm64": "4.44.2", + "@rollup/rollup-darwin-arm64": "4.44.2", + "@rollup/rollup-darwin-x64": "4.44.2", + "@rollup/rollup-freebsd-arm64": "4.44.2", + "@rollup/rollup-freebsd-x64": "4.44.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.44.2", + "@rollup/rollup-linux-arm-musleabihf": "4.44.2", + "@rollup/rollup-linux-arm64-gnu": "4.44.2", + "@rollup/rollup-linux-arm64-musl": "4.44.2", + "@rollup/rollup-linux-loongarch64-gnu": "4.44.2", + "@rollup/rollup-linux-powerpc64le-gnu": "4.44.2", + "@rollup/rollup-linux-riscv64-gnu": "4.44.2", + "@rollup/rollup-linux-riscv64-musl": "4.44.2", + "@rollup/rollup-linux-s390x-gnu": "4.44.2", + "@rollup/rollup-linux-x64-gnu": "4.44.2", + "@rollup/rollup-linux-x64-musl": "4.44.2", + "@rollup/rollup-win32-arm64-msvc": "4.44.2", + "@rollup/rollup-win32-ia32-msvc": "4.44.2", + "@rollup/rollup-win32-x64-msvc": "4.44.2", + "fsevents": "~2.3.2" + } + }, + "node_modules/void-elements": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz", + "integrity": "sha512-qZKX4RnBzH2ugr8Lxa7x+0V6XD9Sb/ouARtiasEQCHB1EVU4NXtmHsDDrx1dO4ne5fc3J6EW05BP1Dl0z0iung==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/watchpack": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.2.tgz", + "integrity": "sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==", + "dev": true, + "license": "MIT", + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/weak-lru-cache": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz", + "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==", + "dev": true, + "license": "MIT", + "optional": true + }, + "node_modules/webpack": { + "version": "5.98.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.98.0.tgz", + "integrity": "sha512-UFynvx+gM44Gv9qFgj0acCQK2VE1CtdfwFdimkapco3hlPCJ/zeq73n2yVKimVbtm+TnApIugGhLJnkU6gjYXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.6", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.14.0", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.0", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-middleware": { + "version": "7.4.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-7.4.2.tgz", + "integrity": "sha512-xOO8n6eggxnwYpy1NlzUKpvrjfJTvae5/D6WOK0S2LSo7vjmo5gCM1DbLUmFqrMTJP+W/0YZNctm7jasWvLuBA==", + "dev": true, + "license": "MIT", + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^4.6.0", + "mime-types": "^2.1.31", + "on-finished": "^2.4.1", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-5.2.2.tgz", + "integrity": "sha512-QcQ72gh8a+7JO63TAx/6XZf/CWhgMzu5m0QirvPfGvptOusAxG12w2+aua1Jkjr7hzaWDnJ2n6JFeexMHI+Zjg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/bonjour": "^3.5.13", + "@types/connect-history-api-fallback": "^1.5.4", + "@types/express": "^4.17.21", + "@types/express-serve-static-core": "^4.17.21", + "@types/serve-index": "^1.9.4", + "@types/serve-static": "^1.15.5", + "@types/sockjs": "^0.3.36", + "@types/ws": "^8.5.10", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.2.1", + "chokidar": "^3.6.0", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^2.0.0", + "express": "^4.21.2", + "graceful-fs": "^4.2.6", + "http-proxy-middleware": "^2.0.9", + "ipaddr.js": "^2.1.0", + "launch-editor": "^2.6.1", + "open": "^10.0.3", + "p-retry": "^6.2.0", + "schema-utils": "^4.2.0", + "selfsigned": "^2.4.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.24", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^7.4.2", + "ws": "^8.18.0" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 18.12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "webpack": { + "optional": true + }, + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "dev": true, + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, + "engines": { + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/webpack-dev-server/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/webpack-dev-server/node_modules/http-proxy-middleware": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.9.tgz", + "integrity": "sha512-c1IyJYLYppU574+YI7R4QyX2ystMtVXZwIdzazUIPIJsHuWNd+mho2j+bKoHftndicGj9yh+xjd+l0yj7VeT1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/webpack-dev-server/node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.18.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.3.tgz", + "integrity": "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-6.0.1.tgz", + "integrity": "sha512-hXXvrjtx2PLYx4qruKl+kyRSLc52V+cCvMxRjmKwoA+CBbbF5GfIBtR6kCvl0fYGqTUPKB+1ktVmTHqMOzgCBg==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.1" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack-subresource-integrity": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz", + "integrity": "sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "typed-assert": "^1.0.8" + }, + "engines": { + "node": ">= 12" + }, + "peerDependencies": { + "html-webpack-plugin": ">= 5.0.0-beta.1 < 6", + "webpack": "^5.12.0" + }, + "peerDependenciesMeta": { + "html-webpack-plugin": { + "optional": true + } + } + }, + "node_modules/webpack/node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/wrap-ansi/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } + }, + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" + }, + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yocto-queue": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.1.tgz", + "integrity": "sha512-AyeEbWOu/TAXdxlV9wmGcR0+yh2j3vYPGOECcIj2S7MkrLyC7ne+oye2BKTItt0ii2PHk4cDy+95+LshzbXnGg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/yoctocolors-cjs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", + "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zone.js": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.15.1.tgz", + "integrity": "sha512-XE96n56IQpJM7NAoXswY3XRLcWFW83xe0BiAOeMD7K5k5xecOeul3Qcpx6GqEeeHNkW5DWL5zOyTbEfB4eti8w==", + "license": "MIT" + } + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package.json b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package.json new file mode 100644 index 0000000..7a63cc5 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/package.json @@ -0,0 +1,39 @@ +{ + "name": "angular-minimal", + "version": "0.0.0", + "scripts": { + "ng": "ng", + "start": "ng serve", + "build": "ng build", + "build:stats": "ng build --stats-json", + "watch": "ng build --watch --configuration development", + "test": "ng test" + }, + "private": true, + "dependencies": { + "@angular/animations": "^19.1.0", + "@angular/common": "^19.1.0", + "@angular/compiler": "^19.1.0", + "@angular/core": "^19.1.0", + "@angular/forms": "^19.1.0", + "@angular/platform-browser": "^19.1.0", + "@angular/platform-browser-dynamic": "^19.1.0", + "@angular/router": "^19.1.0", + "rxjs": "~7.8.0", + "tslib": "^2.3.0", + "zone.js": "~0.15.0" + }, + "devDependencies": { + "@angular-devkit/build-angular": "^19.1.5", + "@angular/cli": "^19.1.5", + "@angular/compiler-cli": "^19.1.0", + "@types/jasmine": "~5.1.0", + "jasmine-core": "~5.5.0", + "karma": "~6.4.0", + "karma-chrome-launcher": "~3.2.0", + "karma-coverage": "~2.2.0", + "karma-jasmine": "~5.1.0", + "karma-jasmine-html-reporter": "~2.1.0", + "typescript": "~5.7.2" + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/public/favicon.ico b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.css b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.css new file mode 100644 index 0000000..3d9a2b2 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.css @@ -0,0 +1,3 @@ +p { + color: red; +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.html b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.html new file mode 100644 index 0000000..5df63cd --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.html @@ -0,0 +1,360 @@ + + + + + + + + + + + +
+
+
+ +

Hello, {{ title }}

+

Congratulations! Your app is running. 🎉

+
+ +
+
+ @for ( + item of [ + { title: 'Explore the Docs', link: 'https://angular.dev' }, + { + title: 'Learn with Tutorials', + link: 'https://angular.dev/tutorials', + }, + { title: 'CLI Docs', link: 'https://angular.dev/tools/cli' }, + { + title: 'Angular Language Service', + link: 'https://angular.dev/tools/language-service', + }, + { + title: 'Angular DevTools', + link: 'https://angular.dev/tools/devtools', + }, + ]; + track item.title + ) { + + {{ item.title }} + + + + + } +
+ +
+
+
+ + + + + + + + + + diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.ts b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.component.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.config.ts b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.config.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.routes.ts b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/app.routes.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/route-1.component.ts b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/app/route-1.component.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/index.html b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/index.html new file mode 100644 index 0000000..d3e4261 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/index.html @@ -0,0 +1,13 @@ + + + + + AngularMinimal + + + + + + + + diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/main.ts b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/main.ts new file mode 100644 index 0000000..e69de29 diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/styles.css b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/styles.css new file mode 100644 index 0000000..4d595a2 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/src/styles.css @@ -0,0 +1,55 @@ +/* You can add global styles to this file, and also import other style files */ + +body { + margin: 0; + padding: 0; + font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', + 'Helvetica', 'Arial', sans-serif; + line-height: 1.6; + color: #333; +} + +* { + box-sizing: border-box; +} + +.container { + max-width: 1200px; + margin: 0 auto; + padding: 0 20px; +} + +.btn { + display: inline-block; + padding: 10px 20px; + background-color: #007bff; + color: white; + text-decoration: none; + border-radius: 4px; + border: none; + cursor: pointer; + font-size: 14px; + transition: background-color 0.3s ease; +} + +.btn:hover { + background-color: #0056b3; +} + +.card { + background: white; + border-radius: 8px; + box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); + padding: 20px; + margin-bottom: 20px; +} + +@media (max-width: 768px) { + .container { + padding: 0 10px; + } + + .card { + padding: 15px; + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.app.json b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.app.json new file mode 100644 index 0000000..8886e90 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.app.json @@ -0,0 +1,11 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/app", + "types": [] + }, + "files": ["src/main.ts"], + "include": ["src/**/*.d.ts"] +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.json b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.json new file mode 100644 index 0000000..5525117 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.json @@ -0,0 +1,27 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "compileOnSave": false, + "compilerOptions": { + "outDir": "./dist/out-tsc", + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "skipLibCheck": true, + "isolatedModules": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "moduleResolution": "bundler", + "importHelpers": true, + "target": "ES2022", + "module": "ES2022" + }, + "angularCompilerOptions": { + "enableI18nLegacyMessageIdFormat": false, + "strictInjectionParameters": true, + "strictInputAccessModifiers": true, + "strictTemplates": true + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.spec.json b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.spec.json new file mode 100644 index 0000000..e00e30e --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/angular-minimal/tsconfig.spec.json @@ -0,0 +1,10 @@ +/* To learn more about Typescript configuration file: https://www.typescriptlang.org/docs/handbook/tsconfig-json.html. */ +/* To learn more about Angular compiler options: https://angular.dev/reference/configs/angular-compiler-options. */ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "./out-tsc/spec", + "types": ["jasmine"] + }, + "include": ["src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/.sonda/sonda-report.json b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/.sonda/sonda-report.json new file mode 100644 index 0000000..3bfbb4f --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/.sonda/sonda-report.json @@ -0,0 +1,111 @@ +{ + "metadata": { + "version": "0.10.1", + "integration": "esbuild", + "sources": false, + "gzip": false, + "brotli": false + }, + "resources": [ + { + "kind": "asset", + "name": "dist/esbuild-sonda/bin.js", + "type": "script", + "uncompressed": 104, + "gzip": 0, + "brotli": 0 + }, + { + "kind": "asset", + "name": "dist/esbuild-sonda/chunks/chunk.js", + "type": "script", + "uncompressed": 2234, + "gzip": 0, + "brotli": 0 + }, + { + "kind": "asset", + "name": "dist/esbuild-sonda/index.js", + "type": "script", + "uncompressed": 63, + "gzip": 0, + "brotli": 0 + }, + { + "kind": "filesystem", + "name": "src/bin.ts", + "type": "script", + "format": "esm", + "uncompressed": 78 + }, + { + "kind": "filesystem", + "name": "src/index.ts", + "type": "script", + "format": "esm", + "uncompressed": 147 + }, + { + "kind": "filesystem", + "name": "src/lib/feature-1.ts", + "type": "script", + "format": "esm", + "uncompressed": 70 + }, + { + "kind": "filesystem", + "name": "src/lib/utils/format.ts", + "type": "script", + "format": "esm", + "uncompressed": 1035 + }, + { + "kind": "filesystem", + "name": "src/lib/utils/math.ts", + "type": "script", + "format": "esm", + "uncompressed": 1035 + } + ], + "connections": [ + { + "kind": "import", + "source": "src/lib/feature-1.ts", + "target": "src/lib/utils/format.ts", + "original": "./utils/format" + }, + { + "kind": "import", + "source": "src/index.ts", + "target": "src/lib/feature-1.ts", + "original": "./lib/feature-1" + }, + { + "kind": "import", + "source": "src/index.ts", + "target": "src/lib/utils/math.ts", + "original": "./lib/utils/math" + }, + { + "kind": "import", + "source": "src/bin.ts", + "target": "src/index.ts", + "original": "./index" + }, + { + "kind": "entrypoint", + "source": "src/index.ts", + "target": "dist/esbuild-sonda/index.js", + "original": null + }, + { + "kind": "entrypoint", + "source": "src/bin.ts", + "target": "dist/esbuild-sonda/bin.js", + "original": null + } + ], + "dependencies": [], + "issues": [], + "sourcemaps": [] +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/README.md b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/README.md new file mode 100644 index 0000000..6b523b7 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/README.md @@ -0,0 +1,47 @@ +# Node Minimal Fixture + +This is a minimal TypeScript project fixture for testing bundle analysis tools. + +## Build Tools + +This project supports multiple build tools: + +- **ESBuild**: `npm run build:esbuild` +- **Webpack**: `npm run build:webpack` +- **Rsbuild**: `npm run build:rsbuild` +- **Vite**: `npm run build:vite` ✨ (newly added) + +## Vite Configuration + +The Vite build configuration includes: + +- **Entry Points**: + - `index.html` → `main.js` (main application) + - `src/bin.ts` → `bin.js` (CLI entry point) +- **Output Directory**: `dist/vite/` +- **Static Assets**: Organized in `static/js/` and `static/[ext]/` +- **Source Maps**: Enabled for debugging +- **Code Splitting**: Automatic chunks in `static/js/async/` + +## Project Structure + +``` +src/ +├── index.ts # Main entry point +├── bin.ts # CLI entry point +├── styles.css # CSS styles +└── lib/ + ├── feature-1.ts # Feature module + ├── feature-2.ts # Lazy-loaded feature + └── utils/ # Utility modules +``` + +## Usage + +```bash +# Build with all tools +npm run build + +# Build with Vite only +npm run build:vite +``` diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild-sonda.script.cjs b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild-sonda.script.cjs new file mode 100644 index 0000000..75cb804 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild-sonda.script.cjs @@ -0,0 +1,64 @@ +const { build } = require('esbuild'); +const sonda = require('sonda/esbuild').default; +const fs = require('fs'); +const path = require('path'); + +const config = { + entryPoints: ['src/index.ts', 'src/bin.ts'], + bundle: true, + outdir: 'dist/esbuild-sonda', + entryNames: '[name]', + chunkNames: 'chunks/[name]', + metafile: true, + format: 'esm', + platform: 'node', + target: 'node18', + sourcemap: false, + minify: false, + splitting: true, + external: [], + treeShaking: true, + loader: { + '.css': 'css', + '.png': 'file', + '.jpg': 'file', + '.jpeg': 'file', + '.gif': 'file', + '.svg': 'file', + }, + logLevel: 'info', + plugins: [ + sonda({ + filename: 'sonda-report.json', + format: 'json', + open: false, + }), + ], +}; + +async function buildWithStats() { + try { + const result = await build(config); + + // Write metafile to stats.json (for compatibility) + if (result.metafile) { + const statsPath = path.join(config.outdir, 'stats.json'); + fs.writeFileSync(statsPath, JSON.stringify(result.metafile, null, 2)); + console.log(`Stats written to ${statsPath}`); + } + + console.log('Build completed successfully with Sonda plugin!'); + console.log('Sonda report: .sonda/sonda-report.json'); + return result; + } catch (error) { + console.error('Build failed:', error); + process.exit(1); + } +} + +// If this file is run directly, execute the build +if (require.main === module) { + buildWithStats(); +} + +module.exports = { config, buildWithStats }; diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild.script.cjs b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild.script.cjs new file mode 100644 index 0000000..132753a --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/esbuild.script.cjs @@ -0,0 +1,55 @@ +const { build } = require('esbuild'); +const fs = require('fs'); +const path = require('path'); + +const config = { + entryPoints: ['src/index.ts', 'src/bin.ts'], + bundle: true, + outdir: 'dist/esbuild', + entryNames: '[name]', // This ensures entry points keep their original names + chunkNames: 'chunks/[name]', // Put shared chunks in a subfolder without hash + metafile: true, + format: 'esm', + platform: 'node', + target: 'node18', + sourcemap: false, + minify: false, + splitting: true, // Keep splitting but with better chunk strategy + external: [], // Bundle all dependencies + treeShaking: true, // Enable tree shaking to ensure unique content per entry + loader: { + '.css': 'css', + '.png': 'file', + '.jpg': 'file', + '.jpeg': 'file', + '.gif': 'file', + '.svg': 'file', + }, + logLevel: 'info', +}; + +async function buildWithStats() { + try { + const result = await build(config); + + // Write metafile to stats.json + if (result.metafile) { + const statsPath = path.join(config.outdir, 'stats.json'); + fs.writeFileSync(statsPath, JSON.stringify(result.metafile, null, 2)); + console.log(`Stats written to ${statsPath}`); + } + + console.log('Build completed successfully!'); + return result; + } catch (error) { + console.error('Build failed:', error); + process.exit(1); + } +} + +// If this file is run directly, execute the build +if (require.main === module) { + buildWithStats(); +} + +module.exports = { config, buildWithStats }; diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/index.html b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/index.html new file mode 100644 index 0000000..09f81a0 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/index.html @@ -0,0 +1,12 @@ + + + + + + Node Minimal Fixture + + +
+ + + diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package-lock.json b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package-lock.json new file mode 100644 index 0000000..9ff3e72 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package-lock.json @@ -0,0 +1,3654 @@ +{ + "name": "node-minimal-fixture", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "node-minimal-fixture", + "version": "1.0.0", + "devDependencies": { + "@rsbuild/core": "^1.0.18", + "esbuild": "^0.24.1", + "rollup-plugin-webpack-stats": "^2.1.0", + "sonda": "^0.10.1", + "ts-loader": "^9.5.1", + "typescript": "^5.7.3", + "vite": "^5.4.0", + "webpack": "^5.95.0", + "webpack-cli": "^5.1.4" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@emnapi/core": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.4.tgz", + "integrity": "sha512-A9CnAbC6ARNMKcIcrQwq6HeHCjpcBZ5wSx4U01WXCqEKlrzB9F9315WDNHkrs2xbx7YjjSxbUYxuN6EQzpcY2g==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.0.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.4.tgz", + "integrity": "sha512-hHyapA4A3gPaDCNfiqyZUStTMqIkKRshqPIuDOXv1hcBnD4U3l8cP0T1HMCfGRxQ6V64TGCcoswChANyOAwbQg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.3.tgz", + "integrity": "sha512-8K5IFFsQqF9wQNJptGbS6FNKgUTsSRYnTqNCG1vPP8jFdjSv18n2mQfJpkt2Oibo9iBEzcDnDxNwKTzC7svlJw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.24.2.tgz", + "integrity": "sha512-thpVCb/rhxE/BnMLQ7GReQLLN8q9qbHmI55F4489/ByVg2aQaQ6kbcLb6FHkocZzQhxc4gx0sCk0tJkKBFzDhA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.24.2.tgz", + "integrity": "sha512-tmwl4hJkCfNHwFB3nBa8z1Uy3ypZpxqxfTQOcHX+xRByyYgunVbZ9MzUUfb0RxaHIMnbHagwAxuTL+tnNM+1/Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.24.2.tgz", + "integrity": "sha512-cNLgeqCqV8WxfcTIOeL4OAtSmL8JjcN6m09XIgro1Wi7cF4t/THaWEa7eL5CMoMBdjoHOTh/vwTO/o2TRXIyzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.24.2.tgz", + "integrity": "sha512-B6Q0YQDqMx9D7rvIcsXfmJfvUYLoP722bgfBlO5cGvNVb5V/+Y7nhBE3mHV9OpxBf4eAS2S68KZztiPaWq4XYw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.24.2.tgz", + "integrity": "sha512-kj3AnYWc+CekmZnS5IPu9D+HWtUI49hbnyqk0FLEJDbzCIQt7hg7ucF1SQAilhtYpIujfaHr6O0UHlzzSPdOeA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.24.2.tgz", + "integrity": "sha512-WeSrmwwHaPkNR5H3yYfowhZcbriGqooyu3zI/3GGpF8AyUdsrrP0X6KumITGA9WOyiJavnGZUwPGvxvwfWPHIA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.24.2.tgz", + "integrity": "sha512-UN8HXjtJ0k/Mj6a9+5u6+2eZ2ERD7Edt1Q9IZiB5UZAIdPnVKDoG7mdTVGhHJIeEml60JteamR3qhsr1r8gXvg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.24.2.tgz", + "integrity": "sha512-TvW7wE/89PYW+IevEJXZ5sF6gJRDY/14hyIGFXdIucxCsbRmLUcjseQu1SyTko+2idmCw94TgyaEZi9HUSOe3Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.24.2.tgz", + "integrity": "sha512-n0WRM/gWIdU29J57hJyUdIsk0WarGd6To0s+Y+LwvlC55wt+GT/OgkwoXCXvIue1i1sSNWblHEig00GBWiJgfA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.24.2.tgz", + "integrity": "sha512-7HnAD6074BW43YvvUmE/35Id9/NB7BeX5EoNkK9obndmZBUk8xmJJeU7DwmUeN7tkysslb2eSl6CTrYz6oEMQg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.24.2.tgz", + "integrity": "sha512-sfv0tGPQhcZOgTKO3oBE9xpHuUqguHvSo4jl+wjnKwFpapx+vUDcawbwPNuBIAYdRAvIDBfZVvXprIj3HA+Ugw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.24.2.tgz", + "integrity": "sha512-CN9AZr8kEndGooS35ntToZLTQLHEjtVB5n7dl8ZcTZMonJ7CCfStrYhrzF97eAecqVbVJ7APOEe18RPI4KLhwQ==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.24.2.tgz", + "integrity": "sha512-iMkk7qr/wl3exJATwkISxI7kTcmHKE+BlymIAbHO8xanq/TjHaaVThFF6ipWzPHryoFsesNQJPE/3wFJw4+huw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.24.2.tgz", + "integrity": "sha512-shsVrgCZ57Vr2L8mm39kO5PPIb+843FStGt7sGGoqiiWYconSxwTiuswC1VJZLCjNiMLAMh34jg4VSEQb+iEbw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.24.2.tgz", + "integrity": "sha512-4eSFWnU9Hhd68fW16GD0TINewo1L6dRrB+oLNNbYyMUAeOD2yCK5KXGK1GH4qD/kT+bTEXjsyTCiJGHPZ3eM9Q==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.24.2.tgz", + "integrity": "sha512-S0Bh0A53b0YHL2XEXC20bHLuGMOhFDO6GN4b3YjRLK//Ep3ql3erpNcPlEFed93hsQAjAQDNsvcK+hV90FubSw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.24.2.tgz", + "integrity": "sha512-8Qi4nQcCTbLnK9WoMjdC9NiTG6/E38RNICU6sUNqK0QFxCYgoARqVqxdFmWkdonVsvGqWhmm7MO0jyTqLqwj0Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.24.2.tgz", + "integrity": "sha512-wuLK/VztRRpMt9zyHSazyCVdCXlpHkKm34WUyinD2lzK07FAHTq0KQvZZlXikNWkDGoT6x3TD51jKQ7gMVpopw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.24.2.tgz", + "integrity": "sha512-VefFaQUc4FMmJuAxmIHgUmfNiLXY438XrL4GDNV1Y1H/RW3qow68xTwjZKfj/+Plp9NANmzbH5R40Meudu8mmw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.24.2.tgz", + "integrity": "sha512-YQbi46SBct6iKnszhSvdluqDmxCJA+Pu280Av9WICNwQmMxV7nLRHZfjQzwbPs3jeWnuAhE9Jy0NrnJ12Oz+0A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.24.2.tgz", + "integrity": "sha512-+iDS6zpNM6EnJyWv0bMGLWSWeXGN/HTaF/LXHXHwejGsVi+ooqDfMCCTerNFxEkM3wYVcExkeGXNqshc9iMaOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.24.2.tgz", + "integrity": "sha512-hTdsW27jcktEvpwNHJU4ZwWFGkz2zRJUz8pvddmXPtXDzVKTTINmlmga3ZzwcuMpUvLw7JkLy9QLKyGpD2Yxig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.24.2.tgz", + "integrity": "sha512-LihEQ2BBKVFLOC9ZItT9iFprsE9tqjDjnbulhHoFxYQtQfai7qfluVODIYxt1PgdoyQkz23+01rzwNwYfutxUQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.24.2.tgz", + "integrity": "sha512-q+iGUwfs8tncmFC9pcnD5IvRHAzmbwQ3GPS5/ceCyHdjXubwQWI12MKWSNSMYLJMq23/IUCvJMS76PDqXe1fxA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.24.2.tgz", + "integrity": "sha512-7VTgWzgMGvup6aSqDPLiW5zHaxYJGTO4OokMjIlrCtf+VpEL+cXKtCvg723iguPYI5oaUNdS+/V7OU2gvXVWEg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.3.12", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.12.tgz", + "integrity": "sha512-OuLGC46TjB5BbN1dH8JULVVZY4WTdkF7tV9Ys6wLL1rubZnCMstOhNHueU5bLCrnRuDhKPDM4g6sw4Bel5Gzqg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/remapping": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/remapping/-/remapping-2.3.5.tgz", + "integrity": "sha512-LI9u/+laYG4Ds1TDKSJW2YPrIlcVYOwi2fUC6xB43lueCjgxV4lffOCZCtYFiH6TNOX+tQKXx97T4IKHbhyHEQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.10.tgz", + "integrity": "sha512-0pPkgz9dY+bijgistcTTJ5mR+ocqRXLuhXHYdzoMmmoJ2C9S46RCm2GMUbatPEUK9Yjy26IrAy8D/M00lLkv+Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.4.tgz", + "integrity": "sha512-VT2+G1VQs/9oz078bLrYbecdZKs912zQlkelYpuf+SXF+QvZDYJlbx/LSx+meSAwdDFnF8FVXW92AVjjkVmgFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.29", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.29.tgz", + "integrity": "sha512-uw6guiW/gcAGPDhLmd77/6lW8QLeiV5RUTsAX46Db6oLhGaVj4lhnPwb184s1bkc8kdVg/+h988dro8GRDpmYQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@module-federation/error-codes": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@module-federation/error-codes/-/error-codes-0.15.0.tgz", + "integrity": "sha512-CFJSF+XKwTcy0PFZ2l/fSUpR4z247+Uwzp1sXVkdIfJ/ATsnqf0Q01f51qqSEA6MYdQi6FKos9FIcu3dCpQNdg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@module-federation/runtime": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime/-/runtime-0.15.0.tgz", + "integrity": "sha512-dTPsCNum9Bhu3yPOcrPYq0YnM9eCMMMNB1wuiqf1+sFbQlNApF0vfZxooqz3ln0/MpgE0jerVvFsLVGfqvC9Ug==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.15.0", + "@module-federation/runtime-core": "0.15.0", + "@module-federation/sdk": "0.15.0" + } + }, + "node_modules/@module-federation/runtime-core": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-core/-/runtime-core-0.15.0.tgz", + "integrity": "sha512-RYzI61fRDrhyhaEOXH3AgIGlHiot0wPFXu7F43cr+ZnTi+VlSYWLdlZ4NBuT9uV6JSmH54/c+tEZm5SXgKR2sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/error-codes": "0.15.0", + "@module-federation/sdk": "0.15.0" + } + }, + "node_modules/@module-federation/runtime-tools": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@module-federation/runtime-tools/-/runtime-tools-0.15.0.tgz", + "integrity": "sha512-kzFn3ObUeBp5vaEtN1WMxhTYBuYEErxugu1RzFUERD21X3BZ+b4cWwdFJuBDlsmVjctIg/QSOoZoPXRKAO0foA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.15.0", + "@module-federation/webpack-bundler-runtime": "0.15.0" + } + }, + "node_modules/@module-federation/sdk": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@module-federation/sdk/-/sdk-0.15.0.tgz", + "integrity": "sha512-PWiYbGcJrKUD6JZiEPihrXhV3bgXdll4bV7rU+opV7tHaun+Z0CdcawjZ82Xnpb8MCPGmqHwa1MPFeUs66zksw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@module-federation/webpack-bundler-runtime": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@module-federation/webpack-bundler-runtime/-/webpack-bundler-runtime-0.15.0.tgz", + "integrity": "sha512-i+3wu2Ljh2TmuUpsnjwZVupOVqV50jP0ndA8PSP4gwMKlgdGeaZ4VH5KkHAXGr2eiYUxYLMrJXz1+eILJqeGDg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime": "0.15.0", + "@module-federation/sdk": "0.15.0" + } + }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.45.0.tgz", + "integrity": "sha512-2o/FgACbji4tW1dzXOqAV15Eu7DdgbKsF2QKcxfG4xbh5iwU7yr5RRP5/U+0asQliSYv5M4o7BevlGIoSL0LXg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.45.0.tgz", + "integrity": "sha512-PSZ0SvMOjEAxwZeTx32eI/j5xSYtDCRxGu5k9zvzoY77xUNssZM+WV6HYBLROpY5CkXsbQjvz40fBb7WPwDqtQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.45.0.tgz", + "integrity": "sha512-BA4yPIPssPB2aRAWzmqzQ3y2/KotkLyZukVB7j3psK/U3nVJdceo6qr9pLM2xN6iRP/wKfxEbOb1yrlZH6sYZg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.45.0.tgz", + "integrity": "sha512-Pr2o0lvTwsiG4HCr43Zy9xXrHspyMvsvEw4FwKYqhli4FuLE5FjcZzuQ4cfPe0iUFCvSQG6lACI0xj74FDZKRA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.45.0.tgz", + "integrity": "sha512-lYE8LkE5h4a/+6VnnLiL14zWMPnx6wNbDG23GcYFpRW1V9hYWHAw9lBZ6ZUIrOaoK7NliF1sdwYGiVmziUF4vA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.45.0.tgz", + "integrity": "sha512-PVQWZK9sbzpvqC9Q0GlehNNSVHR+4m7+wET+7FgSnKG3ci5nAMgGmr9mGBXzAuE5SvguCKJ6mHL6vq1JaJ/gvw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.45.0.tgz", + "integrity": "sha512-hLrmRl53prCcD+YXTfNvXd776HTxNh8wPAMllusQ+amcQmtgo3V5i/nkhPN6FakW+QVLoUUr2AsbtIRPFU3xIA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.45.0.tgz", + "integrity": "sha512-XBKGSYcrkdiRRjl+8XvrUR3AosXU0NvF7VuqMsm7s5nRy+nt58ZMB19Jdp1RdqewLcaYnpk8zeVs/4MlLZEJxw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.45.0.tgz", + "integrity": "sha512-fRvZZPUiBz7NztBE/2QnCS5AtqLVhXmUOPj9IHlfGEXkapgImf4W9+FSkL8cWqoAjozyUzqFmSc4zh2ooaeF6g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.45.0.tgz", + "integrity": "sha512-Btv2WRZOcUGi8XU80XwIvzTg4U6+l6D0V6sZTrZx214nrwxw5nAi8hysaXj/mctyClWgesyuxbeLylCBNauimg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loongarch64-gnu": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.45.0.tgz", + "integrity": "sha512-Li0emNnwtUZdLwHjQPBxn4VWztcrw/h7mgLyHiEI5Z0MhpeFGlzaiBHpSNVOMB/xucjXTTcO+dhv469Djr16KA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.45.0.tgz", + "integrity": "sha512-sB8+pfkYx2kvpDCfd63d5ScYT0Fz1LO6jIb2zLZvmK9ob2D8DeVqrmBDE0iDK8KlBVmsTNzrjr3G1xV4eUZhSw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.45.0.tgz", + "integrity": "sha512-5GQ6PFhh7E6jQm70p1aW05G2cap5zMOvO0se5JMecHeAdj5ZhWEHbJ4hiKpfi1nnnEdTauDXxPgXae/mqjow9w==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.45.0.tgz", + "integrity": "sha512-N/euLsBd1rekWcuduakTo/dJw6U6sBP3eUq+RXM9RNfPuWTvG2w/WObDkIvJ2KChy6oxZmOSC08Ak2OJA0UiAA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.45.0.tgz", + "integrity": "sha512-2l9sA7d7QdikL0xQwNMO3xURBUNEWyHVHfAsHsUdq+E/pgLTUcCE+gih5PCdmyHmfTDeXUWVhqL0WZzg0nua3g==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.45.0.tgz", + "integrity": "sha512-XZdD3fEEQcwG2KrJDdEQu7NrHonPxxaV0/w2HpvINBdcqebz1aL+0vM2WFJq4DeiAVT6F5SUQas65HY5JDqoPw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.45.0.tgz", + "integrity": "sha512-7ayfgvtmmWgKWBkCGg5+xTQ0r5V1owVm67zTrsEY1008L5ro7mCyGYORomARt/OquB9KY7LpxVBZes+oSniAAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.45.0.tgz", + "integrity": "sha512-B+IJgcBnE2bm93jEW5kHisqvPITs4ddLOROAcOc/diBgrEiQJJ6Qcjby75rFSmH5eMGrqJryUgJDhrfj942apQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.45.0.tgz", + "integrity": "sha512-+CXwwG66g0/FpWOnP/v1HnrGVSOygK/osUbu3wPRy8ECXjoYKjRAyfxYpDQOfghC5qPJYLPH0oN4MCOjwgdMug==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.45.0.tgz", + "integrity": "sha512-SRf1cytG7wqcHVLrBc9VtPK4pU5wxiB/lNIkNmW2ApKXIg+RpqwHfsaEK+e7eH4A1BpI6BX/aBWXxZCIrJg3uA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rsbuild/core": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rsbuild/core/-/core-1.4.6.tgz", + "integrity": "sha512-Z5e7ExKGmLv/wvBQEgSE2bPpR9movvq0jnfXjtYzrLzJFGsKFwL/5KShgdr6hUtVGGLoCCCHHHaTBL6BPcNvZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@rspack/core": "1.4.6", + "@rspack/lite-tapable": "~1.0.1", + "@swc/helpers": "^0.5.17", + "core-js": "~3.44.0", + "jiti": "^2.4.2" + }, + "bin": { + "rsbuild": "bin/rsbuild.js" + }, + "engines": { + "node": ">=16.10.0" + } + }, + "node_modules/@rspack/binding": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding/-/binding-1.4.6.tgz", + "integrity": "sha512-rRc6sbKWxhomxxJeqi4QS3S/2T6pKf4JwC/VHXs7KXw7lHXHa3yxPynmn3xHstL0H6VLaM5xQj87Wh7lQYRAPg==", + "dev": true, + "license": "MIT", + "optionalDependencies": { + "@rspack/binding-darwin-arm64": "1.4.6", + "@rspack/binding-darwin-x64": "1.4.6", + "@rspack/binding-linux-arm64-gnu": "1.4.6", + "@rspack/binding-linux-arm64-musl": "1.4.6", + "@rspack/binding-linux-x64-gnu": "1.4.6", + "@rspack/binding-linux-x64-musl": "1.4.6", + "@rspack/binding-wasm32-wasi": "1.4.6", + "@rspack/binding-win32-arm64-msvc": "1.4.6", + "@rspack/binding-win32-ia32-msvc": "1.4.6", + "@rspack/binding-win32-x64-msvc": "1.4.6" + } + }, + "node_modules/@rspack/binding-darwin-arm64": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-arm64/-/binding-darwin-arm64-1.4.6.tgz", + "integrity": "sha512-K37H8e58eY7zBHGeMVtT7m0Z5XvlNQX7YDuaxlbiA4hZxqeRoS5BMX/YOcDiGdNbSuqv+iG5GSckJ99YUI67Cw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-darwin-x64": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-darwin-x64/-/binding-darwin-x64-1.4.6.tgz", + "integrity": "sha512-3p5u9q/Q9MMVe+5XFJ/WiFrzNrrxUjJFR19kB1k/KMcf8ox982xWjnfJuBkET/k7Hn0EZL7L06ym447uIfAVAg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rspack/binding-linux-arm64-gnu": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.4.6.tgz", + "integrity": "sha512-ZrrCn5b037ImZfZ3MShJrRw4d5M3Tq2rFJupr+SGMg7GTl2T6xEmo3ER/evHlT6e0ETi6tRWPxC9A1125jbSQA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-arm64-musl": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.4.6.tgz", + "integrity": "sha512-0a30oR6ZmZrqmsOHQYrbZPCxAgnqAiqlbFozdhHs+Yu2bS7SDiLpdjMg0PHwLZT2+siiMWsLodFZlXRJE54oAQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-gnu": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.4.6.tgz", + "integrity": "sha512-u6pq1aq7bX+NABVDDTOzH64KMj1KJn8fUWO+FaX7Kr7PBjhmxNRs4OaWZjbXEY6COhMYEJZ04h4DhY+lRzcKjA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-linux-x64-musl": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-linux-x64-musl/-/binding-linux-x64-musl-1.4.6.tgz", + "integrity": "sha512-rjP/1dWKB828kzd4/QpDYNVasUAKDj0OeRJGh5L/RluSH3pEqhxm5FwvndpmFDv6m3iPekZ4IO26UrpGJmE9fw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rspack/binding-wasm32-wasi": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-wasm32-wasi/-/binding-wasm32-wasi-1.4.6.tgz", + "integrity": "sha512-5M0g7TaWgCFQJr4NKYW2bTLbQJuAQIgZL7WmiDwotgscBJDQWJVBayFEsnM6PYX1Inmu6RNhQ44BKIYwwoSyYw==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@napi-rs/wasm-runtime": "^0.2.11" + } + }, + "node_modules/@rspack/binding-win32-arm64-msvc": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.4.6.tgz", + "integrity": "sha512-thPCdbh4O+uEAJ8AvXBWZIOW0ZopJAN3CX2zlprso8Cnhi4wDseTtrIxFQh7cTo6pR3xSZAIv/zHd+MMF8TImA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-ia32-msvc": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-1.4.6.tgz", + "integrity": "sha512-KQmm6c/ZfJKQ/TpzbY6J0pDvUB9kwTXzp+xl2FhGq2RXid8uyDS8ZqbeJA6LDxgttsmp4PRVJjMdLVYjZenfLw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/binding-win32-x64-msvc": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.4.6.tgz", + "integrity": "sha512-WRRhCsJ+xcOmvzo/r/b2UTejPLnDEbaD/te1yQwHe97sUaFGr3u1Njk6lVYRTV6mEvUopEChb8yAq/S4dvaGLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rspack/core": { + "version": "1.4.6", + "resolved": "https://registry.npmjs.org/@rspack/core/-/core-1.4.6.tgz", + "integrity": "sha512-/OpJLv7dPEE7x/qCXGecRm9suNxz5w0Dheq2sh0TjTCUHodtMET3T+FlRWznBAlZeNuHLECDp0DWhchgS8BWuA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@module-federation/runtime-tools": "0.15.0", + "@rspack/binding": "1.4.6", + "@rspack/lite-tapable": "1.0.1" + }, + "engines": { + "node": ">=16.0.0" + }, + "peerDependencies": { + "@swc/helpers": ">=0.5.1" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@rspack/lite-tapable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rspack/lite-tapable/-/lite-tapable-1.0.1.tgz", + "integrity": "sha512-VynGOEsVw2s8TAlLf/uESfrgfrq2+rcXB1muPJYBWbsm1Oa6r5qVQhjA5ggM6z/coYPrsVMgovl3Ff7Q7OCp1w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16.0.0" + } + }, + "node_modules/@swc/helpers": { + "version": "0.5.17", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.17.tgz", + "integrity": "sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "tslib": "^2.8.0" + } + }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.0.tgz", + "integrity": "sha512-VyyPYFlOMNylG45GoAe0xDoLwWuowvf92F9kySqzYh8vmYm7D2u4iUJKa1tOUpS70Ku13ASrOkS4ScXFsTaCNQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@types/eslint": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-9.6.1.tgz", + "integrity": "sha512-FXx2pKgId/WyYo2jXw63kk7/+TY7u7AziEJxJAnSFzHlqTAS3Ync6SvgYAN/k4/PQpnnVuzoMuVnByKK2qp0ag==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.7", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.7.tgz", + "integrity": "sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/json-schema": { + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/node": { + "version": "24.0.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-24.0.13.tgz", + "integrity": "sha512-Qm9OYVOFHFYg3wJoTSrz80hoec5Lia/dPp84do3X7dZvLikQvM1YpmvTBEdIr/e+U8HTkFjLHLnl78K/qjf+jQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.8.0" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz", + "integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/helper-numbers": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz", + "integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz", + "integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz", + "integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz", + "integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.13.2", + "@webassemblyjs/helper-api-error": "1.13.2", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz", + "integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz", + "integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/wasm-gen": "1.14.1" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz", + "integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz", + "integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.13.2", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz", + "integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz", + "integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/helper-wasm-section": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-opt": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1", + "@webassemblyjs/wast-printer": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz", + "integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz", + "integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-buffer": "1.14.1", + "@webassemblyjs/wasm-gen": "1.14.1", + "@webassemblyjs/wasm-parser": "1.14.1" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz", + "integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@webassemblyjs/helper-api-error": "1.13.2", + "@webassemblyjs/helper-wasm-bytecode": "1.13.2", + "@webassemblyjs/ieee754": "1.13.2", + "@webassemblyjs/leb128": "1.13.2", + "@webassemblyjs/utf8": "1.13.2" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz", + "integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@webassemblyjs/ast": "1.14.1", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-2.1.1.tgz", + "integrity": "sha512-wy0mglZpDSiSS0XHrVR+BAdId2+yxPSoJW8fsna3ZpYSlufjvxnP4YbKTCBZnNIcGN4r6ZPXV55X4mYExOfLmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-2.0.2.tgz", + "integrity": "sha512-zLHQdI/Qs1UyT5UBdWNqsARasIA+AaF8t+4u2aS2nEpBQh2mWIVb8qAklq0eUENnC5mOItrIB4LiS9xMtph18A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-2.0.5.tgz", + "integrity": "sha512-lqaoKnRYBdo1UgDX8uF24AfGMifWK19TxPmM5FHc2vAGxrJ/qtyUyFBWoY1tISZdelsQ5fBcOusifo5o5wSJxQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "webpack": "5.x.x", + "webpack-cli": "5.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true, + "license": "BSD-3-Clause" + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true, + "license": "Apache-2.0" + }, + "node_modules/acorn": { + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", + "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-phases": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.3.tgz", + "integrity": "sha512-jtKLnfoOzm28PazuQ4dVBcE9Jeo6ha1GAJvq3N0LlNOszmTfx+wSycBehn+FN0RnyeR77IBxN/qVYMw0Rlj0Xw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "acorn": "^8.14.0" + } + }, + "node_modules/ajv": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/braces": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "dev": true, + "license": "MIT", + "dependencies": { + "fill-range": "^7.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.25.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz", + "integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "caniuse-lite": "^1.0.30001726", + "electron-to-chromium": "^1.5.173", + "node-releases": "^2.0.19", + "update-browserslist-db": "^1.1.3" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/bundle-name": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz", + "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001727", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz", + "integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "CC-BY-4.0" + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz", + "integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0" + } + }, + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/core-js": { + "version": "3.44.0", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.44.0.tgz", + "integrity": "sha512-aFCtd4l6GvAXwVEh3XbbVqJGHDJt0OZRa+5ePGx3LLwi12WfexqQxcsohb2wgsa/92xtl19Hd66G/L+TaAxDMw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz", + "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==", + "dev": true, + "license": "MIT", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/default-browser": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.4.0.tgz", + "integrity": "sha512-XDuvSq38Hr1MdN47EDvYtx3U0MTqpCEn+F6ft8z2vYDzMrvQhVp0ui9oQdqW3MvK3vqUETglt1tVGgjLuJ5izg==", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/default-browser-id": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.1.tgz", + "integrity": "sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/define-lazy-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz", + "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.5.182", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz", + "integrity": "sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==", + "dev": true, + "license": "ISC" + }, + "node_modules/enhanced-resolve": { + "version": "5.18.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.2.tgz", + "integrity": "sha512-6Jw4sE1maoRJo3q8MsSIn2onJFbLTOjY9hlx4DZXmOKvLRd1Ok2kXmAGXaafL2+ijsJZ1ClYbl/pmqr9+k4iUQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/envinfo": { + "version": "7.14.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.14.0.tgz", + "integrity": "sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg==", + "dev": true, + "license": "MIT", + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.24.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", + "integrity": "sha512-+9egpBW8I3CD5XPe0n6BfT5fxLzxrlDzqydF3aviG+9ni1lDC/OvMHcxqEFV0+LANZG5R1bFMWfUrjVsdwxJvA==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.24.2", + "@esbuild/android-arm": "0.24.2", + "@esbuild/android-arm64": "0.24.2", + "@esbuild/android-x64": "0.24.2", + "@esbuild/darwin-arm64": "0.24.2", + "@esbuild/darwin-x64": "0.24.2", + "@esbuild/freebsd-arm64": "0.24.2", + "@esbuild/freebsd-x64": "0.24.2", + "@esbuild/linux-arm": "0.24.2", + "@esbuild/linux-arm64": "0.24.2", + "@esbuild/linux-ia32": "0.24.2", + "@esbuild/linux-loong64": "0.24.2", + "@esbuild/linux-mips64el": "0.24.2", + "@esbuild/linux-ppc64": "0.24.2", + "@esbuild/linux-riscv64": "0.24.2", + "@esbuild/linux-s390x": "0.24.2", + "@esbuild/linux-x64": "0.24.2", + "@esbuild/netbsd-arm64": "0.24.2", + "@esbuild/netbsd-x64": "0.24.2", + "@esbuild/openbsd-arm64": "0.24.2", + "@esbuild/openbsd-x64": "0.24.2", + "@esbuild/sunos-x64": "0.24.2", + "@esbuild/win32-arm64": "0.24.2", + "@esbuild/win32-ia32": "0.24.2", + "@esbuild/win32-x64": "0.24.2" + } + }, + "node_modules/escalade": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", + "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-scope": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", + "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/esrecurse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", + "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esrecurse/node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=4.0" + } + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true, + "license": "MIT" + }, + "node_modules/fast-uri": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", + "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", + "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.9.1" + } + }, + "node_modules/fill-range": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true, + "license": "BSD-3-Clause", + "bin": { + "flat": "cli.js" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true, + "license": "BSD-2-Clause" + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true, + "license": "ISC" + }, + "node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/import-local": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.2.0.tgz", + "integrity": "sha512-2SPlun1JUPWoM6t3F0dw0FkCF/jWY8kttcY4f599GLTSjh2OCuuhdTkJQsEcZzBqbXZGKMK2OqW1oZsjtf/gQA==", + "dev": true, + "license": "MIT", + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/interpret": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", + "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/is-core-module": { + "version": "2.16.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", + "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-docker": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz", + "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-inside-container": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz", + "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "license": "MIT", + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-wsl": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", + "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "dev": true, + "license": "ISC" + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/jiti": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz", + "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==", + "dev": true, + "license": "MIT", + "bin": { + "jiti": "lib/jiti-cli.mjs" + } + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/loader-runner": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", + "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" + }, + "node_modules/micromatch": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", + "dev": true, + "license": "MIT", + "dependencies": { + "braces": "^3.0.3", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true, + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", + "integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==", + "dev": true, + "license": "MIT" + }, + "node_modules/open": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/open/-/open-10.2.0.tgz", + "integrity": "sha512-YgBpdJHPyQ2UE5x+hlSXcnejzAvD0b22U2OuAP+8OnlJT+PjWPxtgmGqKKc+RgTM63U9gN0YzrYc71R2WT/hTA==", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true, + "license": "MIT" + }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss": { + "version": "8.5.6", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.6.tgz", + "integrity": "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "safe-buffer": "^5.1.0" + } + }, + "node_modules/rechoir": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve": "^1.20.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/resolve": { + "version": "1.22.10", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", + "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-core-module": "^2.16.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/rollup": { + "version": "4.45.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.45.0.tgz", + "integrity": "sha512-WLjEcJRIo7i3WDDgOIJqVI2d+lAC3EwvOGy+Xfq6hs+GQuAA4Di/H72xmXkOhrIWFg2PFYSKZYfH0f4vfKXN4A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.45.0", + "@rollup/rollup-android-arm64": "4.45.0", + "@rollup/rollup-darwin-arm64": "4.45.0", + "@rollup/rollup-darwin-x64": "4.45.0", + "@rollup/rollup-freebsd-arm64": "4.45.0", + "@rollup/rollup-freebsd-x64": "4.45.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.45.0", + "@rollup/rollup-linux-arm-musleabihf": "4.45.0", + "@rollup/rollup-linux-arm64-gnu": "4.45.0", + "@rollup/rollup-linux-arm64-musl": "4.45.0", + "@rollup/rollup-linux-loongarch64-gnu": "4.45.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.45.0", + "@rollup/rollup-linux-riscv64-gnu": "4.45.0", + "@rollup/rollup-linux-riscv64-musl": "4.45.0", + "@rollup/rollup-linux-s390x-gnu": "4.45.0", + "@rollup/rollup-linux-x64-gnu": "4.45.0", + "@rollup/rollup-linux-x64-musl": "4.45.0", + "@rollup/rollup-win32-arm64-msvc": "4.45.0", + "@rollup/rollup-win32-ia32-msvc": "4.45.0", + "@rollup/rollup-win32-x64-msvc": "4.45.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/rollup-plugin-stats": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-stats/-/rollup-plugin-stats-1.4.0.tgz", + "integrity": "sha512-qbwuMysGHqNrW0XBO3dU8qM7SdVYmMuaABp6SG1wFDClFVdUo8Umtk/LIDFCocNxDf6Tvtu7tXF/FsMy8NZCew==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "rollup": "^3.0.0 || ^4.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/rollup-plugin-webpack-stats": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-webpack-stats/-/rollup-plugin-webpack-stats-2.1.0.tgz", + "integrity": "sha512-7cxCelMRPkqZvjQa4NuHSkdJ6nshLDuDYyPAky8YOjcaz+qEocg0DRcJoSd4r2mKSupz0uZpoav5vqpDm7bSxg==", + "dev": true, + "license": "MIT", + "dependencies": { + "rollup-plugin-stats": "1.4.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "rollup": "^3.0.0 || ^4.0.0", + "vite": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "rollup": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/run-applescript": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", + "integrity": "sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/schema-utils": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.2.tgz", + "integrity": "sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.9.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.1.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/semver": { + "version": "7.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", + "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.2.tgz", + "integrity": "sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "license": "MIT", + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/sonda": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/sonda/-/sonda-0.10.1.tgz", + "integrity": "sha512-nXlQEVsw7833XADV94MXW9EKwLxn4S1U7oSUEgKCQeU4dt0CwYvEFcyRjhjM0Ae2taxsJ9HnFrtw8Eb40/rX4w==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/remapping": "^2.3.5", + "open": "^10.2.0" + }, + "bin": { + "sonda-angular": "bin/sonda-angular.js" + }, + "engines": { + "node": ">=20.19 || >=22.12" + } + }, + "node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 8" + } + }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.2.tgz", + "integrity": "sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/terser": { + "version": "5.43.1", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.43.1.tgz", + "integrity": "sha512-+6erLbBm0+LROX2sPXlUYx/ux5PyE9K/a92Wrt6oA+WDAoFTdpHE5tCYCI5PNzq2y8df4rA+QgHLJuR4jNymsg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.14.0", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.14.tgz", + "integrity": "sha512-vkZjpUjb6OMS7dhV+tILUW6BhpDR7P2L/aQSAv+Uwk+m8KATX9EccViHTJR2qDtACKPIYndLGCyl3FMo+r2LMw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.25", + "jest-worker": "^27.4.5", + "schema-utils": "^4.3.0", + "serialize-javascript": "^6.0.2", + "terser": "^5.31.1" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/ts-loader": { + "version": "9.5.2", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.5.2.tgz", + "integrity": "sha512-Qo4piXvOTWcMGIgRiuFa6nHNm+54HbYaZCKqc9eeZCLRy3XqafQgwX2F7mofrbJG3g7EEb+lkiR+z2Lic2s3Zw==", + "dev": true, + "license": "MIT", + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4", + "source-map": "^0.7.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD" + }, + "node_modules/typescript": { + "version": "5.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", + "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/undici-types": { + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz", + "integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==", + "dev": true, + "license": "MIT" + }, + "node_modules/update-browserslist-db": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz", + "integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.2.0", + "picocolors": "^1.1.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/vite": { + "version": "5.4.19", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.19.tgz", + "integrity": "sha512-qO3aKv3HoQC8QKiNSTuUM1l9o/XX3+c+VTgLHbJWHZGeTPVAg2XwazI9UWzoxjIJCGCV2zU60uqMzjeLZuULqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite/node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/vite/node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/watchpack": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz", + "integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==", + "dev": true, + "license": "MIT", + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack": { + "version": "5.100.1", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.100.1.tgz", + "integrity": "sha512-YJB/ESPUe2Locd0NKXmw72Dx8fZQk1gTzI6rc9TAT4+Sypbnhl8jd8RywB1bDsDF9Dy1RUR7gn3q/ZJTd0OZZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint-scope": "^3.7.7", + "@types/estree": "^1.0.8", + "@types/json-schema": "^7.0.15", + "@webassemblyjs/ast": "^1.14.1", + "@webassemblyjs/wasm-edit": "^1.14.1", + "@webassemblyjs/wasm-parser": "^1.14.1", + "acorn": "^8.15.0", + "acorn-import-phases": "^1.0.3", + "browserslist": "^4.24.0", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.17.2", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.11", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^4.3.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.11", + "watchpack": "^2.4.1", + "webpack-sources": "^3.3.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-cli": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-5.1.4.tgz", + "integrity": "sha512-pIDJHIEI9LR0yxHXQ+Qh95k2EvXpWzZ5l+d+jIo+RdSm9MiHfzazIxwwni/p7+x4eJZuvG1AJwgC4TNQ7NRgsg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^2.1.1", + "@webpack-cli/info": "^2.0.2", + "@webpack-cli/serve": "^2.0.5", + "colorette": "^2.0.14", + "commander": "^10.0.1", + "cross-spawn": "^7.0.3", + "envinfo": "^7.7.3", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^3.1.1", + "rechoir": "^0.8.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=14.15.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz", + "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "node_modules/webpack-merge": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", + "integrity": "sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA==", + "dev": true, + "license": "MIT", + "dependencies": { + "clone-deep": "^4.0.1", + "flat": "^5.0.2", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.3.3.tgz", + "integrity": "sha512-yd1RBzSGanHkitROoPFd6qsrxt+oFhg/129YzheDGqeustzX0vTZJZsSsQjVQC4yzBQ56K55XU8gaNCtIzOnTg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "license": "ISC", + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/wildcard": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.1.tgz", + "integrity": "sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/wsl-utils": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/wsl-utils/-/wsl-utils-0.1.0.tgz", + "integrity": "sha512-h3Fbisa2nKGPxCpm89Hk33lBLsnaGBvctQopaBSOW/uIs6FTe1ATyAnKFJrzVs9vpGdsTe73WF3V4lIsk4Gacw==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package.json b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package.json new file mode 100644 index 0000000..3f4feea --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/package.json @@ -0,0 +1,23 @@ +{ + "name": "node-minimal-fixture", + "version": "1.0.0", + "private": true, + "scripts": { + "build": "npm run build:esbuild && npm run build:webpack && npm run build:rsbuild && npm run build:vite", + "build:esbuild": "node esbuild.script.cjs", + "build:webpack": "node webpack.script.cjs", + "build:rsbuild": "node rsbuild.script.cjs", + "build:vite": "node vite.script.cjs" + }, + "devDependencies": { + "@rsbuild/core": "^1.0.18", + "esbuild": "^0.24.1", + "rollup-plugin-webpack-stats": "^2.1.0", + "sonda": "^0.10.1", + "ts-loader": "^9.5.1", + "typescript": "^5.7.3", + "vite": "^5.4.0", + "webpack": "^5.95.0", + "webpack-cli": "^5.1.4" + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/rsbuild.script.cjs b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/rsbuild.script.cjs new file mode 100644 index 0000000..81e3c17 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/rsbuild.script.cjs @@ -0,0 +1,37 @@ +const { createRsbuild, loadConfig } = require('@rsbuild/core'); +const fs = require('fs'); +const path = require('path'); + +async function build() { + try { + // Load the config from rsbuild.config.ts + const { content } = await loadConfig(); + + const rsbuild = await createRsbuild({ + rsbuildConfig: content, + }); + + const { stats } = await rsbuild.build(); + + // Ensure output directory exists + const outputDir = 'dist/rsbuild'; + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write stats.json + fs.writeFileSync( + path.join(outputDir, 'stats.json'), + JSON.stringify(stats.toJson(), null, 2), + ); + console.log(`Stats written to ${outputDir}/stats.json`); + + console.log('Build completed successfully!'); + process.exit(0); + } catch (error) { + console.error('Build failed:', error); + process.exit(1); + } +} + +build(); diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/bin.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/bin.ts new file mode 100644 index 0000000..10330a8 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/bin.ts @@ -0,0 +1,6 @@ +#!/usr/bin/env node +import { main } from './index'; + +(() => { + main(); +})(); diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/index.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/index.ts new file mode 100644 index 0000000..1dcca1a --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/index.ts @@ -0,0 +1,6 @@ +import { feature1 } from './lib/feature-1'; +import { math } from './lib/utils/math'; + +export function main(): string { + return math + feature1; +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-1.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-1.ts new file mode 100644 index 0000000..731729b --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-1.ts @@ -0,0 +1,3 @@ +import { form } from './utils/format'; + +export const feature1 = form; diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-2.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-2.ts new file mode 100644 index 0000000..f02a1b5 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/feature-2.ts @@ -0,0 +1,5 @@ +import { minimatch } from 'minimatch'; + +export function chart(): string { + return minimatch('src/lib/feature-2.ts', '**/*.ts') ? 'Match' : 'No Match'; +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/styles/theme.css b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/styles/theme.css new file mode 100644 index 0000000..183e190 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/styles/theme.css @@ -0,0 +1,9 @@ +/* +`------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------`; +*/ +:root { + --primary: #007acc; +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/format.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/format.ts new file mode 100644 index 0000000..f30a8b1 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/format.ts @@ -0,0 +1,4 @@ +export const form = `------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------`; diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/math.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/math.ts new file mode 100644 index 0000000..499bcac --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/lib/utils/math.ts @@ -0,0 +1,4 @@ +export const math = `------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ +------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------`; diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/styles.css b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/styles.css new file mode 100644 index 0000000..a0ae60b --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/src/styles.css @@ -0,0 +1,5 @@ +@import './theme.css'; + +.bg { + background: #f0f0f0; +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/tsconfig.json b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/tsconfig.json new file mode 100644 index 0000000..08472c6 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "ESNext", + "moduleResolution": "node", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.config.ts b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.config.ts new file mode 100644 index 0000000..7caa191 --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.config.ts @@ -0,0 +1,32 @@ +import path from 'path'; +import webpackStatsPlugin from 'rollup-plugin-webpack-stats'; +import { defineConfig } from 'vite'; + +export default defineConfig({ + build: { + outDir: './dist/vite', + rollupOptions: { + input: { + main: path.resolve(__dirname, 'index.html'), + bin: path.resolve(__dirname, 'src/bin.ts'), + }, + output: { + assetFileNames: 'assets/[name].[hash][extname]', + chunkFileNames: 'assets/[name].[hash].js', + entryFileNames: 'static/js/[name].js', + }, + }, + sourcemap: true, + minify: false, + }, + plugins: [ + webpackStatsPlugin({ + fileName: 'stats.json', + }), + ], + resolve: { + alias: { + '@': path.resolve(__dirname, 'src'), + }, + }, +}); diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.script.cjs b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.script.cjs new file mode 100644 index 0000000..10f79ca --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/vite.script.cjs @@ -0,0 +1,35 @@ +const { execSync } = require('child_process'); +const fs = require('fs'); +const path = require('path'); + +/** + * Builds the project using Vite. Creates consistent output structure for bundle analysis. + */ +function build() { + console.log('Building with Vite...'); + + try { + // Clean the dist directory + const distDir = path.join(__dirname, 'dist', 'vite'); + if (fs.existsSync(distDir)) { + fs.rmSync(distDir, { recursive: true }); + } + + // Run Vite build + execSync('npx vite build', { + stdio: 'inherit', + cwd: __dirname, + }); + + console.log('Vite build completed successfully!'); + } catch (error) { + console.error('Vite build failed:', error.message); + process.exit(1); + } +} + +if (require.main === module) { + build(); +} + +module.exports = { build }; diff --git a/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/webpack.script.cjs b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/webpack.script.cjs new file mode 100644 index 0000000..7e6923f --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/node-minimal/webpack.script.cjs @@ -0,0 +1,29 @@ +const webpack = require('webpack'); +const fs = require('fs'); +const path = require('path'); +const config = require('./webpack.config.js'); + +const compiler = webpack(config); + +compiler.run((err, stats) => { + if (err) { + console.error(err); + process.exit(1); + } + + // Ensure output directory exists + const outputDir = 'dist/webpack'; + if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); + } + + // Write stats.json + fs.writeFileSync( + path.join(outputDir, 'stats.json'), + JSON.stringify(stats.toJson(), null, 2), + ); + console.log(`Stats written to ${outputDir}/stats.json`); + + console.log('Build completed successfully!'); + compiler.close(() => process.exit(0)); +}); diff --git a/packages/plugin-bundle-stats/mocks/fixtures/stats/angular-minimal.stats.json b/packages/plugin-bundle-stats/mocks/fixtures/stats/angular-minimal.stats.json new file mode 100644 index 0000000..374375c --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/stats/angular-minimal.stats.json @@ -0,0 +1,77 @@ +{ + "inputs": { + "src/main.ts": { + "bytes": 0, + "imports": [] + }, + "node_modules/zone.js/fesm2015/zone.js": { + "bytes": 135236, + "imports": [] + }, + "angular:polyfills:angular:polyfills": { + "bytes": 17, + "imports": [ + { + "path": "node_modules/zone.js/fesm2015/zone.js", + "kind": "import-statement", + "original": "zone.js" + } + ], + "format": "esm" + }, + "src/styles.css": { + "bytes": 903, + "imports": [] + }, + "angular:styles/global:styles": { + "bytes": 25, + "imports": [ + { + "path": "src/styles.css", + "kind": "import-rule", + "original": "src/styles.css" + } + ] + } + }, + "outputs": { + "main-L6P5G76P.js": { + "imports": [], + "exports": [], + "entryPoint": "src/main.ts", + "inputs": { + "src/main.ts": { + "bytesInOutput": 0 + } + }, + "bytes": 0 + }, + "polyfills-B6TNHZQ6.js": { + "imports": [], + "exports": [], + "entryPoint": "angular:polyfills:angular:polyfills", + "inputs": { + "node_modules/zone.js/fesm2015/zone.js": { + "bytesInOutput": 34578 + }, + "angular:polyfills:angular:polyfills": { + "bytesInOutput": 0 + } + }, + "bytes": 34579 + }, + "styles-EGIV7BA7.css": { + "imports": [], + "entryPoint": "angular:styles/global:styles", + "inputs": { + "src/styles.css": { + "bytesInOutput": 630 + }, + "angular:styles/global:styles": { + "bytesInOutput": 0 + } + }, + "bytes": 631 + } + } +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json b/packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json new file mode 100644 index 0000000..3bfbb4f --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json @@ -0,0 +1,111 @@ +{ + "metadata": { + "version": "0.10.1", + "integration": "esbuild", + "sources": false, + "gzip": false, + "brotli": false + }, + "resources": [ + { + "kind": "asset", + "name": "dist/esbuild-sonda/bin.js", + "type": "script", + "uncompressed": 104, + "gzip": 0, + "brotli": 0 + }, + { + "kind": "asset", + "name": "dist/esbuild-sonda/chunks/chunk.js", + "type": "script", + "uncompressed": 2234, + "gzip": 0, + "brotli": 0 + }, + { + "kind": "asset", + "name": "dist/esbuild-sonda/index.js", + "type": "script", + "uncompressed": 63, + "gzip": 0, + "brotli": 0 + }, + { + "kind": "filesystem", + "name": "src/bin.ts", + "type": "script", + "format": "esm", + "uncompressed": 78 + }, + { + "kind": "filesystem", + "name": "src/index.ts", + "type": "script", + "format": "esm", + "uncompressed": 147 + }, + { + "kind": "filesystem", + "name": "src/lib/feature-1.ts", + "type": "script", + "format": "esm", + "uncompressed": 70 + }, + { + "kind": "filesystem", + "name": "src/lib/utils/format.ts", + "type": "script", + "format": "esm", + "uncompressed": 1035 + }, + { + "kind": "filesystem", + "name": "src/lib/utils/math.ts", + "type": "script", + "format": "esm", + "uncompressed": 1035 + } + ], + "connections": [ + { + "kind": "import", + "source": "src/lib/feature-1.ts", + "target": "src/lib/utils/format.ts", + "original": "./utils/format" + }, + { + "kind": "import", + "source": "src/index.ts", + "target": "src/lib/feature-1.ts", + "original": "./lib/feature-1" + }, + { + "kind": "import", + "source": "src/index.ts", + "target": "src/lib/utils/math.ts", + "original": "./lib/utils/math" + }, + { + "kind": "import", + "source": "src/bin.ts", + "target": "src/index.ts", + "original": "./index" + }, + { + "kind": "entrypoint", + "source": "src/index.ts", + "target": "dist/esbuild-sonda/index.js", + "original": null + }, + { + "kind": "entrypoint", + "source": "src/bin.ts", + "target": "dist/esbuild-sonda/bin.js", + "original": null + } + ], + "dependencies": [], + "issues": [], + "sourcemaps": [] +} diff --git a/packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json b/packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json new file mode 100644 index 0000000..699386d --- /dev/null +++ b/packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json @@ -0,0 +1,315 @@ +{ + "inputs": { + "../../../../../node_modules/balanced-match/index.js": { + "bytes": 1219, + "imports": [], + "format": "cjs" + }, + "../../../../../node_modules/brace-expansion/index.js": { + "bytes": 4992, + "imports": [ + { + "path": "../../../../../node_modules/balanced-match/index.js", + "kind": "require-call", + "original": "balanced-match" + } + ], + "format": "cjs" + }, + "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js": { + "bytes": 336, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js": { + "bytes": 5631, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/unescape.js": { + "bytes": 847, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/ast.js": { + "bytes": 22588, + "imports": [ + { + "path": "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js", + "kind": "import-statement", + "original": "./brace-expressions.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + } + ], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/escape.js": { + "bytes": 848, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/index.js": { + "bytes": 39098, + "imports": [ + { + "path": "../../../../../node_modules/brace-expansion/index.js", + "kind": "import-statement", + "original": "brace-expansion" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js", + "kind": "import-statement", + "original": "./assert-valid-pattern.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/ast.js", + "kind": "import-statement", + "original": "./ast.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/escape.js", + "kind": "import-statement", + "original": "./escape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/ast.js", + "kind": "import-statement", + "original": "./ast.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/escape.js", + "kind": "import-statement", + "original": "./escape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + } + ], + "format": "esm" + }, + "../shared-source/node_modules/my-lib/index.js": { + "bytes": 94, + "imports": [], + "format": "esm" + }, + "../shared-source/src/lib/utils/format.ts": { + "bytes": 590, + "imports": [ + { + "path": "../../../../../node_modules/minimatch/dist/esm/index.js", + "kind": "import-statement", + "original": "minimatch" + }, + { + "path": "../shared-source/node_modules/my-lib/index.js", + "kind": "import-statement", + "original": "my-lib" + } + ], + "format": "esm" + }, + "../shared-source/src/lib/feature-1.ts": { + "bytes": 489, + "imports": [ + { + "path": "../shared-source/src/lib/utils/format.ts", + "kind": "import-statement", + "original": "./utils/format" + } + ], + "format": "esm" + }, + "../shared-source/src/lib/utils/math.ts": { + "bytes": 240, + "imports": [], + "format": "esm" + }, + "../shared-source/src/lib/utils/string.ts": { + "bytes": 300, + "imports": [], + "format": "esm" + }, + "../shared-source/src/lib/feature-2.ts": { + "bytes": 53, + "imports": [], + "format": "esm" + }, + "../shared-source/src/index.ts": { + "bytes": 673, + "imports": [ + { + "path": "../shared-source/src/lib/feature-1.ts", + "kind": "import-statement", + "original": "./lib/feature-1" + }, + { + "path": "../shared-source/src/lib/utils/math.ts", + "kind": "import-statement", + "original": "./lib/utils/math" + }, + { + "path": "../shared-source/src/lib/utils/string.ts", + "kind": "import-statement", + "original": "./lib/utils/string" + }, + { + "path": "../shared-source/src/lib/feature-2.ts", + "kind": "dynamic-import", + "original": "./lib/feature-2" + } + ], + "format": "esm" + }, + "../shared-source/src/bin.ts": { + "bytes": 633, + "imports": [ + { + "path": "../shared-source/src/lib/feature-1.ts", + "kind": "import-statement", + "original": "./lib/feature-1" + }, + { + "path": "../shared-source/src/lib/utils/math.ts", + "kind": "import-statement", + "original": "./lib/utils/math" + }, + { + "path": "../shared-source/src/lib/utils/string.ts", + "kind": "import-statement", + "original": "./lib/utils/string" + } + ], + "format": "esm" + } + }, + "outputs": { + "dist/index.js": { + "imports": [ + { + "path": "dist/chunks/chunk-PKX4VJZC.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/feature-2-SERQNJVR.js", + "kind": "dynamic-import" + } + ], + "exports": ["default", "indexOnlyFunction"], + "entryPoint": "../shared-source/src/index.ts", + "inputs": { + "../shared-source/src/index.ts": { + "bytesInOutput": 386 + } + }, + "bytes": 595 + }, + "dist/bin.js": { + "imports": [ + { + "path": "dist/chunks/chunk-PKX4VJZC.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": [], + "entryPoint": "../shared-source/src/bin.ts", + "inputs": { + "../shared-source/src/bin.ts": { + "bytesInOutput": 373 + } + }, + "bytes": 549 + }, + "dist/chunks/chunk-PKX4VJZC.js": { + "imports": [ + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": ["calculate", "externalFunction", "greet"], + "inputs": { + "../../../../../node_modules/balanced-match/index.js": { + "bytesInOutput": 1543 + }, + "../../../../../node_modules/brace-expansion/index.js": { + "bytesInOutput": 4784 + }, + "../../../../../node_modules/minimatch/dist/esm/index.js": { + "bytesInOutput": 23960 + }, + "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js": { + "bytesInOutput": 261 + }, + "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js": { + "bytesInOutput": 3163 + }, + "../../../../../node_modules/minimatch/dist/esm/unescape.js": { + "bytesInOutput": 210 + }, + "../../../../../node_modules/minimatch/dist/esm/ast.js": { + "bytesInOutput": 15518 + }, + "../../../../../node_modules/minimatch/dist/esm/escape.js": { + "bytesInOutput": 165 + }, + "../shared-source/node_modules/my-lib/index.js": { + "bytesInOutput": 93 + }, + "../shared-source/src/lib/utils/format.ts": { + "bytesInOutput": 269 + }, + "../shared-source/src/lib/feature-1.ts": { + "bytesInOutput": 269 + }, + "../shared-source/src/lib/utils/math.ts": { + "bytesInOutput": 145 + }, + "../shared-source/src/lib/utils/string.ts": { + "bytesInOutput": 54 + } + }, + "bytes": 51348 + }, + "dist/chunks/feature-2-SERQNJVR.js": { + "imports": [ + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": ["chart"], + "entryPoint": "../shared-source/src/lib/feature-2.ts", + "inputs": { + "../shared-source/src/lib/feature-2.ts": { + "bytesInOutput": 38 + } + }, + "bytes": 130 + }, + "dist/chunks/chunk-SK6HMZ5B.js": { + "imports": [], + "exports": ["__commonJS", "__toESM"], + "inputs": {}, + "bytes": 1357 + } + } +} diff --git a/packages/plugin-bundle-stats/package.json b/packages/plugin-bundle-stats/package.json new file mode 100644 index 0000000..9cc2c6d --- /dev/null +++ b/packages/plugin-bundle-stats/package.json @@ -0,0 +1,37 @@ +{ + "name": "@code-pushup/bundle-stats-plugin", + "version": "0.69.2", + "license": "MIT", + "description": "Code PushUp plugin for incrementally adopting strict compilation flags in TypeScript projects", + "homepage": "https://github.com/code-pushup/cli/tree/main/packages/plugin-bundle-stats#readme", + "bugs": { + "url": "https://github.com/code-pushup/cli/issues?q=is%3Aissue%20state%3Aopen%20type%3ABug%20label%3A\"🧩%20bundle-stats-plugin\"" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/code-pushup/cli.git", + "directory": "packages/plugin-bundle-stats" + }, + "keywords": [ + "CLI", + "Code PushUp", + "plugin", + "typescript" + ], + "publishConfig": { + "access": "public" + }, + "type": "module", + "dependencies": { + "@code-pushup/models": "0.92.1", + "@code-pushup/utils": "0.92.1", + "minimatch": "9.0.3", + "tslib": "^2.3.0" + }, + "peerDependencies": {}, + "scripts": {}, + "devDependencies": { + "@angular/cli": "^20.0.3", + "typescript": "5.4" + } +} diff --git a/packages/plugin-bundle-stats/project.json b/packages/plugin-bundle-stats/project.json new file mode 100644 index 0000000..00b90a9 --- /dev/null +++ b/packages/plugin-bundle-stats/project.json @@ -0,0 +1,79 @@ +{ + "name": "plugin-bundle-stats", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "packages/plugin-bundle-stats/src", + "projectType": "library", + "targets": { + "code-pushup-minimal-esbuild": { + "executor": "nx:run-commands", + "options": { + "command": "node packages/cli/src/index.ts --no-progress --verbose", + "args": "collect --config packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts", + "env": { + "NODE_OPTIONS": "--import tsx", + "TSX_TSCONFIG_PATH": "tsconfig.base.json" + } + } + }, + "code-pushup-minimal-angular": { + "executor": "nx:run-commands", + "options": { + "command": "node packages/cli/src/index.ts --no-progress --verbose", + "args": "collect --config packages/plugin-bundle-stats/code-pushup.minimal-angular.config.ts", + "env": { + "NODE_OPTIONS": "--import tsx", + "TSX_TSCONFIG_PATH": "tsconfig.base.json" + } + } + }, + "code-pushup-minimal-webpack": { + "executor": "nx:run-commands", + "options": { + "command": "node packages/cli/src/index.ts --no-progress --verbose", + "args": "collect --config packages/plugin-bundle-stats/code-pushup.minimal-webpack.config.ts", + "env": { + "NODE_OPTIONS": "--import tsx", + "TSX_TSCONFIG_PATH": "tsconfig.base.json" + } + } + }, + "code-pushup-minimal-rsbuild": { + "executor": "nx:run-commands", + "options": { + "command": "node packages/cli/src/index.ts --no-progress --verbose", + "args": "collect --config packages/plugin-bundle-stats/code-pushup.minimal-rsbuild.config.ts", + "env": { + "NODE_OPTIONS": "--import tsx", + "TSX_TSCONFIG_PATH": "tsconfig.base.json" + } + } + }, + "code-pushup-minimal-vite": { + "executor": "nx:run-commands", + "options": { + "command": "node packages/cli/src/index.ts --no-progress --verbose", + "args": "collect --config packages/plugin-bundle-stats/code-pushup.minimal-vite.config.ts", + "env": { + "NODE_OPTIONS": "--import tsx", + "TSX_TSCONFIG_PATH": "tsconfig.base.json" + } + } + }, + "code-pushup-minimal-esbuild-sonda": { + "executor": "nx:run-commands", + "options": { + "command": "node packages/cli/src/index.ts --no-progress --verbose", + "args": "collect --config packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts", + "env": { + "NODE_OPTIONS": "--import tsx", + "TSX_TSCONFIG_PATH": "tsconfig.base.json" + } + } + }, + "build": {}, + "lint": {}, + "unit-test": {}, + "int-test": {} + }, + "tags": ["scope:plugin", "type:feature", "publishable"] +} diff --git a/packages/plugin-bundle-stats/src/index.ts b/packages/plugin-bundle-stats/src/index.ts new file mode 100644 index 0000000..69a856a --- /dev/null +++ b/packages/plugin-bundle-stats/src/index.ts @@ -0,0 +1,15 @@ +import { bundleStatsPlugin } from './lib/bundle-stats-plugin.js'; + +export type { + BundleStatsAuditOptions as BundleStatsOptions, + PluginOptions, +} from './lib/types.js'; +export type { + GroupingRule, + PatternList, + BundleStatsConfig, +} from './lib/runner/types.js'; +export type { BlacklistEntry } from './lib/runner/audits/scoring.js'; + +export default bundleStatsPlugin; +export { DEFAULT_GROUPING, DEFAULT_PRUNING } from './lib/constants.js'; diff --git a/packages/plugin-bundle-stats/src/lib/__snapshots__/esbuild.stats.json b/packages/plugin-bundle-stats/src/lib/__snapshots__/esbuild.stats.json new file mode 100644 index 0000000..5fdd8e5 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/__snapshots__/esbuild.stats.json @@ -0,0 +1,279 @@ +{ + "inputs": { + "src/lib/utils/format.ts": { + "bytes": 418, + "imports": [], + "format": "esm" + }, + "src/lib/feature-1.ts": { + "bytes": 417, + "imports": [ + { + "path": "src/lib/utils/format.ts", + "kind": "import-statement", + "original": "./utils/format" + } + ], + "format": "esm" + }, + "src/lib/utils/math.ts": { + "bytes": 240, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/balanced-match/index.js": { + "bytes": 1219, + "imports": [], + "format": "cjs" + }, + "../../../../../node_modules/brace-expansion/index.js": { + "bytes": 4992, + "imports": [ + { + "path": "../../../../../node_modules/balanced-match/index.js", + "kind": "require-call", + "original": "balanced-match" + } + ], + "format": "cjs" + }, + "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js": { + "bytes": 336, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js": { + "bytes": 5631, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/unescape.js": { + "bytes": 847, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/ast.js": { + "bytes": 22588, + "imports": [ + { + "path": "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js", + "kind": "import-statement", + "original": "./brace-expressions.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + } + ], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/escape.js": { + "bytes": 848, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/index.js": { + "bytes": 39098, + "imports": [ + { + "path": "../../../../../node_modules/brace-expansion/index.js", + "kind": "import-statement", + "original": "brace-expansion" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js", + "kind": "import-statement", + "original": "./assert-valid-pattern.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/ast.js", + "kind": "import-statement", + "original": "./ast.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/escape.js", + "kind": "import-statement", + "original": "./escape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/ast.js", + "kind": "import-statement", + "original": "./ast.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/escape.js", + "kind": "import-statement", + "original": "./escape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + } + ], + "format": "esm" + }, + "src/lib/feature-2.ts": { + "bytes": 154, + "imports": [ + { + "path": "../../../../../node_modules/minimatch/dist/esm/index.js", + "kind": "import-statement", + "original": "minimatch" + } + ], + "format": "esm" + }, + "src/index.ts": { + "bytes": 473, + "imports": [ + { + "path": "src/lib/feature-1.ts", + "kind": "import-statement", + "original": "./lib/feature-1" + }, + { + "path": "src/lib/utils/math.ts", + "kind": "import-statement", + "original": "./lib/utils/math" + }, + { + "path": "src/lib/feature-2.ts", + "kind": "dynamic-import", + "original": "./lib/feature-2" + } + ], + "format": "esm" + }, + "src/bin.ts": { + "bytes": 532, + "imports": [ + { + "path": "src/lib/feature-1.ts", + "kind": "import-statement", + "original": "./lib/feature-1" + }, + { + "path": "src/lib/utils/math.ts", + "kind": "import-statement", + "original": "./lib/utils/math" + } + ], + "format": "esm" + } + }, + "outputs": { + "dist/index.js": { + "imports": [ + { + "path": "dist/chunks/chunk-WIJM4GGD.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/feature-2-JRMQOICX.js", + "kind": "dynamic-import" + } + ], + "exports": ["default", "indexOnlyFunction"], + "entryPoint": "src/index.ts", + "inputs": { + "src/index.ts": { + "bytesInOutput": 350 + } + }, + "bytes": 533 + }, + "dist/bin.js": { + "imports": [ + { + "path": "dist/chunks/chunk-WIJM4GGD.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": [], + "entryPoint": "src/bin.ts", + "inputs": { + "src/bin.ts": { + "bytesInOutput": 366 + } + }, + "bytes": 516 + }, + "dist/chunks/chunk-WIJM4GGD.js": { + "imports": [], + "exports": ["calculate", "externalFunction"], + "inputs": { + "src/lib/utils/format.ts": { + "bytesInOutput": 269 + }, + "src/lib/feature-1.ts": { + "bytesInOutput": 269 + }, + "src/lib/utils/math.ts": { + "bytesInOutput": 145 + } + }, + "bytes": 806 + }, + "dist/chunks/feature-2-JRMQOICX.js": { + "imports": [ + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": ["chart"], + "entryPoint": "src/lib/feature-2.ts", + "inputs": { + "../../../../../node_modules/balanced-match/index.js": { + "bytesInOutput": 1541 + }, + "../../../../../node_modules/brace-expansion/index.js": { + "bytesInOutput": 4782 + }, + "../../../../../node_modules/minimatch/dist/esm/index.js": { + "bytesInOutput": 23960 + }, + "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js": { + "bytesInOutput": 261 + }, + "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js": { + "bytesInOutput": 3163 + }, + "../../../../../node_modules/minimatch/dist/esm/unescape.js": { + "bytesInOutput": 210 + }, + "../../../../../node_modules/minimatch/dist/esm/ast.js": { + "bytesInOutput": 15518 + }, + "../../../../../node_modules/minimatch/dist/esm/escape.js": { + "bytesInOutput": 165 + }, + "src/lib/feature-2.ts": { + "bytesInOutput": 99 + } + }, + "bytes": 50369 + }, + "dist/chunks/chunk-SK6HMZ5B.js": { + "imports": [], + "exports": ["__commonJS", "__toESM"], + "inputs": {}, + "bytes": 1357 + } + } +} diff --git a/packages/plugin-bundle-stats/src/lib/__snapshots__/rsbuild.stats.json b/packages/plugin-bundle-stats/src/lib/__snapshots__/rsbuild.stats.json new file mode 100644 index 0000000..04cb3b0 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/__snapshots__/rsbuild.stats.json @@ -0,0 +1,1994 @@ +{ + "name": "web", + "hash": "49eb6aa370487a4a", + "version": "5.75.0", + "rspackVersion": "1.3.12", + "time": 141, + "builtAt": 1751220448060, + "publicPath": "/", + "outputPath": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/dist", + "assetsByChunkName": { + "index": ["static/css/index.css", "static/js/bundle.js"] + }, + "assets": [ + { + "type": "asset", + "name": "static/js/bundle.js", + "size": 13743, + "emitted": true, + "info": { + "javascriptModule": false, + "chunkhash": [], + "contenthash": [], + "fullhash": [], + "related": { "sourceMap": ["static/js/bundle.js.map"] }, + "isOverSizeLimit": false + }, + "cached": false, + "chunkNames": ["index"], + "chunkIdHints": [], + "auxiliaryChunkNames": [], + "auxiliaryChunkIdHints": [], + "related": [], + "filteredRelated": 0, + "chunks": ["1"], + "auxiliaryChunks": [], + "isOverSizeLimit": false + }, + { + "type": "asset", + "name": "static/js/async/bundle.js", + "size": 394, + "emitted": true, + "info": { + "javascriptModule": false, + "chunkhash": [], + "contenthash": [], + "fullhash": [], + "related": { "sourceMap": ["static/js/async/bundle.js.map"] }, + "isOverSizeLimit": false + }, + "cached": false, + "chunkNames": [], + "chunkIdHints": [], + "auxiliaryChunkNames": [], + "auxiliaryChunkIdHints": [], + "related": [], + "filteredRelated": 0, + "chunks": ["0"], + "auxiliaryChunks": [], + "isOverSizeLimit": false + }, + { + "type": "asset", + "name": "index.html", + "size": 295, + "emitted": true, + "info": { + "chunkhash": [], + "contenthash": [], + "fullhash": [], + "related": {}, + "isOverSizeLimit": false + }, + "cached": false, + "chunkNames": [], + "chunkIdHints": [], + "auxiliaryChunkNames": [], + "auxiliaryChunkIdHints": [], + "related": [], + "filteredRelated": 0, + "chunks": [], + "auxiliaryChunks": [], + "isOverSizeLimit": false + }, + { + "type": "asset", + "name": "static/css/index.css", + "size": 65, + "emitted": true, + "info": { + "chunkhash": [], + "contenthash": [], + "fullhash": [], + "related": {}, + "isOverSizeLimit": false + }, + "cached": false, + "chunkNames": ["index"], + "chunkIdHints": [], + "auxiliaryChunkNames": [], + "auxiliaryChunkIdHints": [], + "related": [], + "filteredRelated": 0, + "chunks": ["1"], + "auxiliaryChunks": [], + "isOverSizeLimit": false + } + ], + "chunks": [ + { + "type": "chunk", + "rendered": true, + "initial": false, + "entry": false, + "size": 63, + "sizes": { "javascript": 63 }, + "names": [], + "idHints": [], + "runtime": ["index"], + "files": ["static/js/async/bundle.js"], + "auxiliaryFiles": ["static/js/async/bundle.js.map"], + "hash": "0451cfbe592c2998", + "childrenByOrder": {}, + "id": "0", + "siblings": [], + "parents": ["1"], + "children": [], + "modules": [ + { + "type": "module", + "moduleType": "javascript/auto", + "size": 63, + "sizes": { "javascript": 63 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/dynamic.js", + "name": "./src/dynamic.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/dynamic.js", + "index": 9, + "preOrderIndex": 9, + "index2": 9, + "postOrderIndex": 9, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 7, + "issuerId": 0, + "chunks": ["0"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "import()", + "userRequest": "./dynamic.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["loadDynamic"], + "optimizationBailout": [], + "depth": 1 + } + ], + "origins": [ + { + "module": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "loc": "7:28-50", + "request": "./dynamic.js", + "moduleId": 0 + } + ] + }, + { + "type": "chunk", + "rendered": true, + "initial": true, + "entry": true, + "size": 4628, + "sizes": { "css/mini-extract": 63, "javascript": 4565, "runtime": 5968 }, + "names": ["index"], + "idHints": [], + "runtime": ["index"], + "files": ["static/css/index.css", "static/js/bundle.js"], + "auxiliaryFiles": ["static/js/bundle.js.map"], + "hash": "7754789dbec8b7cd", + "childrenByOrder": {}, + "id": "1", + "siblings": [], + "parents": [], + "children": ["0"], + "modules": [ + { + "type": "module", + "moduleType": "javascript/auto", + "size": 56, + "sizes": { "javascript": 56 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "name": "./src/cjs.cjs", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "index": 6, + "preOrderIndex": 6, + "index2": 5, + "postOrderIndex": 5, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 4, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "moduleName": "./src/cjs.cjs", + "type": "cjs self exports reference", + "userRequest": "self", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "resolvedModule": "./src/cjs.cjs", + "active": true, + "moduleId": 4, + "resolvedModuleId": 4 + }, + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "cjs require", + "userRequest": "./cjs.cjs", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "4:26-38", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 399, + "sizes": { "javascript": 399 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "index": 0, + "preOrderIndex": 0, + "index2": 8, + "postOrderIndex": 8, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "type": "entry", + "userRequest": "./src/index.js", + "active": true, + "moduleId": null, + "resolvedModuleId": null + } + ], + "usedExports": null, + "providedExports": ["default"], + "optimizationBailout": [], + "depth": 0 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 74, + "sizes": { "javascript": 74 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "name": "./src/resolver.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "index": 7, + "preOrderIndex": 7, + "index2": 7, + "postOrderIndex": 7, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 5, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "require.resolve", + "userRequest": "./resolver.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["resolveModule"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 69, + "sizes": { "javascript": 69 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/side-effects.js", + "name": "./src/side-effects.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/side-effects.js", + "index": 1, + "preOrderIndex": 1, + "index2": 0, + "postOrderIndex": 0, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 1, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import", + "userRequest": "./side-effects.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "1:0-27", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["sideEffect"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 52, + "sizes": { "javascript": 52 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "index": 2, + "preOrderIndex": 2, + "index2": 3, + "postOrderIndex": 3, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 2, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import", + "userRequest": "./styles.css", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "2:0-22", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 3755, + "sizes": { "javascript": 3755 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/utils.js", + "name": "./src/utils.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/utils.js", + "index": 5, + "preOrderIndex": 5, + "index2": 4, + "postOrderIndex": 4, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 3, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import", + "userRequest": "./utils.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "3:0-35", + "moduleId": 0, + "resolvedModuleId": 0 + }, + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import specifier", + "userRequest": "./utils.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "8:22-27", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["BIG_DATA", "add", "greet", "multiply"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 160, + "sizes": { "javascript": 160 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src|sync", + "name": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src|sync", + "index": 8, + "preOrderIndex": 8, + "index2": 6, + "postOrderIndex": 6, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "issuerName": "./src/resolver.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + }, + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "name": "./src/resolver.js", + "id": 5 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 6, + "issuerId": 5, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "moduleName": "./src/resolver.js", + "type": "require.resolve context", + "userRequest": ".", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "resolvedModule": "./src/resolver.js", + "active": true, + "moduleId": 5, + "resolvedModuleId": 5 + } + ], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": 2 + }, + { + "type": "module", + "moduleType": "css/mini-extract", + "size": 31, + "sizes": { "css/mini-extract": 31 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "css|commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css|0|||}", + "name": "css commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "index": 4, + "preOrderIndex": 4, + "index2": 2, + "postOrderIndex": 2, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + }, + { + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css", + "id": 2 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "issuerId": 2, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css", + "type": "extract css", + "userRequest": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModuleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css", + "active": true, + "moduleId": 2, + "resolvedModuleId": 2 + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [], + "depth": 2 + }, + { + "type": "module", + "moduleType": "css/mini-extract", + "size": 32, + "sizes": { "css/mini-extract": 32 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "css|commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css|0|||}", + "name": "css commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "index": 3, + "preOrderIndex": 3, + "index2": 1, + "postOrderIndex": 1, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + }, + { + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css", + "id": 2 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "issuerId": 2, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css", + "type": "extract css", + "userRequest": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "resolvedModuleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css", + "active": true, + "moduleId": 2, + "resolvedModuleId": 2 + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [], + "depth": 2 + } + ], + "origins": [ + { + "module": "", + "moduleIdentifier": "", + "moduleName": "", + "loc": "index", + "request": "./src/index.js" + } + ] + } + ], + "modules": [ + { + "type": "module", + "moduleType": "javascript/auto", + "size": 399, + "sizes": { "javascript": 399 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "index": 0, + "preOrderIndex": 0, + "index2": 8, + "postOrderIndex": 8, + "cacheable": true, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "type": "entry", + "userRequest": "./src/index.js", + "active": true, + "moduleId": null, + "resolvedModuleId": null + } + ], + "usedExports": null, + "providedExports": ["default"], + "optimizationBailout": [], + "depth": 0 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 69, + "sizes": { "javascript": 69 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/side-effects.js", + "name": "./src/side-effects.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/side-effects.js", + "index": 1, + "preOrderIndex": 1, + "index2": 0, + "postOrderIndex": 0, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 1, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import", + "userRequest": "./side-effects.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "1:0-27", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["sideEffect"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 52, + "sizes": { "javascript": 52 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "index": 2, + "preOrderIndex": 2, + "index2": 3, + "postOrderIndex": 3, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 2, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import", + "userRequest": "./styles.css", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "2:0-22", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 3755, + "sizes": { "javascript": 3755 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/utils.js", + "name": "./src/utils.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/utils.js", + "index": 5, + "preOrderIndex": 5, + "index2": 4, + "postOrderIndex": 4, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 3, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import", + "userRequest": "./utils.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "3:0-35", + "moduleId": 0, + "resolvedModuleId": 0 + }, + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "esm import specifier", + "userRequest": "./utils.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "8:22-27", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["BIG_DATA", "add", "greet", "multiply"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 56, + "sizes": { "javascript": 56 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "name": "./src/cjs.cjs", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "index": 6, + "preOrderIndex": 6, + "index2": 5, + "postOrderIndex": 5, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 4, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "moduleName": "./src/cjs.cjs", + "type": "cjs self exports reference", + "userRequest": "self", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/cjs.cjs", + "resolvedModule": "./src/cjs.cjs", + "active": true, + "moduleId": 4, + "resolvedModuleId": 4 + }, + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "cjs require", + "userRequest": "./cjs.cjs", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "loc": "4:26-38", + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 74, + "sizes": { "javascript": 74 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "name": "./src/resolver.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "index": 7, + "preOrderIndex": 7, + "index2": 7, + "postOrderIndex": 7, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 5, + "issuerId": 0, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "require.resolve", + "userRequest": "./resolver.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["resolveModule"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 63, + "sizes": { "javascript": 63 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/dynamic.js", + "name": "./src/dynamic.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/dynamic.js", + "index": 9, + "preOrderIndex": 9, + "index2": 9, + "postOrderIndex": 9, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 7, + "issuerId": 0, + "chunks": ["0"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "moduleName": "./src/index.js", + "type": "import()", + "userRequest": "./dynamic.js", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "resolvedModule": "./src/index.js", + "active": true, + "moduleId": 0, + "resolvedModuleId": 0 + } + ], + "usedExports": null, + "providedExports": ["loadDynamic"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "css/mini-extract", + "size": 32, + "sizes": { "css/mini-extract": 32 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "css|commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css|0|||}", + "name": "css commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "index": 3, + "preOrderIndex": 3, + "index2": 1, + "postOrderIndex": 1, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + }, + { + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css", + "id": 2 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "issuerId": 2, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css", + "type": "extract css", + "userRequest": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "resolvedModuleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css", + "active": true, + "moduleId": 2, + "resolvedModuleId": 2 + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [], + "depth": 2 + }, + { + "type": "module", + "moduleType": "css/mini-extract", + "size": 31, + "sizes": { "css/mini-extract": 31 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "css|commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css|0|||}", + "name": "css commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "index": 4, + "preOrderIndex": 4, + "index2": 2, + "postOrderIndex": 2, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + }, + { + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css", + "id": 2 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "issuerId": 2, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css", + "type": "extract css", + "userRequest": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModuleIdentifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rspack/core/dist/cssExtractLoader.js!commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css", + "active": true, + "moduleId": 2, + "resolvedModuleId": 2 + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [], + "depth": 2 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 160, + "sizes": { "javascript": 160 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src|sync", + "name": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src|sync", + "index": 8, + "preOrderIndex": 8, + "index2": 6, + "postOrderIndex": 6, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "issuerName": "./src/resolver.js", + "issuerPath": [ + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/index.js", + "name": "./src/index.js", + "id": 0 + }, + { + "identifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "name": "./src/resolver.js", + "id": 5 + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": 6, + "issuerId": 5, + "chunks": ["1"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "moduleName": "./src/resolver.js", + "type": "require.resolve context", + "userRequest": ".", + "resolvedModuleIdentifier": "builtin:swc-loader??ruleSet[1].rules[4].use[0]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/resolver.js", + "resolvedModule": "./src/resolver.js", + "active": true, + "moduleId": 5, + "resolvedModuleId": 5 + } + ], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": 2 + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 790, + "sizes": { "javascript": 790 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "cacheable": true, + "optional": false, + "orphan": true, + "failed": false, + "errors": 0, + "warnings": 0, + "chunks": [], + "reasons": [ + { + "type": "loader import", + "userRequest": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css.webpack[javascript/auto]!=!!!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "active": true, + "moduleId": null, + "resolvedModuleId": null + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "javascript/auto", + "size": 508, + "sizes": { "javascript": 508 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "name": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "cacheable": true, + "optional": false, + "orphan": true, + "issuer": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "issuerPath": [ + { + "identifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "chunks": [], + "reasons": [ + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "type": "esm import", + "userRequest": "-!../../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./theme.css", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "active": true, + "loc": "4:0-220" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "type": "esm import specifier", + "userRequest": "-!../../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./theme.css", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "active": true, + "loc": "6:26-59" + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "javascript/dynamic", + "size": 2303, + "sizes": { "javascript": 2303 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "javascript/dynamic|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/api.js", + "name": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/api.js", + "cacheable": true, + "optional": false, + "orphan": true, + "issuer": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "issuerPath": [ + { + "identifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "chunks": [], + "reasons": [ + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "type": "esm import", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "active": true, + "loc": "3:0-114" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "type": "esm import specifier", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "active": true, + "loc": "5:30-57" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "moduleName": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "type": "esm import", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "resolvedModule": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "active": true, + "loc": "3:0-114" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "moduleName": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "type": "esm import specifier", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "resolvedModule": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "active": true, + "loc": "4:30-57" + }, + { + "moduleIdentifier": "javascript/dynamic|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/api.js", + "moduleName": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "type": "cjs self exports reference", + "userRequest": "self", + "resolvedModuleIdentifier": "javascript/dynamic|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/api.js", + "resolvedModule": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/api.js", + "active": true + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "javascript/dynamic", + "size": 64, + "sizes": { "javascript": 64 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "javascript/dynamic|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "name": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "cacheable": true, + "optional": false, + "orphan": true, + "issuer": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "issuerName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "issuerPath": [ + { + "identifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "name": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "chunks": [], + "reasons": [ + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "type": "esm import", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "active": true, + "loc": "2:0-136" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "moduleName": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "type": "esm import specifier", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/styles.css", + "resolvedModule": "./src/styles.css!=!../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/styles.css", + "active": true, + "loc": "5:58-98" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "moduleName": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "type": "esm import", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "resolvedModule": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "active": true, + "loc": "2:0-136" + }, + { + "moduleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "moduleName": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "type": "esm import specifier", + "userRequest": "../../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "resolvedModuleIdentifier": "commonjs|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!/Users/michael_hladky/WebstormProjects/quality-metrics-cli/tmp/e2e/plugin-bundle-stats/__test__/rsbuild-stats/src/theme.css", + "resolvedModule": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/index.js??ruleSet[1].rules[1].use[1]!builtin:lightningcss-loader??ruleSet[1].rules[1].use[2]!./src/theme.css", + "active": true, + "loc": "4:58-98" + }, + { + "moduleIdentifier": "javascript/dynamic|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "moduleName": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "type": "cjs self exports reference", + "userRequest": "self", + "resolvedModuleIdentifier": "javascript/dynamic|/Users/michael_hladky/WebstormProjects/quality-metrics-cli/node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "resolvedModule": "../../../../../node_modules/@rsbuild/core/compiled/css-loader/noSourceMaps.js", + "active": true + } + ], + "usedExports": null, + "providedExports": null, + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 264, + "sizes": { "runtime": 264 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "webpack/runtime/compat_get_default_export", + "name": "webpack/runtime/compat_get_default_export", + "cacheable": true, + "optional": false, + "orphan": true, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": [], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 0, + "sizes": { "runtime": 0 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/css loading", + "name": "webpack/runtime/css loading", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 285, + "sizes": { "runtime": 285 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/define_property_getters", + "name": "webpack/runtime/define_property_getters", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 285, + "sizes": { "runtime": 285 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/define_property_getters", + "name": "webpack/runtime/define_property_getters", + "cacheable": true, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 334, + "sizes": { "runtime": 334 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/ensure_chunk", + "name": "webpack/runtime/ensure_chunk", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 223, + "sizes": { "runtime": 223 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/get javascript chunk filename", + "name": "webpack/runtime/get javascript chunk filename", + "cacheable": false, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 224, + "sizes": { "runtime": 224 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/get mini-css chunk filename", + "name": "webpack/runtime/get mini-css chunk filename", + "cacheable": false, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 88, + "sizes": { "runtime": 88 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "webpack/runtime/has_own_property", + "name": "webpack/runtime/has_own_property", + "cacheable": true, + "optional": false, + "orphan": true, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": [], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 88, + "sizes": { "runtime": 88 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "webpack/runtime/has_own_property", + "name": "webpack/runtime/has_own_property", + "cacheable": true, + "optional": false, + "orphan": true, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": [], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 3005, + "sizes": { "runtime": 3005 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/jsonp_chunk_loading", + "name": "webpack/runtime/jsonp_chunk_loading", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 1414, + "sizes": { "runtime": 1414 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/load_script", + "name": "webpack/runtime/load_script", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 274, + "sizes": { "runtime": 274 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "webpack/runtime/make_namespace_object", + "name": "webpack/runtime/make_namespace_object", + "cacheable": true, + "optional": false, + "orphan": true, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": [], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 274, + "sizes": { "runtime": 274 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": true, + "cached": false, + "identifier": "webpack/runtime/make_namespace_object", + "name": "webpack/runtime/make_namespace_object", + "cacheable": true, + "optional": false, + "orphan": true, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": [], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 28, + "sizes": { "runtime": 28 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/public_path", + "name": "webpack/runtime/public_path", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 52, + "sizes": { "runtime": 52 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/rspack_unique_id", + "name": "webpack/runtime/rspack_unique_id", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + }, + { + "type": "module", + "moduleType": "runtime", + "size": 41, + "sizes": { "runtime": 41 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/rspack_version", + "name": "webpack/runtime/rspack_version", + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["1"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [] + } + ], + "entrypoints": { + "index": { + "name": "index", + "chunks": ["1"], + "assets": [ + { "name": "static/css/index.css", "size": 65 }, + { "name": "static/js/bundle.js", "size": 13743 } + ], + "filteredAssets": 0, + "assetsSize": 13808, + "auxiliaryAssets": [{ "name": "static/js/bundle.js.map", "size": 12899 }], + "auxiliaryAssetsSize": 12899, + "children": {}, + "childAssets": {}, + "isOverSizeLimit": false + } + }, + "namedChunkGroups": { + "index": { + "name": "index", + "chunks": ["1"], + "assets": [ + { "name": "static/css/index.css", "size": 65 }, + { "name": "static/js/bundle.js", "size": 13743 } + ], + "filteredAssets": 0, + "assetsSize": 13808, + "auxiliaryAssets": [{ "name": "static/js/bundle.js.map", "size": 12899 }], + "auxiliaryAssetsSize": 12899, + "children": {}, + "childAssets": {}, + "isOverSizeLimit": false + } + }, + "errors": [], + "errorsCount": 0, + "warnings": [], + "warningsCount": 0, + "children": [] +} diff --git a/packages/plugin-bundle-stats/src/lib/__snapshots__/webpack.stats.json b/packages/plugin-bundle-stats/src/lib/__snapshots__/webpack.stats.json new file mode 100644 index 0000000..e81d03e --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/__snapshots__/webpack.stats.json @@ -0,0 +1,1303 @@ +{ + "hash": "b2c1b46929cfeefc5018", + "version": "5.97.1", + "time": 60, + "builtAt": 1752050125968, + "publicPath": "auto", + "outputPath": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/dist", + "assetsByChunkName": { "main": ["bundle.js"] }, + "assets": [ + { + "type": "asset", + "name": "bundle.js", + "size": 17483, + "emitted": true, + "comparedForEmit": false, + "cached": false, + "info": { "javascriptModule": false, "size": 17483 }, + "chunkNames": ["main"], + "chunkIdHints": [], + "auxiliaryChunkNames": [], + "auxiliaryChunkIdHints": [], + "related": [], + "chunks": ["main"], + "auxiliaryChunks": [], + "isOverSizeLimit": false + }, + { + "type": "asset", + "name": "src_dynamic_js.bundle.js", + "size": 1202, + "emitted": true, + "comparedForEmit": false, + "cached": false, + "info": { "javascriptModule": false, "size": 1202 }, + "chunkNames": [], + "chunkIdHints": [], + "auxiliaryChunkNames": [], + "auxiliaryChunkIdHints": [], + "related": [], + "chunks": ["src_dynamic_js"], + "auxiliaryChunks": [], + "isOverSizeLimit": false + } + ], + "chunks": [ + { + "rendered": true, + "initial": true, + "entry": true, + "recorded": false, + "size": 9977, + "sizes": { "javascript": 3129, "runtime": 6848 }, + "names": ["main"], + "idHints": [], + "runtime": ["main"], + "files": ["bundle.js"], + "auxiliaryFiles": [], + "hash": "4d8eaf490abac88aba48", + "childrenByOrder": {}, + "id": "main", + "siblings": [], + "parents": [], + "children": ["src_dynamic_js"], + "modules": [ + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 400, + "sizes": { "javascript": 400 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "index": 0, + "preOrderIndex": 0, + "index2": 3, + "postOrderIndex": 3, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "issuer": null, + "issuerName": null, + "issuerPath": null, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/index.js", + "issuerId": null, + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": null, + "module": null, + "moduleName": null, + "resolvedModuleIdentifier": null, + "resolvedModule": null, + "type": "entry", + "active": true, + "explanation": "", + "userRequest": "./src/index.js", + "loc": "main", + "moduleId": null, + "resolvedModuleId": null + } + ], + "usedExports": null, + "providedExports": ["default"], + "optimizationBailout": [], + "depth": 0 + }, + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 69, + "sizes": { "javascript": 69 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/side-effects.js", + "name": "./src/side-effects.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/side-effects.js", + "index": 1, + "preOrderIndex": 1, + "index2": 0, + "postOrderIndex": 0, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/side-effects.js", + "issuerId": "./src/index.js", + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony side effect evaluation", + "active": true, + "explanation": "", + "userRequest": "./side-effects.js", + "loc": "1:0-27", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": ["sideEffect"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "asset/source", + "layer": null, + "size": 67, + "sizes": { "javascript": 67 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "asset/source|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/styles.css", + "name": "./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/styles.css", + "index": 2, + "preOrderIndex": 2, + "index2": 1, + "postOrderIndex": 1, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/styles.css", + "issuerId": "./src/index.js", + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony side effect evaluation", + "active": true, + "explanation": "", + "userRequest": "./styles.css", + "loc": "2:0-22", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 2593, + "sizes": { "javascript": 2593 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/utils.js", + "name": "./src/utils.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/utils.js", + "index": 3, + "preOrderIndex": 3, + "index2": 2, + "postOrderIndex": 2, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": true, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/utils.js", + "issuerId": "./src/index.js", + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony side effect evaluation", + "active": true, + "explanation": "", + "userRequest": "./utils.js", + "loc": "3:0-35", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + }, + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony import specifier", + "active": true, + "explanation": "", + "userRequest": "./utils.js", + "loc": "11:20-25", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": ["BIG_DATA", "add", "greet", "multiply"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 308, + "sizes": { "runtime": 308 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/define property getters", + "name": "webpack/runtime/define property getters", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 326, + "sizes": { "runtime": 326 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/ensure chunk", + "name": "webpack/runtime/ensure chunk", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 174, + "sizes": { "runtime": 174 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/get javascript chunk filename", + "name": "webpack/runtime/get javascript chunk filename", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 221, + "sizes": { "runtime": 221 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/global", + "name": "webpack/runtime/global", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 88, + "sizes": { "runtime": 88 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/hasOwnProperty shorthand", + "name": "webpack/runtime/hasOwnProperty shorthand", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 3041, + "sizes": { "runtime": 3041 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/jsonp chunk loading", + "name": "webpack/runtime/jsonp chunk loading", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 1397, + "sizes": { "runtime": 1397 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/load script", + "name": "webpack/runtime/load script", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 274, + "sizes": { "runtime": 274 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/make namespace object", + "name": "webpack/runtime/make namespace object", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 1019, + "sizes": { "runtime": 1019 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/publicPath", + "name": "webpack/runtime/publicPath", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "dependent": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + } + ], + "origins": [ + { + "module": "", + "moduleIdentifier": "", + "moduleName": "", + "loc": "main", + "request": "./src/index.js" + } + ] + }, + { + "rendered": true, + "initial": false, + "entry": false, + "recorded": false, + "size": 61, + "sizes": { "javascript": 61 }, + "names": [], + "idHints": [], + "runtime": ["main"], + "files": ["src_dynamic_js.bundle.js"], + "auxiliaryFiles": [], + "hash": "d17697ab1cdb385d8075", + "childrenByOrder": {}, + "id": "src_dynamic_js", + "siblings": [], + "parents": ["main"], + "children": [], + "modules": [ + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 61, + "sizes": { "javascript": 61 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/dynamic.js", + "name": "./src/dynamic.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/dynamic.js", + "index": 4, + "preOrderIndex": 4, + "index2": 4, + "postOrderIndex": 4, + "cacheable": true, + "optional": false, + "orphan": false, + "dependent": false, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/dynamic.js", + "issuerId": "./src/index.js", + "chunks": ["src_dynamic_js"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "import()", + "active": true, + "explanation": "", + "userRequest": "./dynamic.js", + "loc": "9:28-50", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": ["loadDynamic"], + "optimizationBailout": [], + "depth": 1 + } + ], + "origins": [ + { + "module": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "moduleName": "./src/index.js", + "loc": "9:28-50", + "request": "./dynamic.js", + "moduleId": "./src/index.js" + } + ] + } + ], + "modules": [ + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 400, + "sizes": { "javascript": 400 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "index": 0, + "preOrderIndex": 0, + "index2": 3, + "postOrderIndex": 3, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": null, + "issuerName": null, + "issuerPath": null, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/index.js", + "issuerId": null, + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": null, + "module": null, + "moduleName": null, + "resolvedModuleIdentifier": null, + "resolvedModule": null, + "type": "entry", + "active": true, + "explanation": "", + "userRequest": "./src/index.js", + "loc": "main", + "moduleId": null, + "resolvedModuleId": null + } + ], + "usedExports": null, + "providedExports": ["default"], + "optimizationBailout": [], + "depth": 0 + }, + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 69, + "sizes": { "javascript": 69 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/side-effects.js", + "name": "./src/side-effects.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/side-effects.js", + "index": 1, + "preOrderIndex": 1, + "index2": 0, + "postOrderIndex": 0, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/side-effects.js", + "issuerId": "./src/index.js", + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony side effect evaluation", + "active": true, + "explanation": "", + "userRequest": "./side-effects.js", + "loc": "1:0-27", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": ["sideEffect"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "asset/source", + "layer": null, + "size": 67, + "sizes": { "javascript": 67 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "asset/source|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/styles.css", + "name": "./src/styles.css", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/styles.css", + "index": 2, + "preOrderIndex": 2, + "index2": 1, + "postOrderIndex": 1, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/styles.css", + "issuerId": "./src/index.js", + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony side effect evaluation", + "active": true, + "explanation": "", + "userRequest": "./styles.css", + "loc": "2:0-22", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 2593, + "sizes": { "javascript": 2593 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/utils.js", + "name": "./src/utils.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/utils.js", + "index": 3, + "preOrderIndex": 3, + "index2": 2, + "postOrderIndex": 2, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/utils.js", + "issuerId": "./src/index.js", + "chunks": ["main"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony side effect evaluation", + "active": true, + "explanation": "", + "userRequest": "./utils.js", + "loc": "3:0-35", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + }, + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "harmony import specifier", + "active": true, + "explanation": "", + "userRequest": "./utils.js", + "loc": "11:20-25", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": ["BIG_DATA", "add", "greet", "multiply"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "javascript/esm", + "layer": null, + "size": 61, + "sizes": { "javascript": 61 }, + "built": true, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/dynamic.js", + "name": "./src/dynamic.js", + "nameForCondition": "/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/dynamic.js", + "index": 4, + "preOrderIndex": 4, + "index2": 4, + "postOrderIndex": 4, + "cacheable": true, + "optional": false, + "orphan": false, + "issuer": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "issuerName": "./src/index.js", + "issuerPath": [ + { + "identifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "name": "./src/index.js", + "id": "./src/index.js" + } + ], + "failed": false, + "errors": 0, + "warnings": 0, + "id": "./src/dynamic.js", + "issuerId": "./src/index.js", + "chunks": ["src_dynamic_js"], + "assets": [], + "reasons": [ + { + "moduleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "module": "./src/index.js", + "moduleName": "./src/index.js", + "resolvedModuleIdentifier": "javascript/esm|/Users/michael_hladky/WebstormProjects/cli/tmp/e2e/plugin-bundle-stats/__test__/webpack-stats/src/index.js", + "resolvedModule": "./src/index.js", + "type": "import()", + "active": true, + "explanation": "", + "userRequest": "./dynamic.js", + "loc": "9:28-50", + "moduleId": "./src/index.js", + "resolvedModuleId": "./src/index.js" + } + ], + "usedExports": null, + "providedExports": ["loadDynamic"], + "optimizationBailout": [], + "depth": 1 + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 308, + "sizes": { "runtime": 308 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/define property getters", + "name": "webpack/runtime/define property getters", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 326, + "sizes": { "runtime": 326 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/ensure chunk", + "name": "webpack/runtime/ensure chunk", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 174, + "sizes": { "runtime": 174 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/get javascript chunk filename", + "name": "webpack/runtime/get javascript chunk filename", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 221, + "sizes": { "runtime": 221 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/global", + "name": "webpack/runtime/global", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 88, + "sizes": { "runtime": 88 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/hasOwnProperty shorthand", + "name": "webpack/runtime/hasOwnProperty shorthand", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 3041, + "sizes": { "runtime": 3041 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/jsonp chunk loading", + "name": "webpack/runtime/jsonp chunk loading", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 1397, + "sizes": { "runtime": 1397 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/load script", + "name": "webpack/runtime/load script", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 274, + "sizes": { "runtime": 274 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/make namespace object", + "name": "webpack/runtime/make namespace object", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + }, + { + "type": "module", + "moduleType": "runtime", + "layer": null, + "size": 1019, + "sizes": { "runtime": 1019 }, + "built": false, + "codeGenerated": true, + "buildTimeExecuted": false, + "cached": false, + "identifier": "webpack/runtime/publicPath", + "name": "webpack/runtime/publicPath", + "nameForCondition": null, + "index": null, + "preOrderIndex": null, + "index2": null, + "postOrderIndex": null, + "optional": false, + "orphan": false, + "failed": false, + "errors": 0, + "warnings": 0, + "id": "", + "chunks": ["main"], + "assets": [], + "reasons": [], + "usedExports": null, + "providedExports": [], + "optimizationBailout": [], + "depth": null + } + ], + "entrypoints": { + "main": { + "name": "main", + "chunks": ["main"], + "assets": [{ "name": "bundle.js", "size": 17483 }], + "filteredAssets": 0, + "assetsSize": 17483, + "auxiliaryAssets": [], + "filteredAuxiliaryAssets": 0, + "auxiliaryAssetsSize": 0, + "children": {}, + "childAssets": {}, + "isOverSizeLimit": false + } + }, + "namedChunkGroups": { + "main": { + "name": "main", + "chunks": ["main"], + "assets": [{ "name": "bundle.js", "size": 17483 }], + "filteredAssets": 0, + "assetsSize": 17483, + "auxiliaryAssets": [], + "filteredAuxiliaryAssets": 0, + "auxiliaryAssetsSize": 0, + "children": {}, + "childAssets": {}, + "isOverSizeLimit": false + } + }, + "errors": [], + "errorsCount": 0, + "warnings": [], + "warningsCount": 0, + "children": [] +} diff --git a/packages/plugin-bundle-stats/src/lib/bundle-stats-plugin.ts b/packages/plugin-bundle-stats/src/lib/bundle-stats-plugin.ts new file mode 100644 index 0000000..04aaa3e --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/bundle-stats-plugin.ts @@ -0,0 +1,56 @@ +import { createRequire } from 'node:module'; +import type { Audit, PluginConfig } from '@code-pushup/models'; +import { BUNDLE_STATS_PLUGIN_SLUG } from './constants.js'; +import { normalizeBundleStatsOptions } from './normalize.js'; +import { + bundleStatsRunner, + mergeAuditConfigs, +} from './runner/bundle-stats-runner.js'; +import type { PluginOptions } from './types.js'; + +const PKG = createRequire(import.meta.url)('../../package.json'); + +export async function bundleStatsPlugin( + options: PluginOptions, +): Promise { + const { + groups = [], + bundler, + artifactsPaths, + generateArtifactsCommand, + audits, + ...pluginOptions + } = options; + + const bundleStatsConfigs = mergeAuditConfigs( + audits.map(normalizeBundleStatsOptions), + pluginOptions, + ); + + const auditConfigs: Audit[] = bundleStatsConfigs.map( + ({ slug, title, description, ..._ }) => + ({ + slug, + title, + description, + }) satisfies Audit, + ); + + return { + slug: BUNDLE_STATS_PLUGIN_SLUG, + packageName: PKG.name, + version: PKG.version, + title: 'Bundle Stats', + icon: 'folder-rules', + description: 'Official Code PushUp Bundle Stats plugin.', + docsUrl: 'https://npm.im/@code-pushup/bundle-stats-plugin', + audits: auditConfigs, + groups, + runner: await bundleStatsRunner({ + bundler, + artifactsPaths, + generateArtifactsCommand, + bundleStatsConfigs, + }), + }; +} diff --git a/packages/plugin-bundle-stats/src/lib/constants.ts b/packages/plugin-bundle-stats/src/lib/constants.ts new file mode 100644 index 0000000..d58bbdb --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/constants.ts @@ -0,0 +1,379 @@ +import type { PruningConfig } from './runner/audits/details/tree.js'; +import type { GroupingRule } from './runner/types.js'; + +/** + * Default grouping rules for bundle stats analysis. + * These rules help categorize and organize bundle assets by common patterns. + */ +export const DEFAULT_GROUPING: GroupingRule[] = [ + { + title: '@angular/*', + includeInputs: ['**/node_modules/@angular/**'], + icon: '🅰️', + }, + { + title: 'react', + includeInputs: ['**/node_modules/react/**', '**/node_modules/react-dom/**'], + icon: '⚛️', + }, + { + title: 'preact', + includeInputs: ['**/node_modules/preact/**', '**/node_modules/preact-*/**'], + icon: '🪐', + }, + { + title: 'vue', + includeInputs: ['**/node_modules/vue/**', '**/node_modules/@vue/**'], + icon: '💚', + }, + { + title: 'solid', + includeInputs: [ + '**/node_modules/solid-js/**', + '**/node_modules/solid-*/**', + ], + icon: '🟢', + }, + { + title: 'lit', + includeInputs: ['**/node_modules/lit/**', '**/node_modules/lit-html/**'], + icon: '💡', + }, + { + title: 'svelte', + includeInputs: [ + '**/node_modules/svelte/**', + '**/node_modules/@sveltejs/**', + ], + icon: '🧡', + }, + { + title: 'ember', + includeInputs: [ + '**/node_modules/ember-source/**', + '**/node_modules/ember-cli/**', + ], + icon: '🔥', + }, + { + title: 'backbone', + includeInputs: ['**/node_modules/backbone/**'], + icon: '🦴', + }, + { + title: 'alpine', + includeInputs: ['**/node_modules/alpinejs/**'], + icon: '🏔️', + }, + { + title: 'next.js', + includeInputs: ['**/node_modules/next/**'], + icon: '▲', + }, + { + title: 'nuxt', + includeInputs: ['**/node_modules/nuxt/**', '**/node_modules/@nuxt/**'], + icon: '💚', + }, + { + title: 'sveltekit', + includeInputs: ['**/node_modules/@sveltejs/kit/**'], + icon: '🏗️', + }, + { + title: 'remix', + includeInputs: [ + '**/node_modules/remix/**', + '**/node_modules/@remix-run/**', + ], + icon: '🌀', + }, + { + title: 'gatsby', + includeInputs: ['**/node_modules/gatsby/**'], + icon: '🚀', + }, + { + title: 'eleventy', + includeInputs: ['**/node_modules/eleventy/**', '**/node_modules/@11ty/**'], + icon: '1️⃣1️⃣', + }, + { + title: 'astro', + includeInputs: ['**/node_modules/astro/**'], + icon: '🌌', + }, + { + title: '@mui/*', + includeInputs: ['**/node_modules/@mui/**'], + icon: '🖼️', + }, + { + title: 'antd', + includeInputs: [ + '**/node_modules/antd/**', + '**/node_modules/@ant-design/**', + ], + icon: '🐜', + }, + { + title: 'chakra-ui', + includeInputs: ['**/node_modules/@chakra-ui/**'], + icon: '🧘', + }, + { + title: 'tailwindcss', + includeInputs: ['**/node_modules/tailwindcss/**'], + icon: '🌬️', + }, + { + title: 'bootstrap', + includeInputs: ['**/node_modules/bootstrap/**'], + icon: '👢', + }, + { + title: 'bulma', + includeInputs: ['**/node_modules/bulma/**'], + icon: '🍹', + }, + { + title: 'redux', + includeInputs: ['**/node_modules/redux/**', '**/node_modules/@reduxjs/**'], + icon: '🛠️', + }, + { + title: 'mobx', + includeInputs: ['**/node_modules/mobx/**'], + icon: '🧪', + }, + { + title: 'zustand', + includeInputs: ['**/node_modules/zustand/**'], + icon: '🧊', + }, + { + title: 'recoil', + includeInputs: ['**/node_modules/recoil/**'], + icon: '🎱', + }, + { + title: 'rxjs', + includeInputs: ['**/node_modules/rxjs/**'], + icon: '🔄', + }, + { + title: 'xstate', + includeInputs: ['**/node_modules/xstate/**'], + icon: '⚙️', + }, + { + title: 'react-router', + includeInputs: [ + '**/node_modules/react-router/**', + '**/node_modules/react-router-dom/**', + ], + icon: '🗺️', + }, + { + title: 'vue-router', + includeInputs: ['**/node_modules/vue-router/**'], + icon: '🗺️', + }, + { + title: 'webpack', + includeInputs: ['**/node_modules/webpack/**'], + icon: '📦', + }, + { + title: 'rollup', + includeInputs: ['**/node_modules/rollup/**'], + icon: '🔄', + }, + { + title: 'vite', + includeInputs: ['**/node_modules/vite/**'], + icon: '⚡️', + }, + { + title: 'parcel', + includeInputs: [ + '**/node_modules/parcel/**', + '**/node_modules/parcel-bundler/**', + ], + icon: '🎁', + }, + { + title: 'esbuild', + includeInputs: ['**/node_modules/esbuild/**'], + icon: '🏗️', + }, + { + title: 'snowpack', + includeInputs: ['**/node_modules/snowpack/**'], + icon: '❄️', + }, + { + title: 'jest', + includeInputs: ['**/node_modules/jest/**'], + icon: '🎯', + }, + { + title: 'mocha', + includeInputs: ['**/node_modules/mocha/**'], + icon: '☕️', + }, + { + title: 'chai', + includeInputs: ['**/node_modules/chai/**'], + icon: '🍵', + }, + { + title: 'cypress', + includeInputs: ['**/node_modules/cypress/**'], + icon: '🌪️', + }, + { + title: 'playwright', + includeInputs: ['**/node_modules/playwright/**'], + icon: '🎭', + }, + { + title: 'ava', + includeInputs: ['**/node_modules/ava/**'], + icon: '🐦', + }, + { + title: 'express', + includeInputs: ['**/node_modules/express/**'], + icon: '🚆', + }, + { + title: 'koa', + includeInputs: ['**/node_modules/koa/**'], + icon: '🍵', + }, + { + title: 'hapi', + includeInputs: ['**/node_modules/@hapi/hapi/**'], + icon: '🎉', + }, + { + title: 'fastify', + includeInputs: ['**/node_modules/fastify/**'], + icon: '🚀', + }, + { + title: '@nestjs/*', + includeInputs: ['**/node_modules/@nestjs/**'], + icon: '🔱', + }, + { + title: 'sails', + includeInputs: ['**/node_modules/sails/**'], + icon: '⛵️', + }, + { + title: 'loopback', + includeInputs: ['**/node_modules/@loopback/**'], + icon: '🔄', + }, + { + title: 'feathers', + includeInputs: ['**/node_modules/feathers/**'], + icon: '🪶', + }, + { + title: 'meteor', + includeInputs: ['**/node_modules/meteor/**'], + icon: '☄️', + }, + { + title: 'typeorm', + includeInputs: ['**/node_modules/typeorm/**'], + icon: '🗄️', + }, + { + title: '@prisma/*', + includeInputs: ['**/node_modules/@prisma/**'], + icon: '📐', + }, + { + title: 'sequelize', + includeInputs: ['**/node_modules/sequelize/**'], + icon: '🐆', + }, + { + title: 'mongoose', + includeInputs: ['**/node_modules/mongoose/**'], + icon: '🐭', + }, + { + title: 'graphql', + includeInputs: ['**/node_modules/graphql/**'], + icon: '🔮', + }, + { + title: '@apollo/*', + includeInputs: ['**/node_modules/@apollo/**'], + icon: '🛰️', + }, + { + title: 'axios', + includeInputs: ['**/node_modules/axios/**'], + icon: '🎣', + }, + { + title: 'socket.io', + includeInputs: ['**/node_modules/socket.io/**'], + icon: '🔌', + }, + { + title: 'eslint', + includeInputs: ['**/node_modules/eslint/**'], + icon: '🧹', + }, + { + title: 'prettier', + includeInputs: ['**/node_modules/prettier/**'], + icon: '🖌️', + }, + { + title: 'husky', + includeInputs: ['**/node_modules/husky/**'], + icon: '🐶', + }, + { + title: 'lint-staged', + includeInputs: ['**/node_modules/lint-staged/**'], + icon: '🐝', + }, + { + title: 'storybook', + includeInputs: ['**/node_modules/@storybook/**'], + icon: '📖', + }, + { + title: 'packages/*', + includeInputs: ['packages/**/*'], + // folder icon + icon: '📁', + }, + { + title: 'Dependencies', + includeInputs: ['**/node_modules/@*/**', '**/node_modules/**'], + }, +]; + +/** + * Default pruning options for bundle stats analysis. + * These settings control how the bundle tree is simplified and organized. + */ +export const DEFAULT_PRUNING: PruningConfig = { + maxChildren: 10, + maxDepth: 4, +}; + +/** + * Plugin slug for bundle stats plugin + */ +export const BUNDLE_STATS_PLUGIN_SLUG = 'bundle-stats'; diff --git a/packages/plugin-bundle-stats/src/lib/normalize.ts b/packages/plugin-bundle-stats/src/lib/normalize.ts new file mode 100644 index 0000000..8f22f67 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/normalize.ts @@ -0,0 +1,497 @@ +import type { Audit } from '@code-pushup/models'; +import { formatBytes, slugify } from '@code-pushup/utils'; + +import type { InsightsTableConfig } from './runner/audits/details/table.js'; +import type { DependencyTreeConfig } from './runner/audits/details/tree.js'; +import { + DEFAULT_PENALTY, + type PenaltyConfig, + type ScoringConfig, +} from './runner/audits/scoring.js'; +import type { SelectionConfig } from './runner/audits/selection.js'; +import type { BundleStatsConfig, MinMax } from './runner/types.js'; +import type { + BundleStatsAuditOptions, + PluginBundleStatsAuditOptions, + PluginDependencyTreeOptions, + PluginInsightsTableOptions, + PluginScoringOptions, + SelectionGeneralConfig, + SelectionOptions, +} from './types.js'; + +function formatStandardizedScoringSection(scoring: ScoringConfig): string { + const { totalSize, penalty } = scoring; + const items: string[] = []; + + // Artefact Size section + if (penalty && penalty.artefactSize) { + const [min, max] = penalty.artefactSize; + const weight = penalty.errorWeight || 0; + items.push( + ` - Artefact Size: >\`${formatBytes(min)}\` & <\`${formatBytes(max)}\`; weight: \`${weight}\``, + ); + } + + // Blacklist section + if (penalty && penalty.blacklist) { + const count = penalty.blacklist.length; + const weight = penalty.errorWeight || 0; + items.push(` - Blacklist: \`${count}\` matches; weight: \`${weight}\``); + } + + // Total Size section (if configured) + if (totalSize && totalSize[1] !== Infinity) { + items.push(` - Total Size: >\`${formatBytes(totalSize[1])}\` threshold`); + } + + return items.length > 0 ? `- **Scoring:**\n${items.join('\n')}` : ''; +} + +function formatStandardizedIssuesSection(scoring: ScoringConfig): string { + const { penalty } = scoring; + const items: string[] = []; + + if (penalty) { + // Check if this audit generates issues + if (penalty.blacklist && penalty.blacklist.length > 0) { + items.push( + ` - Error: \`1+\` candidates - Violation detected, requires action`, + ` - Info: \`0\` candidates - No violations found`, + ); + } else if (penalty.artefactSize) { + const [, max] = penalty.artefactSize; + items.push( + ` - Warning: <\`${formatBytes(max)}\` - Size acceptable but monitor growth`, + ` - Error: >\`${formatBytes(max)}\` - Exceeds size budget`, + ); + } else { + items.push(` - Info: \`0\` violations - Analysis only, no penalties`); + } + } else { + items.push(` - Info: \`0\` violations - Analysis only, no penalties`); + } + + return `- **Issues:**\n${items.join('\n')}`; +} + +function formatStandardizedTableSection( + insightsTable: InsightsTableConfig | undefined, +): string { + if ( + !insightsTable || + !insightsTable.groups || + insightsTable.groups.length === 0 + ) { + return ''; // Hide empty table section + } + + const groupItems = insightsTable.groups + .filter((group) => group.title) + .map((group) => `*${group.icon || ''}${group.title}*`) + .slice(0, 5); // Limit to prevent overly long descriptions + + const groupsText = + groupItems.length > 0 + ? `Detail listing of ${groupItems.join(', ')}` + : 'Configured groups'; + + return `- **Table:**\n - Groups: ${groupsText}\n - Rest: Other contributing modules`; +} + +function formatStandardizedTreeSection( + dependencyTree: DependencyTreeConfig | undefined, +): string { + if (!dependencyTree) { + return ''; // Hide disabled tree section + } + + const { pruning, groups, mode } = dependencyTree; + + // Format pruning settings + let pruningText = 'Default settings'; + if (pruning) { + const pruningParts: string[] = []; + if (pruning.minSize) { + pruningParts.push(`Min size: \`${formatBytes(pruning.minSize)}\``); + } + if (pruning.maxChildren) { + pruningParts.push(`Max children: \`${pruning.maxChildren}\``); + } + if (pruning.maxDepth) { + pruningParts.push(`Max depth: \`${pruning.maxDepth}\``); + } + if (pruning.pathLength) { + pruningParts.push(`Path length: \`${pruning.pathLength}\``); + } + + if (pruningParts.length > 0) { + pruningText = pruningParts.join(', '); + } + } + + // Format groups + let groupsText = 'None'; + if (groups && groups.length > 0) { + const groupSummaries = groups.map((group) => { + const parts: string[] = []; + if (group.title) { + parts.push(`"${group.title}"`); + } + if (group.icon) { + parts.push(`${group.icon}`); + } + if (group.includeInputs) { + if (Array.isArray(group.includeInputs)) { + const includePatterns = group.includeInputs + .slice(0, 2) + .map((p: string) => `"${p}"`) + .join(', '); + const moreCount = + group.includeInputs.length > 2 + ? `, +${group.includeInputs.length - 2} more` + : ''; + parts.push(`include: [${includePatterns}${moreCount}]`); + } else { + parts.push(`include: "${group.includeInputs}"`); + } + } + if ( + group.excludeInputs && + (typeof group.excludeInputs === 'string' + ? [group.excludeInputs] + : group.excludeInputs + ).length > 0 + ) { + const excludeArray = + typeof group.excludeInputs === 'string' + ? [group.excludeInputs] + : group.excludeInputs; + const excludePatterns = excludeArray + .slice(0, 1) + .map((p: string) => `"${p}"`) + .join(', '); + const moreCount = + excludeArray.length > 1 ? `, +${excludeArray.length - 1} more` : ''; + parts.push(`exclude: [${excludePatterns}${moreCount}]`); + } + return parts.join(' '); + }); + groupsText = groupSummaries.join('; '); + } + + // Format mode + const modeText = mode || 'onlyMatching'; + + return `- **Tree:**\n - Mode: \`${modeText}\`\n - Groups: ${groupsText}\n - Pruning: ${pruningText}`; +} + +function formatStandardizedSelectionSection( + selection: SelectionConfig, +): string { + const items: string[] = [` - Mode: \`${selection.mode}\``]; + + // Selection mode + + // Output patterns + if (selection.includeOutputs.length > 0) { + const patterns = selection.includeOutputs + .slice(0, 3) + .map((p) => `\`${p}\``) + .join(', '); + const extra = + selection.includeOutputs.length > 3 + ? ` (+${selection.includeOutputs.length - 3} more)` + : ''; + items.push(` - Include Outputs: ${patterns}${extra}`); + } + + if (selection.excludeOutputs.length > 0) { + const patterns = selection.excludeOutputs + .slice(0, 2) + .map((p) => `\`${p}\``) + .join(', '); + const extra = + selection.excludeOutputs.length > 2 + ? ` (+${selection.excludeOutputs.length - 2} more)` + : ''; + items.push(` - Exclude Outputs: ${patterns}${extra}`); + } + + // Input patterns + if (selection.includeInputs.length > 0) { + const patterns = selection.includeInputs + .slice(0, 3) + .map((p) => `\`${p}\``) + .join(', '); + const extra = + selection.includeInputs.length > 3 + ? ` (+${selection.includeInputs.length - 3} more)` + : ''; + items.push(` - Include Inputs: ${patterns}${extra}`); + } + + if (selection.excludeInputs.length > 0) { + const patterns = selection.excludeInputs + .slice(0, 2) + .map((p) => `\`${p}\``) + .join(', '); + const extra = + selection.excludeInputs.length > 2 + ? ` (+${selection.excludeInputs.length - 2} more)` + : ''; + items.push(` - Exclude Inputs: ${patterns}${extra}`); + } + + return `- **Selection:**\n${items.join('\n')}`; +} + +export function cleanTitleForSlug(title: string): string { + return title + .replace(/[^\w\s-]/g, '') + .replace(/\s+/g, '-') + .toLowerCase(); +} + +export function prepareDescription(config: BundleStatsConfig): string { + const { description, scoring, selection, dependencyTree, insightsTable } = + config; + + // Start with the action paragraph (preserve existing custom descriptions) + let enhancedDescription = description || ''; + + // Only add standardized sections if we have a custom description + if (enhancedDescription.trim()) { + const sections: string[] = []; + + // Add standardized sections + const scoringSection = formatStandardizedScoringSection(scoring); + if (scoringSection) { + sections.push(scoringSection); + } + + const issuesSection = formatStandardizedIssuesSection(scoring); + if (issuesSection) { + sections.push(issuesSection); + } + + const selectionSection = formatStandardizedSelectionSection(selection); + if (selectionSection) { + sections.push(selectionSection); + } + + // Handle insightsTable which could be false + const normalizedInsightsTable = + insightsTable === false ? undefined : insightsTable; + const tableSection = formatStandardizedTableSection( + normalizedInsightsTable, + ); + if (tableSection) { + sections.push(tableSection); + } + + const treeSection = formatStandardizedTreeSection(dependencyTree); + if (treeSection) { + sections.push(treeSection); + } + + // Wrap config sections in details if any exist + if (sections.length > 0) { + const configContent = sections.join('\n\n'); + enhancedDescription += `\n\n
\n⚙️ Configuration\n\n${configContent}\n\n
`; + } + } + + return enhancedDescription.trim() || ''; +} + +/** + * Converts SelectionGeneralConfig to SelectionOptions by adding default empty arrays. + */ +export function selectionGeneralConfigToOptions( + config: SelectionGeneralConfig, +): SelectionOptions { + return { + ...config, + mode: 'withStartupDeps', + includeOutputs: [], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + includeImports: [], + excludeImports: [], + includeEntryPoints: [], + excludeEntryPoints: [], + }; +} + +export function normalizeSelectionOptions( + options: SelectionOptions | undefined, +): SelectionConfig { + if (options === undefined) { + // Default: include all outputs for startup mode + return { + mode: 'withStartupDeps', + includeOutputs: ['**/*'], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }; + } + + const globalInclude = options.include || []; + const globalExclude = options.exclude || []; + + return { + mode: options.mode || 'withStartupDeps', + includeOutputs: [...(options.includeOutputs || []), ...globalInclude], + excludeOutputs: [...(options.excludeOutputs || []), ...globalExclude], + includeInputs: [...(options.includeInputs || []), ...globalInclude], + excludeInputs: [...(options.excludeInputs || []), ...globalExclude], + }; +} + +export function normalizeBundleStatsOptions( + auditOptions: BundleStatsAuditOptions, +): BundleStatsConfig { + const { slug, title, description, scoring, selection, ...restOptions } = + auditOptions; + const { penalty, totalSize } = scoring ?? {}; + + // Use the proper selection normalization helper that merges global patterns + const normalizedSelection = normalizeSelectionOptions(selection); + + let normalizedPenalty: false | PenaltyConfig | undefined; + if (penalty && typeof penalty === 'object') { + const { artefactSize, ...restPenalty } = penalty; + const penaltyConfig: PenaltyConfig = { + ...restPenalty, // Preserve all penalty properties including warningWeight, errorWeight + ...(artefactSize ? { artefactSize: normalizeRange(artefactSize) } : {}), + }; + normalizedPenalty = penaltyConfig; + } + + const normalizedScoring: ScoringConfig = { + mode: 'matchingWithStaticImports', + totalSize: normalizeRange(totalSize ?? Infinity), + penalty: normalizedPenalty, + }; + + const normalizedConfig: BundleStatsConfig = { + slug: slug ?? slugify(title), + title, + description: description || '', + selection: normalizedSelection, + scoring: normalizedScoring, + dependencyTree: restOptions.dependencyTree, + insightsTable: restOptions.insightsTable, + }; + + normalizedConfig.description = prepareDescription(normalizedConfig); + + return normalizedConfig; +} + +/** + * Normalizes scoring options. Converts plugin-level scoring to runner scoring config. + */ +export function normalizeScoringOptions( + options: PluginScoringOptions | undefined, +): ScoringConfig | undefined { + if (!options) { + return undefined; + } + + const { penalty } = options; + + return { + mode: 'matchingWithStaticImports', + totalSize: [0, Infinity], // Default range + penalty: penalty + ? { + ...DEFAULT_PENALTY, + ...penalty, + artefactSize: penalty.artefactSize + ? normalizeRange(penalty.artefactSize) + : undefined, + } + : DEFAULT_PENALTY, + }; +} + +/** + * Normalizes dependency tree options from plugin configuration. + * Groups array overwrites, pruning merges with defaults. + */ +export function normalizeDependencyTreeOptions( + options: PluginDependencyTreeOptions | undefined, +): DependencyTreeConfig { + return { + groups: options?.groups ?? [], + pruning: { + maxDepth: 2, + maxChildren: 10, + minSize: 1000, + pathLength: 60, + ...options?.pruning, + }, + mode: options?.mode ?? 'onlyMatching', + }; +} + +/** + * Normalizes insights table options. Converts plugin-level options to runner config. + */ +export function normalizeInsightsTableOptions( + options: PluginInsightsTableOptions | false | undefined, +): InsightsTableConfig | undefined { + if (options === false || options === undefined) { + return undefined; + } + + return { + mode: options.mode || 'onlyMatching', + groups: options.groups || [], + pruning: options.pruning + ? { + enabled: options.pruning.enabled ?? false, + maxChildren: options.pruning.maxChildren, + minSize: options.pruning.minSize, + } + : undefined, + }; +} + +export function normalizeRange(range: MinMax | number): MinMax { + if (typeof range === 'number') { + return [0, range]; + } + + return range; +} + +export function getAuditsFromConfigs(configs: BundleStatsConfig[]): Audit[] { + return configs.map(({ slug, title, description }) => ({ + slug, + title, + description, + })); +} + +/** + * Normalizes complete plugin options. Centralizes all normalization logic. + */ +export function normalizeBundleStatsAuditOptions( + auditOptions: BundleStatsAuditOptions[], + pluginOptions: PluginBundleStatsAuditOptions, +) { + return { + bundleStatsConfigs: auditOptions.map(normalizeBundleStatsOptions), + scoring: normalizeScoringOptions(pluginOptions.scoring), + dependencyTree: normalizeDependencyTreeOptions( + pluginOptions.dependencyTree, + ), + insightsTable: normalizeInsightsTableOptions(pluginOptions.insightsTable), + selection: pluginOptions.selection, + }; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.ts new file mode 100644 index 0000000..44d7f2d --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.ts @@ -0,0 +1,69 @@ +import type { AuditOutput } from '@code-pushup/models'; +import type { BundleStatsConfig } from '../types.js'; +import type { UnifiedStats } from '../unify/unified-stats.types.js'; +import { createDisplayValue, createEmptyAudit } from '../utils.js'; +import { createAuditOutputDetails } from './details/audit-details.js'; +import { getIssues } from './details/issues.js'; +import { createBundleStatsScoring } from './scoring.js'; +import { selectBundles } from './selection.js'; + +/** + * Calculates total bytes from unified stats tree. Aggregates byte counts across all artefacts. + */ +export function calculateTotalBytes(statsSlice: UnifiedStats): number { + return Object.values(statsSlice).reduce((acc, curr) => acc + curr.bytes, 0); +} + +/** + * Creates audit output from processed tree data and configuration. Combines size scoring with penalty calculations from actual issues. + */ +export function createAuditOutput( + statsSlice: UnifiedStats, + config: BundleStatsConfig, +): AuditOutput { + const trees = Object.values(statsSlice); + const totalBytes = calculateTotalBytes(statsSlice); + + console.time('⚡ GET_ISSUES'); + const issues = getIssues(statsSlice, config); + console.timeEnd('⚡ GET_ISSUES'); + + const calculateScore = createBundleStatsScoring({ + mode: config.scoring.mode, + totalSize: config.scoring.totalSize, + penalty: config.scoring.penalty, + }); + + return { + slug: config.slug, + score: calculateScore(totalBytes, issues), + value: totalBytes, + displayValue: createDisplayValue(totalBytes, trees.length), + details: createAuditOutputDetails(issues, statsSlice, config), + }; +} + +/** + * Generates audit outputs from bundle stats tree and configurations + */ +export function generateAuditOutputs( + bundleStatsTree: UnifiedStats, + configs: BundleStatsConfig[], +): AuditOutput[] { + return configs.map((config) => { + console.time(`🔍 SELECT_BUNDLES - ${config.slug}`); + + const filteredTree = selectBundles(bundleStatsTree, config.selection); + console.timeEnd(`🔍 SELECT_BUNDLES - ${config.slug}`); + + if (!filteredTree || Object.keys(filteredTree).length === 0) { + return createEmptyAudit(config); + } + + console.time(`📝 CREATE_AUDIT_OUTPUT - ${config.slug}`); + const result = createAuditOutput(filteredTree, config); + console.timeEnd(`📝 CREATE_AUDIT_OUTPUT - ${config.slug}`); + + return result; + }); +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.unit.test.ts new file mode 100644 index 0000000..52d207b --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.unit.test.ts @@ -0,0 +1,64 @@ +import { describe, expect, it } from 'vitest'; +import { calculateTotalBytes, generateAuditOutputs } from './audit-outputs.js'; + +describe('calculateTotalBytes', () => { + it('should calculate total bytes from empty stats', () => { + expect(calculateTotalBytes({})).toBe(0); + }); + + it('should calculate total bytes from multiple outputs', () => { + expect( + calculateTotalBytes({ + 'bundle.js': { + path: 'bundle.js', + bytes: 1000, + }, + 'vendor.js': { + path: 'vendor.js', + bytes: 2500, + }, + 'styles.css': { + path: 'styles.css', + bytes: 500, + }, + }), + ).toBe(4000); + }); +}); + +describe('generateAuditOutputs', () => { + it('should generate empty audit when no artifacts match selection', () => { + expect( + generateAuditOutputs( + { + 'main.css': { path: 'main.css', bytes: 1000 }, + }, + [ + { + title: 'JS Bundle', + slug: 'js-bundle', + description: 'JS bundle analysis', + selection: { + mode: 'matchingOnly', + includeOutputs: ['**/*.js'], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }, + scoring: { + mode: 'onlyMatching', + totalSize: [1000, 10_000], + }, + }, + ], + ), + ).toStrictEqual([ + expect.objectContaining({ + slug: 'js-bundle', + score: 0, + value: 0, + displayValue: '0 B (0 files)', + }), + ]); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/audit-details.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/audit-details.ts new file mode 100644 index 0000000..a4f3cec --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/audit-details.ts @@ -0,0 +1,52 @@ +import type { AuditDetails, Issue } from '@code-pushup/models'; +import type { BundleStatsConfig } from '../../types.js'; +import type { UnifiedStats } from '../../unify/unified-stats.types.js'; +import { createInsightsTable } from './table.js'; +import { createTree } from './tree.js'; + +/** + * Creates audit details containing issues, insights table, and artifact tree based on configuration. + * Assembles comprehensive output details for bundle analysis reporting. + */ +export function createAuditOutputDetails( + issues: Issue[], + statsSlice: UnifiedStats, + config: BundleStatsConfig, +): AuditDetails { + const details: AuditDetails = { + issues, + }; + + if ( + config.insightsTable && + config.insightsTable.groups && + config.insightsTable.groups.length > 0 + ) { + console.time('📊 CREATE_INSIGHTS_TABLE'); + details.table = createInsightsTable(statsSlice, config.insightsTable); + console.timeEnd('📊 CREATE_INSIGHTS_TABLE'); + } + + // Check if dependency tree is enabled (default: enabled if config exists) + const isTreeEnabled = + config.dependencyTree && + typeof config.dependencyTree === 'object' && + (!('enabled' in config.dependencyTree) || + config.dependencyTree.enabled !== false); + + if (isTreeEnabled && typeof config.dependencyTree === 'object') { + console.time('🌳 CREATE_TREE'); + details.trees = [ + createTree(statsSlice, { + title: config.slug, + mode: config.dependencyTree.mode ?? 'onlyMatching', + pruning: config.dependencyTree.pruning ?? {}, + groups: config.dependencyTree.groups ?? [], + selection: config.selection, // Pass selection config for onlyMatching filtering + }), + ]; + console.timeEnd('🌳 CREATE_TREE'); + } + + return details; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/formatting.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/formatting.ts new file mode 100644 index 0000000..7f762b7 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/formatting.ts @@ -0,0 +1,172 @@ +import { + extractConcreteSegments, + extractPathSlice, + findSegmentIndex, + normalizePathForMatching, + splitPathSegments, +} from './path-utils.js'; + +// Regex cache to avoid recreating the same regex patterns +const REGEX_CACHE = new Map(); + +function getCachedRegex(pattern: string): RegExp { + const cached = REGEX_CACHE.get(pattern); + if (cached) { + return cached; + } + + const regex = new RegExp(String.raw`${pattern}\/([^\/]+)`); + REGEX_CACHE.set(pattern, regex); + return regex; +} + +export function removeFileExtension(name: string): string { + return name.replace(/\.(js|ts|jsx|tsx|css|scss|json)$/, ''); +} + +export function isGenericName(name: string): boolean { + return name === 'index' || name === 'main' || name === ''; +} + +export function extractScopedPackage( + path: string, +): { scope: string; package?: string } | null { + const match = path.match(/@([^/]+)(?:\/([^/]+))?/); + if (match) { + return { + scope: match[1]!, + package: match[2], + }; + } + return null; +} + +export function extractMeaningfulPathPart(path: string): string | null { + const parts = splitPathSegments(path.replace(/^\.\//, '')); + + if (parts.length === 0) { + return null; + } + + const lastPart = parts.at(-1); + if (lastPart) { + const withoutExt = removeFileExtension(lastPart); + if (withoutExt && !isGenericName(withoutExt)) { + return withoutExt; + } + } + + if (parts.length > 1) { + const secondLast = parts.at(-2); + if (secondLast && !isGenericName(secondLast)) { + return secondLast; + } + } + + return null; +} + +export function cleanupGroupName(groupName: string): string { + const scopedPackage = extractScopedPackage(groupName); + if (scopedPackage) { + return scopedPackage.package + ? `@${scopedPackage.scope}/${scopedPackage.package}` + : `@${scopedPackage.scope}`; + } + + const segments = splitPathSegments(groupName); + if (segments.length === 0) { + return groupName; + } + + // For scoped packages, try to extract the scope and package + for (let i = 0; i < segments.length; i++) { + const segment = segments[i]; + if (!segment) { + continue; + } + + // Handle scoped packages like @angular/router + if (segment.startsWith('@') && i + 1 < segments.length) { + const scopeName = segment.slice(1); + const packageName = segments[i + 1]; + return packageName ? `@${scopeName}/${packageName}` : `@${scopeName}`; + } + } + + // Extract the last meaningful segment (the actual package/folder name) + for (let i = segments.length - 1; i >= 0; i--) { + const segment = segments[i]; + if (!segment || isGenericName(segment)) { + continue; + } + + // Return the first meaningful segment we find from the end + return segment; + } + + const withoutExt = removeFileExtension(groupName); + if (isGenericName(withoutExt)) { + return groupName; + } + + return withoutExt || groupName; +} + +export function extractGroupKeyFromPattern( + filePath: string, + pattern: string, + maxDepth?: number, +): string | null { + const normalizedPath = normalizePathForMatching(filePath); + const concreteSegments = extractConcreteSegments(pattern); + + if (concreteSegments.length === 0) { + return extractMeaningfulPathPart(normalizedPath); + } + + if (maxDepth && maxDepth > 0 && concreteSegments.length > 0) { + const keyPart = concreteSegments[0]!; + const keyIndex = findSegmentIndex(filePath, keyPart); + + if (keyIndex !== -1) { + return extractPathSlice(filePath, keyIndex, maxDepth); + } + } + + for (const segment of concreteSegments) { + const regex = getCachedRegex(segment); // Use cached regex + const match = filePath.match(regex) || normalizedPath.match(regex); + + if (match?.[1]) { + const extracted = match[1]; + const cleaned = removeFileExtension(extracted); + if (cleaned && !isGenericName(cleaned)) { + return cleaned; + } + } + } + + return null; +} + +export function deriveGroupTitle( + path: string, + patterns: readonly string[], + fallbackTitle: string, +): string { + for (const pattern of patterns) { + const concreteSegments = extractConcreteSegments(pattern); + + if (concreteSegments.includes(fallbackTitle)) { + return fallbackTitle; + } + + const groupName = extractGroupKeyFromPattern(path, pattern); + if (groupName) { + return cleanupGroupName(groupName); + } + } + + return fallbackTitle; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.ts new file mode 100644 index 0000000..05e383a --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.ts @@ -0,0 +1,462 @@ +import { minimatch } from 'minimatch'; +import type { GroupingRule, LogicalGroupingRule } from '../../types.js'; +import { + cleanupGroupName, + deriveGroupTitle, + extractGroupKeyFromPattern, +} from './formatting.js'; +import { normalizePathForMatching, splitPathSegments } from './path-utils.js'; +import type { StatsNodeValues } from './types.js'; + +export type PatternMatcher = (path: string) => boolean; + +// Pattern cache to avoid recompiling the same patterns +const PATTERN_CACHE = new Map(); + +/** + * Normalizes patterns from string | PatternList to readonly string[]. + */ +function normalizePatterns( + patterns?: string | readonly string[], +): readonly string[] { + if (!patterns) { + return []; + } + + const normalizedArray = typeof patterns === 'string' ? [patterns] : patterns; + + // Filter out any undefined, null, or empty string values + return normalizedArray.filter( + (pattern): pattern is string => + typeof pattern === 'string' && pattern.trim() !== '', + ); +} + +export type MatchOptions = { + matchBase?: boolean; + normalizeRelativePaths?: boolean; +}; + +export type GroupData = Omit & { + title: string; + type: 'group'; +}; + +export type GroupManager = { + groups: Map; + findOrCreateGroup: ( + key: string, + rule: LogicalGroupingRule, + defaultTitle?: string, + ) => T; + getAllGroups: () => T[]; + getGroupsWithData: () => T[]; +}; + +export type StatsTreeNode = { + children: StatsTreeNode[]; + name: string; + values: StatsNodeValues; +}; + +export type StatsTree = { + root: StatsTreeNode; +}; + +const DEFAULT_GROUP_NAME = 'Group'; + +/** + * Compiles pattern into cached matcher function. Avoids recompilation overhead. + */ +export function compilePattern( + pattern: string, + options: MatchOptions = {}, +): PatternMatcher { + // Create cache key from pattern and options + const cacheKey = `${pattern}|${JSON.stringify(options)}`; + + // Return cached pattern if available + const cached = PATTERN_CACHE.get(cacheKey); + if (cached) { + return cached; + } + + // Compile new pattern + const matcher = (path: string) => { + const minimatchOptions = options.matchBase ? { matchBase: true } : {}; + if (minimatch(path, pattern, minimatchOptions)) { + return true; + } + if (options.normalizeRelativePaths) { + const normalizedPath = normalizePathForMatching(path); + return minimatch(normalizedPath, pattern, minimatchOptions); + } + return false; + }; + + // Cache and return + PATTERN_CACHE.set(cacheKey, matcher); + return matcher; +} + +/** + * Checks if path matches a GroupingRule using include/exclude logic + */ +function matchesGroupingRule( + path: string, + rule: GroupingRule, + options: MatchOptions = {}, +): boolean { + const includePatterns = normalizePatterns(rule.includeInputs); + const excludePatterns = normalizePatterns(rule.excludeInputs); + + return evaluatePathWithIncludeExclude( + path, + includePatterns, + excludePatterns, + options, + ); +} + +/** + * Separates patterns into include and exclude arrays. Exclude patterns start with ! + * @deprecated - Use the new include/exclude GroupingRule format instead + */ +function separateIncludeExcludePatterns(patterns: readonly string[]): { + includePatterns: string[]; + excludePatterns: string[]; +} { + const includePatterns: string[] = []; + const excludePatterns: string[] = []; + + for (const pattern of patterns) { + if (pattern.startsWith('!')) { + excludePatterns.push(pattern.slice(1)); // Remove ! prefix + } else { + includePatterns.push(pattern); + } + } + + return { includePatterns, excludePatterns }; +} + +/** + * Evaluates path against include/exclude patterns using the same logic as selection system + */ +function evaluatePathWithIncludeExclude( + path: string, + includePatterns: readonly string[], + excludePatterns: readonly string[], + options: MatchOptions = {}, +): boolean { + // If exclude patterns exist, check if path matches any - if so, exclude it + if (excludePatterns.length > 0) { + for (const pattern of excludePatterns) { + const matcher = compilePattern(pattern, options); + if (matcher(path)) { + return false; + } + } + } + + // If no include patterns, include everything (after exclusion check) + if (includePatterns.length === 0) { + return true; + } + + // Check if path matches any include pattern + for (const pattern of includePatterns) { + const matcher = compilePattern(pattern, options); + if (matcher(path)) { + return true; + } + } + + return false; +} + +export function matchesAnyPattern( + path: string, + patterns: readonly string[], + options: MatchOptions = {}, +): boolean { + // Legacy support for old patterns array format + const { includePatterns, excludePatterns } = + separateIncludeExcludePatterns(patterns); + return evaluatePathWithIncludeExclude( + path, + includePatterns, + excludePatterns, + options, + ); +} + +/** + * Finds first matching rule for path. Processes rules in forward order for top-down precedence. + */ +export function findMatchingRule( + filePath: string, + rules: GroupingRule[], +): GroupingRule | null { + for (const rule of rules) { + if ( + rule && + matchesGroupingRule(filePath, rule, { + matchBase: true, + normalizeRelativePaths: true, + }) + ) { + return rule; + } + } + return null; +} + +export function generateGroupKey( + filePath: string, + rule: GroupingRule, + preferRuleTitle = false, +): string { + if (preferRuleTitle && rule.title) { + return rule.title; + } + + // For new include/exclude format, use the include patterns for title generation + const includePatterns = normalizePatterns(rule.includeInputs); + return deriveGroupTitle( + filePath, + includePatterns, + rule.title || DEFAULT_GROUP_NAME, + ); +} + +export function createGroupManager(): GroupManager { + const groups = new Map(); + return { + groups, + findOrCreateGroup( + key: string, + rule: LogicalGroupingRule, + defaultTitle?: string, + ): T { + let group = groups.get(key); + if (!group) { + const title = rule.title || defaultTitle || key; + const groupData = { + title, + bytes: 0, + modules: 0, + type: 'group' as const, + icon: rule.icon, + }; + group = groupData as T; + groups.set(key, group); + } + return group; + }, + getAllGroups(): T[] { + return [...groups.values()]; + }, + getGroupsWithData(): T[] { + return [...groups.values()].filter((g) => g.bytes > 0); + }, + }; +} + +export function toLogicalGroupingRule(rule: GroupingRule): LogicalGroupingRule { + const { numSegments: maxDepth, ...rest } = rule; + return { ...rest, maxDepth: 1 }; +} + +export function findOrCreateGroupFromRule( + groupManager: GroupManager, + key: string, + rule: GroupingRule, + defaultTitle?: string, +): T { + const logicalRule = toLogicalGroupingRule(rule); + return groupManager.findOrCreateGroup(key, logicalRule, defaultTitle); +} + +export function processForTable( + filePath: string, + rules: GroupingRule[], + preferRuleTitle = true, +): { rule: GroupingRule | null; groupKey: string | null } { + const rule = findMatchingRule(filePath, rules); + if (!rule) { + return { rule: null, groupKey: null }; + } + const groupKey = generateGroupKey(filePath, rule, preferRuleTitle); + return { rule, groupKey }; +} + +function extractIntelligentGroupKey( + filePath: string, + patterns: readonly string[], + maxDepth: number, +): string { + const pathParts = splitPathSegments(filePath); + + // Try pattern-based extraction first + for (const pattern of patterns) { + const patternKey = extractGroupKeyFromPattern(filePath, pattern, maxDepth); + if (patternKey) { + return patternKey; + } + } + + // Fallback to simple depth-based extraction from the beginning of path + if (pathParts.length >= maxDepth) { + return pathParts.slice(0, maxDepth).join('/'); + } + + // If path is shorter than maxDepth, use the whole path + return pathParts.join('/'); +} + +/** + * Groups nodes by patterns at current level only. Organizes files into logical groups without recursive processing. + */ +export function applyGrouping( + nodes: StatsTreeNode[], + groups: GroupingRule[], +): StatsTreeNode[] { + if (!groups || groups.length === 0) { + return [...nodes].toSorted((a, b) => b.values.bytes - a.values.bytes); + } + + // Process nodes without recursive grouping - caller handles recursion + let finalNodes = [...nodes]; + // Track original input nodes vs newly created group nodes + const originalNodes = new Set(nodes); + finalNodes.sort((a, b) => b.values.bytes - a.values.bytes); + + for (const group of groups) { + const { title, includeInputs, icon, numSegments: maxDepth } = group; + const nodesToGroup: StatsTreeNode[] = []; + const remainingNodes: StatsTreeNode[] = []; + + finalNodes.forEach((node) => { + const matchingRule = findMatchingRule(node.name, [group]); + if (matchingRule && originalNodes.has(node)) { + // Only group original input nodes, not previously created group nodes + nodesToGroup.push(node); + } else { + remainingNodes.push(node); + } + }); + + if (nodesToGroup.length > 0) { + const groupedNodes: StatsTreeNode[] = []; + + // When reduce is true, always create a single consolidated group + const shouldCreateSingleGroup = !maxDepth || maxDepth === 0; + + if (!shouldCreateSingleGroup && maxDepth && maxDepth > 0) { + const pathGroups = new Map(); + nodesToGroup.forEach((node) => { + const groupKey = extractIntelligentGroupKey( + node.name, + normalizePatterns(includeInputs), + maxDepth, + ); + if (!pathGroups.has(groupKey)) { + pathGroups.set(groupKey, []); + } + pathGroups.get(groupKey)!.push(node); + }); + + pathGroups.forEach((nodesInGroup, groupPath) => { + const totalBytes = nodesInGroup.reduce( + (sum, node) => sum + node.values.bytes, + 0, + ); + const totalModules = nodesInGroup.reduce( + (sum, node) => sum + node.values.modules, + 0, + ); + + const folderNode: StatsTreeNode = { + name: title || cleanupGroupName(groupPath), + values: { + path: groupPath, + bytes: totalBytes, + modules: totalModules, + type: 'group', + icon, + }, + children: nodesInGroup.toSorted( + (a, b) => b.values.bytes - a.values.bytes, + ), + }; + groupedNodes.push(folderNode); + }); + } else { + let effectiveTitle: string; + if (title) { + effectiveTitle = title; + } else { + const samplePath = nodesToGroup[0]?.name || ''; + effectiveTitle = deriveGroupTitle( + samplePath, + normalizePatterns(includeInputs), + DEFAULT_GROUP_NAME, + ); + } + + const totalBytes = nodesToGroup.reduce( + (sum, node) => sum + node.values.bytes, + 0, + ); + const totalModules = nodesToGroup.reduce( + (sum, node) => sum + node.values.modules, + 0, + ); + + const groupNode: StatsTreeNode = { + name: effectiveTitle, + values: { + path: '', + bytes: totalBytes, + modules: totalModules, + type: 'group', + icon, + }, + // When reduce is true, don't show children - collapse to summary only + children: nodesToGroup.toSorted( + (a, b) => b.values.bytes - a.values.bytes, + ), + }; + groupedNodes.push(groupNode); + } + + groupedNodes.sort((a, b) => b.values.bytes - a.values.bytes); + remainingNodes.push(...groupedNodes); + } + + finalNodes = remainingNodes; + finalNodes.sort((a, b) => b.values.bytes - a.values.bytes); + } + + // Filter out files that are excluded by any group's exclude patterns + return finalNodes.filter((node) => { + // Keep group nodes (created by grouping process) + if (!originalNodes.has(node)) { + return true; + } + + // For original nodes, check if they're excluded by any group + return !groups.some((group) => { + if (!group.excludeInputs || group.excludeInputs.length === 0) { + return false; + } + + const excludePatterns = normalizePatterns(group.excludeInputs); + return excludePatterns.some((pattern) => { + const matcher = compilePattern(pattern); + return matcher(node.name); + }); + }); + }); +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.unit.test.ts new file mode 100644 index 0000000..7161eba --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.unit.test.ts @@ -0,0 +1,41 @@ +import { describe, expect, it } from 'vitest'; +import type { GroupingRule } from '../../types.js'; +import { findMatchingRule } from './grouping.js'; + +describe('GroupingRule exclude logic', () => { + it('should exclude paths that match exclude patterns even when they match include patterns', () => { + const rule: GroupingRule = { + includeInputs: '**/node_modules/**', + excludeInputs: [ + '**/node_modules/react/**', + '**/node_modules/@angular/**', + ], + }; + + // These paths match include but should be excluded + expect(findMatchingRule('node_modules/react/index.js', [rule])).toBeNull(); + expect( + findMatchingRule('node_modules/@angular/core/index.js', [rule]), + ).toBeNull(); + + // This path matches include and is not excluded + expect(findMatchingRule('node_modules/lodash/index.js', [rule])).toEqual( + rule, + ); + }); + + it('should handle multiple exclude patterns', () => { + const rule: GroupingRule = { + includeInputs: '**/src/**', + excludeInputs: ['**/*.test.ts', '**/*.spec.ts', '**/src/legacy/**'], + }; + + // These should be excluded + expect(findMatchingRule('src/app.test.ts', [rule])).toBeNull(); + expect(findMatchingRule('src/utils.spec.ts', [rule])).toBeNull(); + expect(findMatchingRule('src/legacy/old-code.ts', [rule])).toBeNull(); + + // This should match + expect(findMatchingRule('src/app.ts', [rule])).toEqual(rule); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.ts new file mode 100644 index 0000000..25dc586 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.ts @@ -0,0 +1,518 @@ +import { minimatch } from 'minimatch'; +import type { Issue } from '@code-pushup/models'; +import { formatBytes } from '@code-pushup/utils'; +import type { BundleStatsConfig } from '../../types.js'; +import type { + UnifiedStats, + UnifiedStatsBundle, +} from '../../unify/unified-stats.types.js'; +import type { BlacklistEntry, BlacklistPatternList } from '../scoring.js'; + +// ===== PERFORMANCE OPTIMIZATIONS ===== + +// Cache for blacklist pattern matches to avoid repeated minimatch calls +const BLACKLIST_PATTERN_CACHE = new Map(); + +// Clear cache when it gets too large to prevent memory issues +function clearCacheIfNeeded(): void { + if (BLACKLIST_PATTERN_CACHE.size > 50_000) { + BLACKLIST_PATTERN_CACHE.clear(); + } +} + +// ===== ISSUE ICONS ===== + +export const ISSUE_ICONS = { + TOO_LARGE: '🔺', + TOO_SMALL: '🔻', + BLACKLIST: '🚫', +} as const; + +/** + * Normalizes blacklist entry to extract pattern string and hint. + */ +function normalizeBlacklistEntry(entry: BlacklistEntry): { + pattern: string; + hint?: string; +} { + if (typeof entry === 'string') { + return { pattern: entry }; + } + return { pattern: entry.pattern, hint: entry.hint }; +} + +/** + * Optimized pattern matching with caching. Avoids repeated minimatch calls for same path-pattern pairs. + */ +function matchesPattern(path: string, pattern: string): boolean { + const cacheKey = `${path}|${pattern}`; + + const cached = BLACKLIST_PATTERN_CACHE.get(cacheKey); + if (cached !== undefined) { + return cached; + } + + const result = minimatch(path, pattern, { matchBase: true }); + BLACKLIST_PATTERN_CACHE.set(cacheKey, result); + + return result; +} + +/** + * Checks if a path matches any of the given blacklist patterns. Enables pattern-based filtering with optimized caching. + */ +function matchesBlacklistPattern( + path: string, + patterns: BlacklistPatternList, +): { pattern: string; hint?: string } | null { + // Clear cache periodically to prevent memory bloat + clearCacheIfNeeded(); + + for (const entry of patterns) { + const { pattern, hint } = normalizeBlacklistEntry(entry); + if (matchesPattern(path, pattern)) { + return { pattern, hint }; + } + } + return null; +} + +/** + * Creates error issue for oversized artifact exceeding maximum threshold. Indicates unoptimized bundle or accidental check-in requiring optimization. + * + * @param outputPath - Path to the output file that exceeds size limit + * @param bytes - Actual size of the artifact in bytes + * @param maxSize - Maximum allowed size threshold in bytes + * @returns Issue object with error severity and optimization recommendation + * + * @example + * ```js + * createTooLargeIssue('dist/bundle.js', 1048576, 500000) + * // Returns: { message: "🔺 `dist/bundle.js` is **1 MB** _(> 488 kB)_", severity: 'error', ... } + * ``` + */ +export function createTooLargeIssue( + outputPath: string, + bytes: number, + maxSize: number, +): Issue { + return { + message: `${ISSUE_ICONS.TOO_LARGE} \`${outputPath}\` is **${formatBytes(bytes)}** _(> ${formatBytes(maxSize)})_`, + severity: 'error', + source: { file: outputPath }, + }; +} + +/** + * Creates warning issue for undersized artifact below minimum threshold. Signals missing dependencies or incomplete build requiring verification. + * + * @param outputPath - Path to the output file that is below size limit + * @param bytes - Actual size of the artifact in bytes + * @param minSize - Minimum expected size threshold in bytes + * @returns Issue object with warning severity and verification recommendation + * + * @example + * ```js + * createTooSmallIssue('dist/chunk.js', 512, 2048) + * // Returns: { message: "🔻 `dist/chunk.js` is **512 B** _(< 2 kB)_", severity: 'warning', ... } + * ``` + */ +export function createTooSmallIssue( + outputPath: string, + bytes: number, + minSize: number, +): Issue { + return { + message: `${ISSUE_ICONS.TOO_SMALL} \`${outputPath}\` is **${formatBytes(bytes)}** _(< ${formatBytes(minSize)})_`, + severity: 'warning', + source: { file: outputPath }, + }; +} + +/** + * Creates error issue for blacklisted import pattern match. Enforces dependency restrictions for security and architectural compliance. + */ +export function createBlacklistedIssue( + importPath: string, + outputPath: string, + pattern: string, + hint?: string, +): Issue { + const baseMessage = `${ISSUE_ICONS.BLACKLIST} \`${importPath}\` matches blacklist pattern \`${pattern}\``; + const message = hint ? `${baseMessage} - ${hint}` : baseMessage; + + return { + message, + severity: 'error', + source: { file: outputPath }, + }; +} + +/** + * Validates artifact size against configured thresholds and returns appropriate issues. Ensures bundles stay within acceptable size ranges. + * + * @param outputPath - Path to the output file being checked + * @param output - Output metadata containing size information + * @param minSize - Minimum expected size threshold in bytes (optional) + * @param maxSize - Maximum allowed size threshold in bytes (optional) + * @returns Array of size-related issues found + */ +export function checkSizeIssues( + outputPath: string, + output: UnifiedStatsBundle, + minSize?: number, + maxSize?: number, +): Issue[] { + const outputBytes = output.bytes; + + if (maxSize !== undefined && outputBytes > maxSize) { + return [createTooLargeIssue(outputPath, outputBytes, maxSize)]; + } else if (minSize !== undefined && outputBytes < minSize) { + return [createTooSmallIssue(outputPath, outputBytes, minSize)]; + } + + return []; +} + +/** + * Scans artifact inputs and imports for blacklisted patterns and returns violation issues. + * Enforces dependency restrictions across bundle contents. + * + * Searches for blacklisted paths in these locations: + * 1. Primary File Path Locations: + * - Object keys in the inputs section + * - "path" properties in imports + * - "original" properties in imports (exact import statements as written in source code) + * 2. Entry Point Locations: + * - "entryPoint" properties in chunk/output definitions + * 3. Output File Locations: + * - Output file paths (as object keys) + * 4. Special Path Patterns: + * - Disabled paths with "(disabled):" prefix + * - Runtime paths with "" pattern + * + * @param outputPath - Path to the output file being scanned + * @param output - Output metadata containing inputs and imports + * @param blacklistPatterns - Array of blacklist patterns (strings or objects with hints) + * @returns Array of blacklist-related issues found + */ +export function checkBlacklistIssues( + outputPath: string, + output: UnifiedStatsBundle, + blacklistPatterns: BlacklistPatternList, +): Issue[] { + const issues: Issue[] = []; + + // 1. Check output path itself (object key in outputs section) + const outputPathMatch = matchesBlacklistPattern( + outputPath, + blacklistPatterns, + ); + if (outputPathMatch) { + issues.push( + createBlacklistedIssue( + outputPath, + outputPath, + outputPathMatch.pattern, + outputPathMatch.hint, + ), + ); + } + + // 2. Check entryPoint property + if (output.entryPoint) { + const entryPointMatch = matchesBlacklistPattern( + output.entryPoint, + blacklistPatterns, + ); + if (entryPointMatch) { + issues.push( + createBlacklistedIssue( + output.entryPoint, + outputPath, + entryPointMatch.pattern, + entryPointMatch.hint, + ), + ); + } + } + + // 3. Check input paths (object keys in inputs section) + if (output.inputs) { + for (const inputPath in output.inputs) { + if (!Object.prototype.hasOwnProperty.call(output.inputs, inputPath)) { + continue; + } + const matchedPattern = matchesBlacklistPattern( + inputPath, + blacklistPatterns, + ); + if (matchedPattern) { + issues.push( + createBlacklistedIssue( + inputPath, + outputPath, + matchedPattern.pattern, + matchedPattern.hint, + ), + ); + } + } + } + + // 4. Check import paths and original import statements + if (output.imports) { + for (let i = 0; i < output.imports.length; i++) { + const importInfo = output.imports[i]!; + + // Check resolved import path + const importPathMatch = matchesBlacklistPattern( + importInfo.path, + blacklistPatterns, + ); + if (importPathMatch) { + issues.push( + createBlacklistedIssue( + importInfo.path, + outputPath, + importPathMatch.pattern, + importPathMatch.hint, + ), + ); + } + + // Check original import statement (exact import as written in source code) + if (importInfo.original) { + const originalMatch = matchesBlacklistPattern( + importInfo.original, + blacklistPatterns, + ); + if (originalMatch) { + issues.push( + createBlacklistedIssue( + importInfo.original, + outputPath, + originalMatch.pattern, + originalMatch.hint, + ), + ); + } + } + } + } + + return issues; +} + +/** + * Generates comprehensive diagnostic issues for bundle artifacts including size violations and blacklisted imports. Provides actionable feedback for bundle optimization and dependency management. + * + * @param statsSlice - Unified bundle statistics containing output files and metadata + * @param config - Bundle configuration with penalty options and diagnostic thresholds + * @returns Array of diagnostic issues with severity levels and recommended actions + */ +export function getIssues( + statsSlice: UnifiedStats, + config: BundleStatsConfig, +): Issue[] { + // Clear cache at start of each audit run for clean state + BLACKLIST_PATTERN_CACHE.clear(); + + const issues: Issue[] = []; + const { penalty = false } = config.scoring || { penalty: false }; + + if (!penalty) { + return issues; + } + + const blacklistPatterns = penalty?.blacklist; + const artefactSizeThresholds = penalty?.artefactSize; + + if (!blacklistPatterns?.length && !artefactSizeThresholds) { + return issues; + } + + const minArtifactSize = artefactSizeThresholds?.[0]; + const maxArtifactSize = artefactSizeThresholds?.[1]; + const hasBlacklist = blacklistPatterns && blacklistPatterns.length > 0; + const hasSizeThresholds = + minArtifactSize !== undefined || maxArtifactSize !== undefined; + + // Track unique blacklisted patterns per bundle to avoid duplicates + const blacklistedPatterns = new Map< + string, + { pattern: string; hint?: string; files: string[]; outputPath: string } + >(); + + for (const outputPath in statsSlice) { + if (!Object.prototype.hasOwnProperty.call(statsSlice, outputPath)) { + continue; + } + const output = statsSlice[outputPath]!; + + if (hasSizeThresholds) { + issues.push( + ...checkSizeIssues( + outputPath, + output, + minArtifactSize, + maxArtifactSize, + ), + ); + } + + if (hasBlacklist) { + // Collect blacklisted patterns without creating issues yet + collectBlacklistedPatterns( + outputPath, + output, + blacklistPatterns, + blacklistedPatterns, + ); + } + } + + // Create unique issues for blacklisted patterns + for (const [ + _patternKey, + { pattern, hint, files, outputPath }, + ] of blacklistedPatterns) { + if (files.length === 1) { + // Single file - show specific file name + issues.push(createBlacklistedIssue(files[0]!, outputPath, pattern, hint)); + } else { + // Multiple files - show pattern summary + const summaryMessage = `Blacklisted modules matching \`${pattern}\` included in file`; + issues.push( + createBlacklistedPatternIssue({ + summaryMessage, + outputPath, + pattern, + hint, + }), + ); + } + } + + return issues; +} + +type BlacklistedPatternIssueOptions = { + summaryMessage: string; + outputPath: string; + pattern: string; + hint?: string; +}; + +/** + * Creates error issue for multiple blacklisted files from same pattern. Consolidates multiple violations into single issue. + */ +export function createBlacklistedPatternIssue( + options: BlacklistedPatternIssueOptions, +): Issue { + const { summaryMessage, hint } = options; + const baseMessage = `${ISSUE_ICONS.BLACKLIST} ${summaryMessage}`; + const message = hint ? `${baseMessage} - ${hint}` : baseMessage; + + return { + message, + severity: 'error', + source: { file: options.outputPath }, + }; +} + +/** + * Collects blacklisted patterns without creating duplicate issues. Groups by pattern per bundle. + */ +function collectBlacklistedPatterns( + outputPath: string, + output: UnifiedStatsBundle, + blacklistPatterns: BlacklistPatternList, + blacklistedPatterns: Map< + string, + { pattern: string; hint?: string; files: string[]; outputPath: string } + >, +): void { + const addToPattern = ( + filePath: string, + matchResult: { pattern: string; hint?: string }, + ) => { + const patternKey = `${outputPath}:${matchResult.pattern}`; + if (blacklistedPatterns.has(patternKey)) { + const existing = blacklistedPatterns.get(patternKey)!; + if (!existing.files.includes(filePath)) { + existing.files.push(filePath); + } + } else { + blacklistedPatterns.set(patternKey, { + pattern: matchResult.pattern, + hint: matchResult.hint, + files: [filePath], + outputPath, + }); + } + }; + + // 1. Check output path itself (object key in outputs section) + const outputPathMatch = matchesBlacklistPattern( + outputPath, + blacklistPatterns, + ); + if (outputPathMatch) { + addToPattern(outputPath, outputPathMatch); + } + + // 2. Check entryPoint property + if (output.entryPoint) { + const entryPointMatch = matchesBlacklistPattern( + output.entryPoint, + blacklistPatterns, + ); + if (entryPointMatch) { + addToPattern(output.entryPoint, entryPointMatch); + } + } + + // 3. Check input paths (object keys in inputs section) + if (output.inputs) { + for (const inputPath in output.inputs) { + if (!Object.prototype.hasOwnProperty.call(output.inputs, inputPath)) { + continue; + } + const matchedPattern = matchesBlacklistPattern( + inputPath, + blacklistPatterns, + ); + if (matchedPattern) { + addToPattern(inputPath, matchedPattern); + } + } + } + + // 4. Check import paths and original import statements + if (output.imports) { + for (let i = 0; i < output.imports.length; i++) { + const importInfo = output.imports[i]!; + + // Check resolved import path + const importPathMatch = matchesBlacklistPattern( + importInfo.path, + blacklistPatterns, + ); + if (importPathMatch) { + addToPattern(importInfo.path, importPathMatch); + } + + // Check original import statement (exact import as written in source code) + if (importInfo.original) { + const originalMatch = matchesBlacklistPattern( + importInfo.original, + blacklistPatterns, + ); + if (originalMatch) { + addToPattern(importInfo.original, originalMatch); + } + } + } + } +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.unit.test.ts new file mode 100644 index 0000000..530967c --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.unit.test.ts @@ -0,0 +1,212 @@ +import { describe, expect, it } from 'vitest'; +import { + checkBlacklistIssues, + checkSizeIssues, + createBlacklistedIssue, + createTooLargeIssue, + createTooSmallIssue, + getIssues, +} from './issues.js'; + +describe('createTooLargeIssue', () => { + it('should create error issue for oversized artifact', () => { + expect(createTooLargeIssue('bundle.js', 1_048_576, 500_000)).toStrictEqual({ + severity: 'error', + message: '🔺 `bundle.js` is **1 MB** _(> 488.28 kB)_', + source: { file: 'bundle.js' }, + }); + }); +}); + +describe('createTooSmallIssue', () => { + it('should create warning issue for undersized artifact', () => { + expect(createTooSmallIssue('chunk.js', 512, 2048)).toStrictEqual({ + severity: 'warning', + message: '🔻 `chunk.js` is **512 B** _(< 2 kB)_', + source: { file: 'chunk.js' }, + }); + }); +}); + +describe('createBlacklistedIssue', () => { + it('should create error issue for blacklisted import', () => { + expect( + createBlacklistedIssue('src/math.ts', 'dist/bundle.js', '**/*math*'), + ).toStrictEqual({ + severity: 'error', + message: '🚫 `src/math.ts` matches blacklist pattern `**/*math*`', + source: { file: 'dist/bundle.js' }, + }); + }); +}); + +describe('checkSizeIssues', () => { + it('should return too large issue when file exceeds maxSize', () => { + expect( + checkSizeIssues( + 'big.js', + { path: 'big.js', bytes: 1000 }, + undefined, + 500, + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should return too small issue when file is below minSize', () => { + expect( + checkSizeIssues( + 'small.js', + { path: 'small.js', bytes: 100 }, + 500, + undefined, + ), + ).toStrictEqual([expect.objectContaining({ severity: 'warning' })]); + }); + + it('should return empty array when file is within size range', () => { + expect( + checkSizeIssues('ok.js', { path: 'ok.js', bytes: 750 }, 500, 1000), + ).toStrictEqual([]); + }); +}); + +describe('checkBlacklistIssues', () => { + it('should check output path itself for blacklist patterns', () => { + expect( + checkBlacklistIssues('a.js', { path: 'a.js', bytes: 1 }, ['a*']), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should check output path itself for blacklist patterns with hint', () => { + const issues = checkBlacklistIssues('a.js', { path: 'a.js', bytes: 1 }, [ + { pattern: 'a*', hint: 'Test hint message' }, + ]); + expect(issues).toStrictEqual([ + expect.objectContaining({ + severity: 'error', + message: expect.stringContaining('Test hint message'), + }), + ]); + }); + + it('should check entryPoint property for blacklist patterns', () => { + expect( + checkBlacklistIssues( + 'out.js', + { path: 'out.js', bytes: 1, entryPoint: 'b.js' }, + ['b*'], + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should check input paths for blacklist patterns', () => { + expect( + checkBlacklistIssues( + 'out.js', + { path: 'out.js', bytes: 1, inputs: { 'c.js': { bytes: 1 } } }, + ['c*'], + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should check import resolved paths for blacklist patterns', () => { + expect( + checkBlacklistIssues( + 'out.js', + { + path: 'out.js', + bytes: 1, + imports: [{ path: 'd.js', kind: 'static' }], + }, + ['d*'], + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should check import original statements for blacklist patterns', () => { + expect( + checkBlacklistIssues( + 'out.js', + { + path: 'out.js', + bytes: 1, + imports: [{ path: 'x.js', kind: 'static', original: './e' }], + }, + ['./e*'], + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should return multiple issues when multiple paths match blacklist patterns', () => { + expect( + checkBlacklistIssues( + 'f.js', + { + path: 'f.js', + bytes: 1, + inputs: { 'g.js': { bytes: 1 } }, + imports: [{ path: 'h.js', kind: 'static' }], + }, + ['*'], + ), + ).toStrictEqual([ + expect.objectContaining({ severity: 'error' }), + expect.objectContaining({ severity: 'error' }), + expect.objectContaining({ severity: 'error' }), + ]); + }); + + it('should match disabled paths with (disabled): prefix', () => { + expect( + checkBlacklistIssues( + 'out.js', + { + path: 'out.js', + bytes: 1, + inputs: { '(disabled):i.js': { bytes: 1 } }, + }, + ['*disabled*'], + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); + + it('should match runtime paths with pattern', () => { + expect( + checkBlacklistIssues( + 'out.js', + { + path: 'out.js', + bytes: 1, + imports: [{ path: '', kind: 'static' }], + }, + [''], + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); +}); + +describe('getIssues', () => { + it('should return empty array when no configuration is provided', () => { + expect(getIssues({}, {} as any)).toStrictEqual([]); + }); + + it('should process multiple outputs and return issues', () => { + expect( + getIssues( + { + 'a.js': { path: 'a.js', bytes: 1 }, + 'b.js': { path: 'b.js', bytes: 2 }, + }, + { + title: 'Test', + slug: 'test', + selection: { includeOutputs: ['**/*.js'] }, + scoring: { + totalSize: [0, 1000], + penalty: { blacklist: ['a*'] }, + }, + } as any, + ), + ).toStrictEqual([expect.objectContaining({ severity: 'error' })]); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts new file mode 100644 index 0000000..80a6b94 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts @@ -0,0 +1,47 @@ +/** + * Shared path utilities to avoid circular dependencies between formatting.ts and grouping.ts + */ + +/** + * Splits a path into segments, filtering out empty parts. + */ +export function splitPathSegments(path: string): string[] { + return path.split('/').filter((part) => part !== ''); +} + +/** + * Normalizes a path for pattern matching by removing leading './' and ensuring consistent format. + */ +export function normalizePathForMatching(path: string): string { + return path.replace(/\.\.\//g, '').replace(/^\/+/, ''); +} + +/** + * Extracts concrete (non-wildcard) segments from a glob pattern. + */ +export function extractConcreteSegments(pattern: string): string[] { + return splitPathSegments(pattern).filter( + (segment) => segment !== '**' && segment !== '*' && !segment.includes('*'), + ); +} + +/** + * Finds the index of a specific segment in a file path. + */ +export function findSegmentIndex(filePath: string, segment: string): number { + const segments = splitPathSegments(filePath); + return segments.indexOf(segment); +} + +/** + * Extracts a slice of the path starting from a specific index with a maximum depth. + */ +export function extractPathSlice( + filePath: string, + startIndex: number, + maxDepth: number, +): string { + const segments = splitPathSegments(filePath); + const endIndex = Math.min(startIndex + maxDepth, segments.length); + return segments.slice(startIndex, endIndex).join('/'); +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts new file mode 100644 index 0000000..757666b --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts @@ -0,0 +1,291 @@ +import type { Table } from '@code-pushup/models'; +import { formatBytes } from '@code-pushup/utils'; +import type { GroupingRule } from '../../types.js'; +import type { UnifiedStats } from '../../unify/unified-stats.types.js'; +import { + type GroupData, + createGroupManager, + findOrCreateGroupFromRule, + processForTable, +} from './grouping.js'; + +const DEFAULT_GROUP_NAME = 'Group'; +const REST_GROUP_NAME = 'Rest'; + +// Performance optimizations: Simple pattern cache only +const PATTERN_MATCH_CACHE = new Map< + string, + { rule: GroupingRule | null; groupKey: string | null } +>(); + +export type SharedViewConfig = { + enabled?: boolean; + mode?: 'onlyMatching' | 'all'; +}; + +export type TablePruningConfig = { + enabled?: boolean; + maxChildren?: number; + minSize?: number; +}; + +export type InsightsTableConfig = SharedViewConfig & { + groups: GroupingRule[]; + pruning?: TablePruningConfig; +}; + +/** + * Simplified aggregation with algorithmic optimizations. Eliminates expensive nested operations and redundant pattern matching. + */ +export function aggregateAndSortGroups( + statsSlice: UnifiedStats, + insights: InsightsTableConfig, +): { groups: GroupData[]; restGroup: { title: string; bytes: number } } { + const groupingRules = insights.groups || []; + + // Early exit optimization + if (groupingRules.length === 0) { + const totalBytes = Object.values(statsSlice).reduce( + (acc, { bytes }) => acc + bytes, + 0, + ); + return { + groups: [], + restGroup: { bytes: totalBytes, title: REST_GROUP_NAME }, + }; + } + + const groupManager = createGroupManager(); + PATTERN_MATCH_CACHE.clear(); + + // Pre-create all possible groups to avoid repeated lookups + const preCreatedGroups = new Map(); + for (const rule of groupingRules) { + const effectiveTitle = rule.title || DEFAULT_GROUP_NAME; + const group = findOrCreateGroupFromRule( + groupManager, + effectiveTitle, + rule, + effectiveTitle, + ); + preCreatedGroups.set(effectiveTitle, group); + } + + let totalRestBytes = 0; + const outputEntries = Object.entries(statsSlice); + + // Single-pass processing: collect all inputs first, then process in batch + const inputsToProcess: { + inputPath: string; + inputBytes: number; + outputKey: string; + }[] = []; + + for (const [outputKey, output] of outputEntries) { + totalRestBytes += output.bytes; + + if (output.inputs) { + for (const [inputPath, input] of Object.entries(output.inputs)) { + if (input.bytes > 0) { + inputsToProcess.push({ + inputPath, + inputBytes: input.bytes, + outputKey, + }); + } + } + } + } + + // Process all inputs in single optimized loop with early termination + const outputBytesConsumed = new Map(); + const processedInputs = new Set(); // Track inputs that have been fully consumed + + for (const { inputPath, inputBytes, outputKey } of inputsToProcess) { + // Skip inputs that have already been fully processed by a previous rule + if (processedInputs.has(inputPath)) { + continue; + } + + // Use cached pattern matching + let matchResult = PATTERN_MATCH_CACHE.get(inputPath); + if (!matchResult) { + matchResult = processForTable(inputPath, groupingRules, true); + PATTERN_MATCH_CACHE.set(inputPath, matchResult); + } + + const { rule, groupKey } = matchResult; + if (rule && groupKey) { + // Use pre-created group or create new + let group = preCreatedGroups.get(groupKey); + if (!group) { + group = findOrCreateGroupFromRule( + groupManager, + groupKey, + rule, + rule.title || groupKey, + ); + preCreatedGroups.set(groupKey, group); + } + + group.bytes += inputBytes; + group.modules += 1; + + // Track consumed bytes per output + const consumed = outputBytesConsumed.get(outputKey) || 0; + outputBytesConsumed.set(outputKey, consumed + inputBytes); + totalRestBytes -= inputBytes; + + // Mark input as fully processed - no need to check it against other patterns + processedInputs.add(inputPath); + } + } + + // Process remaining output bytes efficiently, skipping outputs with no remaining bytes + for (const [outputKey, output] of outputEntries) { + const consumedBytes = outputBytesConsumed.get(outputKey) || 0; + const remainingBytes = output.bytes - consumedBytes; + + // Skip outputs that have been fully consumed by input processing + if (remainingBytes <= 0) { + continue; + } + + let matchResult = PATTERN_MATCH_CACHE.get(outputKey); + if (!matchResult) { + matchResult = processForTable(outputKey, groupingRules, true); + PATTERN_MATCH_CACHE.set(outputKey, matchResult); + } + + const { rule, groupKey } = matchResult; + if (rule && groupKey) { + let group = preCreatedGroups.get(groupKey); + if (!group) { + group = findOrCreateGroupFromRule( + groupManager, + groupKey, + rule, + rule.title || groupKey, + ); + preCreatedGroups.set(groupKey, group); + } + group.bytes += remainingBytes; + totalRestBytes -= remainingBytes; + } + } + + const restGroup = { + bytes: Math.max(0, totalRestBytes), + title: REST_GROUP_NAME, + }; + + const groups = groupManager.getGroupsWithData(); + + // Optimized sorting - only sort if we have multiple groups + if (groups.length > 1) { + groups.sort((a, b) => b.bytes - a.bytes); + } + + return { groups, restGroup }; +} + +/** + * Transforms aggregated group data into table format. Creates table rows from group statistics. + */ +export function createTable( + groups: GroupData[], + restGroup: { title: string; bytes: number }, + viewMode: 'onlyMatching' | 'all' = 'onlyMatching', + pruning?: TablePruningConfig, +): Table { + const rows: { group: string; modules: string; size: string }[] = []; + + let processedGroups = groups; + let processedRestGroup = restGroup; + + // Apply pruning if enabled + if (pruning?.enabled) { + const { minSize = 0, maxChildren } = pruning; + + // Filter groups by minimum size + const keptGroups: GroupData[] = []; + const prunedGroups: GroupData[] = []; + + for (const group of groups) { + if (group.bytes >= minSize) { + keptGroups.push(group); + } else { + prunedGroups.push(group); + } + } + + // Apply maxChildren limit + let finalGroups = keptGroups; + if (maxChildren && keptGroups.length > maxChildren) { + finalGroups = keptGroups.slice(0, maxChildren); + const excessGroups = keptGroups.slice(maxChildren); + prunedGroups.push(...excessGroups); + } + + // Add pruned groups to rest + if (prunedGroups.length > 0) { + const prunedBytes = prunedGroups.reduce( + (sum, group) => sum + group.bytes, + 0, + ); + processedRestGroup = { + title: REST_GROUP_NAME, + bytes: restGroup.bytes + prunedBytes, + }; + } + + processedGroups = finalGroups; + } + + for (const group of processedGroups) { + // Apply viewMode filtering + if (viewMode === 'onlyMatching' && group.bytes === 0) { + continue; + } + + rows.push({ + group: group.icon ? `${group.icon} ${group.title}` : group.title, + modules: group.modules.toString(), + size: formatBytes(group.bytes), + }); + } + + // Apply viewMode filtering to rest group + if (processedRestGroup.bytes > 0 || viewMode === 'all') { + rows.push({ + group: 'Rest', + modules: '-', + size: formatBytes(processedRestGroup.bytes), + }); + } + + return { + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows, + }; +} + +/** + * Creates insights table from stats and grouping rules. Combines aggregation and table formatting. + */ +export function createInsightsTable( + statsSlice: UnifiedStats, + insights: InsightsTableConfig, +): Table { + const { groups, restGroup } = aggregateAndSortGroups(statsSlice, insights); + return createTable( + groups, + restGroup, + insights.mode || 'onlyMatching', + insights.pruning, + ); +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.unit.test.ts new file mode 100644 index 0000000..ba91a68 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.unit.test.ts @@ -0,0 +1,470 @@ +import { describe, expect, it } from 'vitest'; +import { aggregateAndSortGroups, createTable } from './table.js'; + +describe('aggregateAndSortGroups', () => { + it('should count input files once across groups', () => { + expect( + aggregateAndSortGroups( + { + 'dist/app.js': { + path: 'dist/app.js', + bytes: 18_000, + inputs: { + 'src/feature-1.ts': { bytes: 8000 }, + 'src/feature-2.ts': { bytes: 10_000 }, + }, + }, + 'dist/utils.js': { + path: 'dist/utils.js', + bytes: 425, + inputs: { + 'src/feature-1.ts': { bytes: 200 }, + 'src/feature-2.ts': { bytes: 225 }, + }, + }, + }, + { + groups: [ + { + title: 'Feature 2', + includeInputs: ['**/feature-2.ts'], + }, + { + title: 'Feature *', + includeInputs: ['**/feature-*.ts'], + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Feature 2', + bytes: 10_000, + icon: undefined, + modules: 1, + type: 'group', + }, + { + title: 'Feature *', + bytes: 8000, + icon: undefined, + modules: 1, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 425 }, + }); + }); + + it('should include output file bytes when output path matches pattern', () => { + expect( + aggregateAndSortGroups( + { + 'dist/feature-2.js': { + path: 'dist/feature-2.js', + bytes: 12_000, + inputs: { + 'src/feature-2.ts': { bytes: 10_000 }, + }, + }, + }, + { + groups: [ + { + title: 'Feature 2', + includeInputs: ['**/feature-2.js'], + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Feature 2', + bytes: 12_000, + icon: undefined, + modules: 0, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 0 }, + }); + }); + + it('should assign unmatched bytes to Rest group', () => { + expect( + aggregateAndSortGroups( + { + 'dist/app.js': { + path: 'dist/app.js', + bytes: 20_000, + inputs: { + 'src/feature-1.ts': { bytes: 8000 }, + 'src/feature-2.ts': { bytes: 8000 }, + }, + }, + }, + { + groups: [ + { + title: 'Feature 2', + includeInputs: ['**/feature-2.ts'], + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Feature 2', + bytes: 8000, + icon: undefined, + modules: 1, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 12_000 }, + }); + }); + + it('should include bundler overhead in Rest group', () => { + expect( + aggregateAndSortGroups( + { + 'dist/feature-2.js': { + path: 'dist/feature-2.js', + bytes: 12_000, + inputs: { + 'src/feature-2.ts': { bytes: 10_000 }, + }, + }, + }, + { + groups: [ + { + title: 'Feature 2', + includeInputs: ['**/feature-2.ts'], + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Feature 2', + bytes: 10_000, + icon: undefined, + modules: 1, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 2000 }, + }); + }); + + it('should format bytes in human readable format', () => { + expect( + aggregateAndSortGroups( + { + 'dist/app.js': { + path: 'dist/app.js', + bytes: 10_100, + inputs: { + 'src/feature.ts': { bytes: 8100 }, + }, + }, + }, + { + groups: [ + { + title: 'Feature', + includeInputs: ['**/feature.ts'], + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Feature', + bytes: 8100, + icon: undefined, + modules: 1, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 2000 }, + }); + }); + + it('should handle include/exclude patterns', () => { + expect( + aggregateAndSortGroups( + { + 'dist/app.js': { + path: 'dist/app.js', + bytes: 25_000, + inputs: { + 'src/index.ts': { bytes: 5000 }, + 'src/feature-1.ts': { bytes: 10_000 }, + 'src/feature-2.ts': { bytes: 7500 }, + 'src/utils/format.ts': { bytes: 2500 }, + }, + }, + }, + { + groups: [ + { + title: 'Application Code', + includeInputs: '**/src/**', + excludeInputs: ['**/utils/**', '**/*.spec.ts'], + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Application Code', + bytes: 22_500, // 5000 + 10000 + 7500 (excluding utils) + icon: undefined, + modules: 3, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 2500 }, // 2500 from utils + any bundler overhead + }); + }); + + it('should handle multiple groups with icons', () => { + expect( + aggregateAndSortGroups( + { + 'dist/app.js': { + path: 'dist/app.js', + bytes: 50_000, + inputs: { + 'src/feature-1.ts': { bytes: 10_000 }, + 'src/utils/format.ts': { bytes: 5000 }, + 'node_modules/lodash/index.js': { bytes: 15_000 }, + }, + }, + }, + { + groups: [ + { + title: 'Features', + includeInputs: '**/feature-*.ts', + icon: '🎯', + }, + { + title: 'Utilities', + includeInputs: '**/utils/**', + icon: '🔧', + }, + { + title: 'Dependencies', + includeInputs: 'node_modules/**', + icon: '📦', + }, + ], + }, + ), + ).toStrictEqual({ + groups: [ + { + title: 'Dependencies', + bytes: 15_000, + icon: '📦', + modules: 1, + type: 'group', + }, + { + title: 'Features', + bytes: 10_000, + icon: '🎯', + modules: 1, + type: 'group', + }, + { + title: 'Utilities', + bytes: 5000, + icon: '🔧', + modules: 1, + type: 'group', + }, + ], + restGroup: { title: 'Rest', bytes: 20_000 }, + }); + }); +}); + +describe('createTable', () => { + it('should add icon to group title', () => { + expect( + createTable( + [ + { + title: 'Feature', + bytes: 10_000, + icon: '📁', + modules: 0, + type: 'group', + }, + ], + { title: 'Rest', bytes: 0 }, + ), + ).toStrictEqual({ + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows: [{ group: '📁 Feature', modules: '0', size: '9.77 kB' }], + }); + }); + + it('should handle groups without icons', () => { + expect( + createTable( + [ + { + title: 'Feature', + bytes: 10_000, + modules: 2, + type: 'group', + }, + ], + { title: 'Rest', bytes: 1000 }, + ), + ).toStrictEqual({ + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows: [ + { group: 'Feature', modules: '2', size: '9.77 kB' }, + { group: 'Rest', modules: '-', size: '1000 B' }, + ], + }); + }); + + it('should handle onlyMatching mode by filtering zero-byte groups', () => { + expect( + createTable( + [ + { + title: 'Feature 1', + bytes: 10_000, + modules: 1, + type: 'group', + }, + { + title: 'Feature 2', + bytes: 0, + modules: 0, + type: 'group', + }, + ], + { title: 'Rest', bytes: 0 }, + 'onlyMatching', + ), + ).toStrictEqual({ + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows: [{ group: 'Feature 1', modules: '1', size: '9.77 kB' }], + }); + }); + + it('should show all groups in all mode including zero-byte groups', () => { + expect( + createTable( + [ + { + title: 'Feature 1', + bytes: 10_000, + modules: 1, + type: 'group', + }, + { + title: 'Feature 2', + bytes: 0, + modules: 0, + type: 'group', + }, + ], + { title: 'Rest', bytes: 5000 }, + 'all', + ), + ).toStrictEqual({ + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows: [ + { group: 'Feature 1', modules: '1', size: '9.77 kB' }, + { group: 'Feature 2', modules: '0', size: '0 B' }, + { group: 'Rest', modules: '-', size: '4.88 kB' }, + ], + }); + }); + + it('should apply pruning with maxChildren', () => { + expect( + createTable( + [ + { title: 'Feature 1', bytes: 10_000, modules: 1, type: 'group' }, + { title: 'Feature 2', bytes: 8000, modules: 1, type: 'group' }, + { title: 'Feature 3', bytes: 6000, modules: 1, type: 'group' }, + { title: 'Feature 4', bytes: 4000, modules: 1, type: 'group' }, + ], + { title: 'Rest', bytes: 2000 }, + 'all', + { enabled: true, maxChildren: 2 }, + ), + ).toStrictEqual({ + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows: [ + { group: 'Feature 1', modules: '1', size: '9.77 kB' }, + { group: 'Feature 2', modules: '1', size: '7.81 kB' }, + { group: 'Rest', modules: '-', size: '11.72 kB' }, // 6000 + 4000 + 2000 + ], + }); + }); + + it('should apply pruning with minSize', () => { + expect( + createTable( + [ + { title: 'Large Feature', bytes: 50_000, modules: 1, type: 'group' }, + { title: 'Medium Feature', bytes: 30_000, modules: 1, type: 'group' }, + { title: 'Small Feature', bytes: 5000, modules: 1, type: 'group' }, + ], + { title: 'Rest', bytes: 1000 }, + 'all', + { enabled: true, minSize: 25_000 }, + ), + ).toStrictEqual({ + columns: [ + { key: 'group', label: 'Group', align: 'left' }, + { key: 'modules', label: 'Modules', align: 'right' }, + { key: 'size', label: 'Size', align: 'right' }, + ], + rows: [ + { group: 'Large Feature', modules: '1', size: '48.83 kB' }, + { group: 'Medium Feature', modules: '1', size: '29.3 kB' }, + { group: 'Rest', modules: '-', size: '5.86 kB' }, // 5000 + 1000 + ], + }); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.ts new file mode 100644 index 0000000..fa0d051 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.ts @@ -0,0 +1,387 @@ +import type { BasicTree, BasicTreeNode } from '@code-pushup/models'; +import { formatBytes, pluralizeToken, truncateText } from '@code-pushup/utils'; +import type { GroupingRule } from '../../types.js'; +import type { UnifiedStats } from '../../unify/unified-stats.types'; +import type { SelectionConfig } from '../selection.js'; +import { + type StatsTreeNode, + applyGrouping as applyGroupingAndSort, +} from './grouping.js'; +import type { SharedViewConfig } from './table.js'; +import type { StatsNodeValues } from './types.js'; + +/** + * Helper type that transforms picked properties by adding "Display" suffix and making them strings. + */ +export type AddDisplaySuffix = { + [K in keyof T as `${string & K}Display`]: string; +}; + +/** + * Display values for StatsTreeNode with formatted strings. + */ +export type StatsTreeNodeDisplayValues = AddDisplaySuffix< + Pick +>; + +export type FormattedStatsTreeNode = { + name: string; + values?: Record; + children: FormattedStatsTreeNode[]; +}; + +/** + * Display tree structure for bundle statistics output. + */ +export type FormattedStatsTree = { + root: FormattedStatsTreeNode; +}; + +export const DEFAULT_PATH_LENGTH = 40; + +// Simple performance optimization: single cache for formatted strings +const STRING_FORMAT_CACHE = new Map(); + +export type DependencyTreeConfig = { + groups?: GroupingRule[] | false; + pruning?: PruningConfig; +} & SharedViewConfig; + +export type PruningConfig = { + enabled?: boolean; + maxChildren?: number; + maxDepth?: number; + minSize?: number; + pathLength?: number | false; +}; + +export type PruneTreeNode = { + children: StatsTreeNode[]; +}; + +/** + * Converts statistics to tree structure. Streamlined for speed. + */ +export function convertStatsToTree(stats: UnifiedStats): StatsTreeNode[] { + const artifacts = Object.values(stats); + const result: StatsTreeNode[] = []; + + for (const artefact of artifacts) { + const isEntry = Boolean(artefact.entryPoint); + let inputNodes: StatsTreeNode[] = []; + + if (artefact.inputs) { + const validInputs: StatsTreeNode[] = []; + + for (const [path, input] of Object.entries(artefact.inputs)) { + if (input.bytes > 0) { + validInputs.push({ + name: path, + values: { + path, + bytes: input.bytes, + modules: 1, + type: 'static-import', + }, + children: [], + }); + } + } + + if (validInputs.length > 1) { + validInputs.sort((a, b) => b.values.bytes - a.values.bytes); + } + inputNodes = validInputs; + } + + result.push({ + name: artefact.path, + values: { + path: artefact.path, + bytes: artefact.bytes, + modules: inputNodes.length, + type: isEntry ? 'entry-file' : 'static-import', + }, + children: inputNodes, + }); + } + + if (result.length > 1) { + result.sort((a, b) => b.values.bytes - a.values.bytes); + } + + return result; +} + +/** + * Flattens single-child groups to reduce hierarchy and applies group icons to actual files. + */ +function flattenSingleChildGroups(nodes: StatsTreeNode[]): StatsTreeNode[] { + return nodes.map((node) => { + // If this is a group with exactly one child, flatten it + if (node.values.type === 'group' && node.children.length === 1) { + const child = node.children[0]!; + + // Use the group's icon for the child file if the group has an icon + return { + ...child, + values: { + ...child.values, + icon: node.values.icon, // Use group icon only if it exists + }, + children: flattenSingleChildGroups(child.children), // Recursively flatten children + }; + } + + // For other nodes, just recursively process children + return { + ...node, + children: flattenSingleChildGroups(node.children), + }; + }); +} + +/** + * Formats tree nodes with clean names and separate values for proper alignment. + */ +export function formatStatsTreeForDisplay( + node: StatsTreeNode, + pathLength: number | false = DEFAULT_PATH_LENGTH, +): FormattedStatsTreeNode { + const maxChars = pathLength === false ? DEFAULT_PATH_LENGTH : pathLength; + + // Clean name truncation (no icons or size info) + const cleanName = + maxChars < node.name.length + ? truncateText(node.name, { maxChars, position: 'middle' }) + : node.name; + + // Use only explicitly configured icons + const icon = node.values.icon; + + // Recurse through children (keep it simple - recursion is fast in JS) + const children = node.children.map((child) => + formatStatsTreeForDisplay(child, pathLength), + ); + + const values: Record = {}; + + // Show size for all nodes except intermediate nodes in single-child chains + // This means: entry files, groups with multiple children, and leaf files all show size + if (node.children.length !== 1) { + values['size'] = formatBytes(node.values.bytes); + } + + // Only show source count if more than 1 source + if (node.values.modules > 1) { + // For "..." groups that represent multiple files, show "files" instead of "sources" + const token = node.name === '...' ? 'file' : 'module'; + values['modules'] = pluralizeToken(token, node.values.modules); + } + + return { + name: icon ? `${icon} ${cleanName}` : cleanName, + values, + children, + }; +} + +/** + * Converts FormattedStatsTreeNode to BasicTreeNode for proper ASCII display. + */ +function formattedStatsTreeNodeToBasicTreeNode( + node: FormattedStatsTreeNode, +): BasicTreeNode { + return { + name: node.name, + ...(node.values && { values: node.values }), + ...(node.children.length > 0 && { + children: node.children.map(formattedStatsTreeNodeToBasicTreeNode), + }), + }; +} + +/** + * Creates artifact tree with focused optimizations. + */ +export function createTree( + statsSlice: UnifiedStats, + options: { + title: string; + selection?: SelectionConfig; + } & DependencyTreeConfig, +): BasicTree { + const { title, groups, pruning, mode } = options; + + // Simple cache management + if (STRING_FORMAT_CACHE.size > 25_000) { + STRING_FORMAT_CACHE.clear(); + } + + let nodes = convertStatsToTree(statsSlice); + + // Apply grouping if needed + if (Array.isArray(groups) && groups.length > 0 && nodes.length > 0) { + // Apply grouping only to inputs (children) within each output file + // Don't group the output files themselves + for (const node of nodes) { + if (node.children.length > 0) { + node.children = applyGroupingAndSort(node.children, groups); + } + } + + // Flatten single-child groups after applying grouping + nodes = flattenSingleChildGroups(nodes); + } + + // Apply onlyMatching mode filtering - hide files with no matching inputs + if (mode === 'onlyMatching') { + nodes = nodes.filter((node) => node.children.length > 0); + } + + // Apply pruning only if explicitly configured and enabled + let prunedNodes: StatsTreeNode[]; + if (pruning && pruning.enabled !== false) { + const prunedRoot = pruneTree({ children: nodes }, pruning); + prunedNodes = prunedRoot.children; + } else { + // No pruning - show all nodes + prunedNodes = nodes; + } + + // Calculate totals + let totalBytes = 0; + let totalModules = 0; + for (const node of prunedNodes) { + totalBytes += node.values.bytes; + totalModules += node.values.modules; + } + + // Format nodes + const formattedChildren = prunedNodes.map((node) => + formatStatsTreeForDisplay(node, pruning?.pathLength), + ); + + const formattedRoot: FormattedStatsTreeNode = { + name: title, + values: { + 'total size': formatBytes(totalBytes), + ...(totalModules > 1 && { 'total modules': totalModules }), + files: prunedNodes.length, + }, + children: formattedChildren, + }; + + // Convert to BasicTree for proper ASCII display + const root = formattedStatsTreeNodeToBasicTreeNode(formattedRoot); + + return { + type: 'basic', + title, + root, + }; +} + +export function pruneTree( + rootNode: PruneTreeNode, + options: PruningConfig, +): PruneTreeNode { + // Provide defaults for all required properties + const completeOptions: Required = { + maxDepth: options.maxDepth ?? 999, + maxChildren: options.maxChildren ?? 999, + minSize: options.minSize ?? 0, + pathLength: options.pathLength ?? 999, + enabled: options.enabled ?? true, + }; + + // Start from 1 so that maxDepth: 2 stops at package level, maxDepth: 3 shows individual files + return pruneTreeRecursive(rootNode, completeOptions, 1); +} + +function pruneTreeRecursive( + node: PruneTreeNode, + options: Required, + currentDepth: number, +): PruneTreeNode { + const { maxChildren, maxDepth, minSize } = options; + + if (node.children.length === 0) { + return node; + } + + // Sort children by size (largest first) + if (node.children.length > 1) { + node.children.sort((a, b) => b.values.bytes - a.values.bytes); + } + + // Apply maxChildren and minSize filtering at all levels within maxDepth + const keptChildren: StatsTreeNode[] = []; + const groupedChildren: StatsTreeNode[] = []; + + for (const child of node.children) { + if (child.values.bytes >= minSize) { + // Recursively prune child's subtree if within maxDepth + const prunedChild = + currentDepth < maxDepth + ? pruneTreeRecursive( + { children: child.children }, + options, + currentDepth + 1, + ) + : { children: [] }; + + keptChildren.push({ + ...child, + children: prunedChild.children, + }); + } else { + // Collect small files for grouping + groupedChildren.push(child); + } + } + + // Apply maxChildren limit - move overflow to grouped items + let finalChildren = keptChildren; + if (keptChildren.length > maxChildren) { + const kept = keptChildren.slice(0, maxChildren); + const overflow = keptChildren.slice(maxChildren); + + // Add overflow files to the grouped items + groupedChildren.push(...overflow); + finalChildren = kept; + } + + // Create "..." group if we have multiple items to represent, or show single item directly + if (groupedChildren.length > 0) { + if (groupedChildren.length === 1) { + // If there's only one grouped item, show it directly instead of creating "..." group + finalChildren.push(groupedChildren[0]!); + } else { + // Multiple items - create "..." group + const totalBytes = groupedChildren.reduce( + (sum, child) => sum + child.values.bytes, + 0, + ); + const totalModules = groupedChildren.reduce( + (sum, child) => sum + child.values.modules, + 0, + ); + + const moreNode = { + name: '...', + values: { + path: '', + bytes: totalBytes, + modules: totalModules, + type: 'group' as const, + }, + children: [], // Empty - just represents the grouped items + }; + + finalChildren.push(moreNode); + } + } + + return { children: finalChildren }; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.unit.test.ts new file mode 100644 index 0000000..083697b --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.unit.test.ts @@ -0,0 +1,756 @@ +import { describe, expect, it } from 'vitest'; +import { type StatsTreeNode, applyGrouping } from './grouping.js'; + +describe('applyGrouping', () => { + it('should group inputs by single pattern', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'dist/output.js', + values: { + path: 'dist/output.js', + bytes: 200, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils.ts', + values: { + path: 'src/utils.ts', + bytes: 50, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { includeInputs: ['src/**'], title: 'Source Files' }, + ]), + ).toStrictEqual([ + { + name: 'dist/output.js', + values: { + path: 'dist/output.js', + bytes: 200, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'Source Files', + values: { + path: '', + bytes: 150, + modules: 2, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils.ts', + values: { + path: 'src/utils.ts', + bytes: 50, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should group inputs by multiple patterns', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'src/components/Button.tsx', + values: { + path: 'src/components/Button.tsx', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils/helper.ts', + values: { + path: 'src/utils/helper.ts', + bytes: 40, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'tests/unit.test.ts', + values: { + path: 'tests/unit.test.ts', + bytes: 60, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { includeInputs: ['src/**', 'tests/**'], title: 'Project Files' }, + ]), + ).toStrictEqual([ + { + name: 'Project Files', + values: { + bytes: 180, + modules: 3, + type: 'group', + path: '', + icon: undefined, + }, + children: [ + { + name: 'src/components/Button.tsx', + values: { + bytes: 80, + modules: 1, + type: 'static-import', + path: 'src/components/Button.tsx', + }, + children: [], + }, + { + name: 'tests/unit.test.ts', + values: { + bytes: 60, + modules: 1, + type: 'static-import', + path: 'tests/unit.test.ts', + }, + children: [], + }, + { + name: 'src/utils/helper.ts', + values: { + bytes: 40, + modules: 1, + type: 'static-import', + path: 'src/utils/helper.ts', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should group inputs with include/exclude patterns', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'src/components/Button.tsx', + values: { + path: 'src/components/Button.tsx', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/components/Button.test.tsx', + values: { + path: 'src/components/Button.test.tsx', + bytes: 40, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils/helper.ts', + values: { + path: 'src/utils/helper.ts', + bytes: 60, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { + title: 'Source Code', + includeInputs: ['src/**'], + excludeInputs: ['**/*.test.*'], + }, + ]), + ).toStrictEqual([ + { + name: 'Source Code', + values: { + path: '', + bytes: 140, + modules: 2, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'src/components/Button.tsx', + values: { + path: 'src/components/Button.tsx', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils/helper.ts', + values: { + path: 'src/utils/helper.ts', + bytes: 60, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should group inputs with numSegments', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'node_modules/react/index.js', + values: { + path: 'node_modules/react/index.js', + bytes: 120, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'node_modules/lodash/core.js', + values: { + path: 'node_modules/lodash/core.js', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { includeInputs: ['node_modules/**'], numSegments: 2 }, + ]), + ).toStrictEqual([ + { + name: 'react', + values: { + path: 'node_modules/react', + bytes: 120, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'node_modules/react/index.js', + values: { + path: 'node_modules/react/index.js', + bytes: 120, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + { + name: 'lodash', + values: { + path: 'node_modules/lodash', + bytes: 80, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'node_modules/lodash/core.js', + values: { + path: 'node_modules/lodash/core.js', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should add icons to nodes', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [{ includeInputs: ['src/**'], icon: '📦' }]), + ).toStrictEqual([ + { + name: 'Group', + values: { + path: '', + bytes: 100, + modules: 1, + type: 'group', + icon: '📦', + }, + children: [ + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should add title to nodes', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { includeInputs: ['src/**'], title: 'Source Code' }, + ]), + ).toStrictEqual([ + { + name: 'Source Code', + values: { + path: '', + bytes: 100, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should autoderive title from patterns', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'node_modules/react/index.js', + values: { + path: 'node_modules/react/index.js', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [{ includeInputs: ['node_modules/**'] }]), + ).toStrictEqual([ + { + name: 'react', + values: { + path: '', + bytes: 100, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'node_modules/react/index.js', + values: { + path: 'node_modules/react/index.js', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should separate packages into different groups with numSegments', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'packages/design-system/ui/button/src/button.component.ts', + values: { + path: 'packages/design-system/ui/button/src/button.component.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'packages/vanilla/lib/core/services/service.ts', + values: { + path: 'packages/vanilla/lib/core/services/service.ts', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'packages/themepark/components/theme.ts', + values: { + path: 'packages/themepark/components/theme.ts', + bytes: 60, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { includeInputs: ['packages/**'], numSegments: 2 }, + ]), + ).toStrictEqual([ + { + name: 'design-system', + values: { + path: 'packages/design-system', + bytes: 100, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'packages/design-system/ui/button/src/button.component.ts', + values: { + path: 'packages/design-system/ui/button/src/button.component.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + { + name: 'vanilla', + values: { + path: 'packages/vanilla', + bytes: 80, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'packages/vanilla/lib/core/services/service.ts', + values: { + path: 'packages/vanilla/lib/core/services/service.ts', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + { + name: 'themepark', + values: { + path: 'packages/themepark', + bytes: 60, + modules: 1, + type: 'group', + icon: undefined, + }, + children: [ + { + name: 'packages/themepark/components/theme.ts', + values: { + path: 'packages/themepark/components/theme.ts', + bytes: 60, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should handle complex include/exclude combinations', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'src/components/Button.tsx', + values: { + path: 'src/components/Button.tsx', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/components/Button.test.tsx', + values: { + path: 'src/components/Button.test.tsx', + bytes: 40, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/components/Modal.spec.tsx', + values: { + path: 'src/components/Modal.spec.tsx', + bytes: 30, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'node_modules/react/index.js', + values: { + path: 'node_modules/react/index.js', + bytes: 200, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { + title: 'Source Code', + includeInputs: ['src/**'], + excludeInputs: ['**/*.test.*', '**/*.spec.*'], + icon: '📦', + }, + { + title: 'Dependencies', + includeInputs: ['node_modules/**'], + icon: '🔗', + }, + ]), + ).toStrictEqual([ + { + name: 'Dependencies', + values: { + path: '', + bytes: 200, + modules: 1, + type: 'group', + icon: '🔗', + }, + children: [ + { + name: 'node_modules/react/index.js', + values: { + path: 'node_modules/react/index.js', + bytes: 200, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + { + name: 'Source Code', + values: { + path: '', + bytes: 80, + modules: 1, + type: 'group', + icon: '📦', + }, + children: [ + { + name: 'src/components/Button.tsx', + values: { + path: 'src/components/Button.tsx', + bytes: 80, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); + + it('should group inputs by multiple patterns with icons', () => { + const nodes: StatsTreeNode[] = [ + { + name: 'dist/output.js', + values: { + path: 'dist/output.js', + bytes: 300, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils.ts', + values: { + path: 'src/utils.ts', + bytes: 50, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ]; + + expect( + applyGrouping(nodes, [ + { + includeInputs: ['src/main.ts', 'src/utils.ts'], + title: 'Source Files', + icon: '📄', + }, + ]), + ).toStrictEqual([ + { + name: 'dist/output.js', + values: { + path: 'dist/output.js', + bytes: 300, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'Source Files', + values: { + path: '', + bytes: 150, + modules: 2, + type: 'group', + icon: '📄', + }, + children: [ + { + name: 'src/main.ts', + values: { + path: 'src/main.ts', + bytes: 100, + modules: 1, + type: 'static-import', + }, + children: [], + }, + { + name: 'src/utils.ts', + values: { + path: 'src/utils.ts', + bytes: 50, + modules: 1, + type: 'static-import', + }, + children: [], + }, + ], + }, + ]); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/types.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/types.ts new file mode 100644 index 0000000..a06ccde --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/types.ts @@ -0,0 +1,9 @@ +export type ArtefactType = 'root' | 'entry-file' | 'static-import' | 'group'; + +export type StatsNodeValues = { + path: string; + bytes: number; + modules: number; + type: ArtefactType; + icon?: string; +}; diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/scoring.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/scoring.ts new file mode 100644 index 0000000..040304c --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/scoring.ts @@ -0,0 +1,208 @@ +import type { Issue } from '@code-pushup/models'; +import type { MinMax } from '../types.js'; + +export type BlacklistPatternList = readonly BlacklistEntry[]; +export type BlacklistEntry = + | string + | { + pattern: string; + hint?: string; + }; + +export type PenaltyConfig = { + enabled?: boolean; + artefactSize?: [number, number]; + warningWeight?: number; + errorWeight?: number; + /** + * glob patterns when matching get penalised + * e.g. packagenames outdates, should be lazy loaded, etc. + * Can be simple strings or objects with pattern and optional hint + */ + blacklist?: BlacklistPatternList; +}; + +export type ScoringConfig = { + mode: 'off' | 'matchingWithStaticImports' | 'onlyMatching'; + totalSize?: MinMax; + penalty?: false | PenaltyConfig; +}; + +export type ScoreCalculator = (value: number, issues: Issue[]) => number; + +export const DEFAULT_PENALTY: PenaltyConfig = { + warningWeight: 0.1, + errorWeight: 0.2, +}; + +/** + * Calculates normalized penalty score from issues using provided penalty options. Legacy function for backward compatibility. + * + * ## Penalty Parameters + * - **E**: Count of issues of severity errors (🚨) + * - **W**: Count of issues of severity warnings (⚠️) + * - **we**: Weight per error issue (default 0.2) + * - **ww**: Weight per warning issue (default 0.1) + * + * ## Default Penalty Options + * When penalty options are not provided, these defaults are used: + * - **errorWeight**: 0.2 + * - **warningWeight**: 0.1 + * + * ## Issues Penalty Formula + * ``` + * penalty = we × E + ww × W + * normalizedPenalty = penalty / (we + ww) + * ``` + * + * @param issues - Array of diagnostic issues with severity levels + * @param penalty - Penalty configuration with error and warning weights + * @returns Normalized penalty score (0-1) based on issue counts and weights + */ +export function calculatePenalty( + issues: Issue[], + penalty?: PenaltyConfig, +): number { + const errorWeight = penalty?.errorWeight ?? 0.2; + const warningWeight = penalty?.warningWeight ?? 0.1; + + let errorCount = 0; + let warningCount = 0; + + for (const issue of issues) { + if (issue.severity === 'error') { + errorCount++; + } else if (issue.severity === 'warning') { + warningCount++; + } + } + + const penaltyValue = errorWeight * errorCount + warningWeight * warningCount; + const totalWeight = errorWeight + warningWeight; + + return totalWeight > 0 ? penaltyValue / totalWeight : 0; +} + +/** + * Creates a score calculator function configured with bundle settings. Applies direct penalty subtraction for intuitive scoring behavior with a maximum penalty cap of 20%. + * + * ## Scoring + * Assigns a score in the range [0 … 1] to each artefact (or artefact selection) based on: + * - Size vs. configurable minimum and maximum thresholds (if totalSize provided, otherwise defaults to 100%) + * - Direct penalty subtraction based on issue severity levels (when enabled) + * - Penalty is capped at maximum 20% of the size score + * + * A perfect score (1) means "within acceptable range"; lower values indicate regressions. + * + * ## Size Parameters + * - **S**: Actual bytes + * - **Min**: Minimum threshold bytes (lower bound) + * - **Max**: Maximum threshold bytes (upper bound) + * + * ## Size Score Formula + * When totalSize is not provided: + * ``` + * sizeScore = 1 (100%) + * ``` + * + * For single threshold (number): + * ``` + * sizeScore = { + * 1, if S ≤ threshold + * 0, if S > threshold + * } + * ``` + * + * For range thresholds [Min, Max]: + * ``` + * sizeScore = { + * max(0, S/Min), if S < Min (penalize under-sized bundles) + * 1, if Min ≤ S ≤ Max (perfect score) + * 0, if S > Max (too big = score 0) + * } + * ``` + * + * ## Penalty Calculation + * Direct subtraction approach with 20% maximum penalty cap: + * ``` + * penaltyShift = errors × errorWeight + warnings × warningWeight + * cappedPenalty = min(penaltyShift, sizeScore × 0.2) + * ``` + * Default weights: errorWeight = 0.2, warningWeight = 0.1 + * + * ## Final Score Calculation + * ``` + * finalScore = max(0, sizeScore - cappedPenalty) + * ``` + * This creates a penalty shift pattern where issues directly reduce the score by their weight values, + * but the total penalty reduction is capped at 20% of the original size score. + * Note: When `penalty` is `false` or undefined, only size score is used. + * + * @param options - Scoring configuration containing optional thresholds and penalty weights + * @returns Score calculator function that takes (value, issues) and returns score [0-1] + */ +export function createBundleStatsScoring( + options: ScoringConfig, +): ScoreCalculator { + const { totalSize, penalty } = options; + + return (value: number, issues: Issue[] = []): number => { + let sizeScore: number; + + if (!totalSize) { + // No size constraints - default to perfect score (100%) + sizeScore = 1; + } else if (Array.isArray(totalSize)) { + // Range thresholds [min, max] + const [minThreshold, maxThreshold] = totalSize; + + if (value < minThreshold) { + sizeScore = Math.max(0, value / minThreshold); + } else if (value <= maxThreshold) { + sizeScore = 1; + } else { + sizeScore = 0; + } + } else { + sizeScore = value <= totalSize ? 1 : 0; + } + + if (penalty === false || penalty === undefined || issues.length === 0) { + return sizeScore; + } + + const penaltyOptions = penalty || DEFAULT_PENALTY; + const penaltyShift = calculatePenaltyShift(issues, penaltyOptions); + + // Cap penalty at maximum 20% of the size score + const maxPenalty = sizeScore * 0.2; + const cappedPenalty = Math.min(penaltyShift, maxPenalty); + + return Math.max(0, sizeScore - cappedPenalty); + }; +} + +/** + * Calculates direct penalty shift based on issue counts and weights. Creates intuitive score reduction where each issue subtracts its weight from the final score. + * + * @param issues - Array of diagnostic issues with severity levels + * @param options - Penalty configuration with error and warning weights + * @returns Direct penalty shift value to subtract from size score + */ +function calculatePenaltyShift( + issues: Issue[], + options: PenaltyConfig, +): number { + const errorCount = issues.filter( + (issue) => issue.severity === 'error', + ).length; + const warningCount = issues.filter( + (issue) => issue.severity === 'warning', + ).length; + + const errorWeight = options.errorWeight ?? 0.2; + const warningWeight = options.warningWeight ?? 0.1; + + // Direct penalty: each error/warning reduces score by its weight + return errorCount * errorWeight + warningCount * warningWeight; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/selection.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/selection.ts new file mode 100644 index 0000000..9fdde4e --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/selection.ts @@ -0,0 +1,308 @@ +import type { + UnifiedStats, + UnifiedStatsBundle, +} from '../unify/unified-stats.types.js'; +import { type PatternMatcher, compilePattern } from './details/grouping.js'; + +export type SelectionOutputsConfig = { + includeOutputs: string[]; + excludeOutputs: string[]; +}; + +export type SelectionInputsConfig = { + includeInputs: string[]; + excludeInputs: string[]; +}; + +export type SelectionMode = + | 'matchingOnly' + | 'bundle' + | 'withStartupDeps' + | 'withAllDeps'; + +export type SelectionConfig = { + mode: SelectionMode; +} & SelectionOutputsConfig & + SelectionInputsConfig; + +export type CompiledPatterns = { + includeOutputs: PatternMatcher[]; + excludeOutputs: PatternMatcher[]; + includeInputs: PatternMatcher[]; + excludeInputs: PatternMatcher[]; +}; + +function compilePatterns(patterns: string[]): PatternMatcher[] { + return patterns.map((pattern) => + compilePattern(pattern, { normalizeRelativePaths: true }), + ); +} + +function matchesAnyPattern(path: string, patterns: PatternMatcher[]): boolean { + for (const pattern of patterns) { + if (pattern(path)) { + return true; + } // Early exit on first match + } + return false; +} + +function* getInputPaths(bundle: UnifiedStatsBundle): Generator { + if (!bundle.inputs) { + return; + } + for (const path of Object.keys(bundle.inputs)) { + yield path; + } +} + +function hasInputMatchingPatterns( + bundle: UnifiedStatsBundle, + patterns: PatternMatcher[], +): boolean { + if (patterns.length === 0) { + return false; + } + for (const path of getInputPaths(bundle)) { + if (matchesAnyPattern(path, patterns)) { + return true; + } // Stop on first match + } + return false; +} + +// Mode-specific processors for optimized selection +const bundleSelectors = { + matchingOnly: ( + bundle: UnifiedStatsBundle, + patterns: CompiledPatterns, + ): boolean => + patterns.includeInputs.length > 0 && + hasInputMatchingPatterns(bundle, patterns.includeInputs), + + bundle: (bundle: UnifiedStatsBundle, patterns: CompiledPatterns): boolean => { + const hasIncludePatterns = + patterns.includeOutputs.length > 0 || patterns.includeInputs.length > 0; + if (!hasIncludePatterns) { + return false; + } + + // Check output patterns + if ( + patterns.includeOutputs.length > 0 && + !matchesAnyPattern(bundle.path, patterns.includeOutputs) + ) { + return false; + } + + // Check input patterns + if ( + patterns.includeInputs.length > 0 && + !hasInputMatchingPatterns(bundle, patterns.includeInputs) + ) { + return false; + } + + // Check exclusions + return ( + !matchesAnyPattern(bundle.path, patterns.excludeOutputs) && + !hasInputMatchingPatterns(bundle, patterns.excludeInputs) + ); + }, + + withStartupDeps: ( + bundle: UnifiedStatsBundle, + patterns: CompiledPatterns, + ): boolean => bundleSelectors.bundle(bundle, patterns), + + withAllDeps: ( + bundle: UnifiedStatsBundle, + patterns: CompiledPatterns, + ): boolean => bundleSelectors.bundle(bundle, patterns), +}; + +function processMatchingOnlyBundle( + bundle: UnifiedStatsBundle, + patterns: CompiledPatterns, +): UnifiedStatsBundle | null { + if (!bundle.inputs) { + return null; + } + + const filteredInputs: typeof bundle.inputs = {}; + let filteredBytes = 0; + let hasMatches = false; + + for (const [inputPath, inputData] of Object.entries(bundle.inputs)) { + if (matchesAnyPattern(inputPath, patterns.includeInputs)) { + filteredInputs[inputPath] = inputData; + filteredBytes += inputData.bytes; + hasMatches = true; + } + } + + return hasMatches + ? { + path: bundle.path, + bytes: filteredBytes, + inputs: filteredInputs, + } + : null; +} + +function collectImportsForMode( + bundle: UnifiedStatsBundle, + mode: SelectionMode, +): string[] { + if (!bundle.imports) { + return []; + } + + const imports: string[] = []; + for (const imp of bundle.imports) { + if (mode === 'withAllDeps' || imp.kind === 'import-statement') { + imports.push(imp.path); + } + } + return imports; +} + +function validatePatterns(patterns: CompiledPatterns): void { + const hasAnyPatterns = [ + patterns.includeOutputs, + patterns.excludeOutputs, + patterns.includeInputs, + patterns.excludeInputs, + ].some((arr) => arr.length > 0); + + if (!hasAnyPatterns) { + throw new Error( + 'Selection requires at least one include/exclude pattern for outputs or inputs. ' + + 'Provide patterns like: { includeOutputs: ["*.js"] } or { includeInputs: ["src/**"] }', + ); + } +} + +export function compileSelectionPatterns( + config: SelectionConfig, +): CompiledPatterns { + return { + includeOutputs: compilePatterns(config.includeOutputs), + excludeOutputs: compilePatterns(config.excludeOutputs), + includeInputs: compilePatterns(config.includeInputs), + excludeInputs: compilePatterns(config.excludeInputs), + }; +} + +export function selectBundles( + unifiedStats: UnifiedStats, + selectionConfig: SelectionConfig, +): UnifiedStats { + // 🚀 Smart Optimization 1: Single-pass pattern compilation + const patterns = compileSelectionPatterns(selectionConfig); + validatePatterns(patterns); + + // 🚀 Smart Optimization 2: O(1) bundle lookups with simple map + const pathToKey = new Map(); + for (const [key, bundle] of Object.entries(unifiedStats)) { + pathToKey.set(bundle.path, key); + } + + const findBundleByPath = (path: string) => { + const key = pathToKey.get(path); + return key && unifiedStats[key] ? { key, bundle: unifiedStats[key] } : null; + }; + + // 🚀 Smart Optimization 3: Early exit & set-based processing + const selectedBundles = new Map(); + + // Get mode-specific selector for optimized processing + const isSelected = (bundle: UnifiedStatsBundle): boolean => { + switch (selectionConfig.mode) { + case 'matchingOnly': + return bundleSelectors.matchingOnly(bundle, patterns); + case 'bundle': + return bundleSelectors.bundle(bundle, patterns); + case 'withStartupDeps': + return bundleSelectors.withStartupDeps(bundle, patterns); + case 'withAllDeps': + return bundleSelectors.withAllDeps(bundle, patterns); + default: + return false; + } + }; + + // Process all bundles with early exits + for (const [key, bundle] of Object.entries(unifiedStats)) { + if (!isSelected(bundle)) { + continue; // Early exit + } + + let processedBundle = bundle; + + // Special processing for matchingOnly mode + if (selectionConfig.mode === 'matchingOnly') { + const filtered = processMatchingOnlyBundle(bundle, patterns); + if (!filtered) { + continue; // Early exit + } + processedBundle = filtered; + } + + selectedBundles.set(key, processedBundle); + } + + // 🚀 Smart Optimization 4: Optimized dependency processing + if ( + selectionConfig.mode === 'withStartupDeps' || + selectionConfig.mode === 'withAllDeps' + ) { + const processed = new Set(); + const importsToProcess: string[] = []; + + // Collect all imports from selected bundles + for (const bundle of selectedBundles.values()) { + importsToProcess.push( + ...collectImportsForMode(bundle, selectionConfig.mode), + ); + } + + // Process imports with optimized lookups and early exits + while (importsToProcess.length > 0) { + const importPath = importsToProcess.pop()!; + if (processed.has(importPath)) { + continue; + } // Early exit + processed.add(importPath); + + const found = findBundleByPath(importPath); + if (!found || selectedBundles.has(found.key)) { + continue; + } // Early exit + + // Check if import should be excluded + if (matchesAnyPattern(found.bundle.path, patterns.excludeOutputs)) { + continue; + } + if (hasInputMatchingPatterns(found.bundle, patterns.excludeInputs)) { + continue; + } + + selectedBundles.set(found.key, found.bundle); + + // Add nested static imports for further processing + if (found.bundle.imports) { + for (const nestedImport of found.bundle.imports) { + if ( + nestedImport.kind === 'import-statement' && + !processed.has(nestedImport.path) + ) { + importsToProcess.push(nestedImport.path); + } + } + } + } + } + + return Object.fromEntries(selectedBundles); +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/selection.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/selection.unit.test.ts new file mode 100644 index 0000000..944c087 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/selection.unit.test.ts @@ -0,0 +1,427 @@ +import { describe, expect, it } from 'vitest'; +import { normalizeSelectionOptions } from '../../normalize.js'; +import type { UnifiedStats } from '../unify/unified-stats.types.js'; +import { compileSelectionPatterns, selectBundles } from './selection.js'; + +describe('compileSelectionPatterns', () => { + it('should return object with correct structure for all pattern types', () => { + const result = compileSelectionPatterns({ + mode: 'bundle', + includeOutputs: ['dist/**/*.js'], + excludeOutputs: ['dist/**/*.map'], + includeInputs: ['src/**/*.ts'], + excludeInputs: ['**/*.test.ts'], + }); + + expect(result).toStrictEqual({ + includeOutputs: [expect.any(Function)], + excludeOutputs: [expect.any(Function)], + includeInputs: [expect.any(Function)], + excludeInputs: [expect.any(Function)], + }); + expect([ + result.includeOutputs[0]!('dist/main.js'), + result.includeOutputs[0]!('dist/main.map'), + ]).toEqual([true, false]); + }); + + it('should handle empty selection options', () => { + expect( + compileSelectionPatterns({ + mode: 'bundle', + includeOutputs: [], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }), + ).toStrictEqual({ + includeOutputs: [], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }); + }); + + it('should merge global include/exclude patterns', () => { + const result = compileSelectionPatterns( + normalizeSelectionOptions({ + include: ['src/**'], + exclude: ['*.test.*'], + includeOutputs: ['main.js'], + excludeOutputs: ['dev.js'], + includeInputs: ['components/**'], + excludeInputs: ['temp.js'], + }), + ); + + expect( + [ + result.includeOutputs, + result.excludeOutputs, + result.includeInputs, + result.excludeInputs, + ].map((arr) => arr.length), + ).toEqual([2, 2, 2, 2]); + }); + + it('should work with type configurations', () => { + const result = compileSelectionPatterns({ + mode: 'bundle' as const, + includeOutputs: ['*.js'], + excludeOutputs: ['*.test.js'], + includeInputs: [], + excludeInputs: [], + }); + + expect([ + result.includeOutputs[0]!('main.js'), + result.excludeOutputs[0]!('main.test.js'), + ]).toEqual([true, true]); + }); +}); + +describe('selectBundles', () => { + const empty = { + mode: 'bundle' as const, + includeOutputs: [], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }; + + const stats: UnifiedStats = { + 'dist/index.js': { + path: 'dist/index.js', + bytes: 5000, + inputs: { + 'src/index.ts': { bytes: 1000 }, + 'src/lib/feature-1.ts': { bytes: 1000 }, + 'src/lib/utils/format.ts': { bytes: 1000 }, + 'src/lib/utils/math.ts': { bytes: 1000 }, + 'src/lib/feature-2.ts': { bytes: 1000 }, + }, + imports: [ + { path: 'dist/chunks/chunk-U6O5K65G.js', kind: 'import-statement' }, + { path: 'dist/chunks/feature-2-X2YVDBQK.js', kind: 'dynamic-import' }, + ], + }, + 'dist/bin.js': { + path: 'dist/bin.js', + bytes: 3000, + inputs: { + 'src/bin.ts': { bytes: 500 }, + 'src/lib/feature-1.ts': { bytes: 1000 }, + 'src/lib/utils/format.ts': { bytes: 1000 }, + 'src/lib/utils/math.ts': { bytes: 500 }, + }, + imports: [ + { path: 'dist/chunks/chunk-U6O5K65G.js', kind: 'import-statement' }, + ], + }, + 'dist/chunks/chunk-U6O5K65G.js': { + path: 'dist/chunks/chunk-U6O5K65G.js', + bytes: 2000, + inputs: { + 'src/lib/utils/format.ts': { bytes: 1000 }, + 'src/lib/feature-1.ts': { bytes: 500 }, + 'src/lib/utils/math.ts': { bytes: 500 }, + }, + }, + 'dist/chunks/feature-2-X2YVDBQK.js': { + path: 'dist/chunks/feature-2-X2YVDBQK.js', + bytes: 1000, + inputs: { + 'src/lib/feature-2.ts': { bytes: 1000 }, + }, + }, + }; + + it('should return empty result for empty stats', () => { + expect( + selectBundles({}, { ...empty, includeOutputs: ['*.js'] }), + ).toStrictEqual({}); + }); + + it('should throw error for empty selection options', () => { + expect(() => selectBundles({}, empty)).toThrowError( + 'Selection requires at least one include/exclude pattern', + ); + expect(() => + selectBundles( + { 'main.js': { path: 'dist/main.js', bytes: 0, inputs: {} } }, + empty, + ), + ).toThrowError('Provide patterns like'); + }); + + // Byte Inclusion Tests + it('should select output and dependencies (Include Output)', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + mode: 'withStartupDeps', + includeOutputs: ['**/dist/index.js'], + }), + ), + ).toEqual(['dist/index.js', 'dist/chunks/chunk-U6O5K65G.js']); + }); + + it('should include static imports only (Include Output)', () => { + const result = selectBundles(stats, { + ...empty, + mode: 'withStartupDeps', + includeOutputs: ['**/dist/index.js'], + }); + expect([ + !!result['dist/chunks/chunk-U6O5K65G.js'], + !!result['dist/chunks/feature-2-X2YVDBQK.js'], + ]).toEqual([true, false]); + }); + + it('should select only bundle file in bundle mode', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + mode: 'bundle', + includeOutputs: ['**/dist/index.js'], + }), + ), + ).toEqual(['dist/index.js']); + }); + + it('should exclude files by pattern (Include/Exclude Output)', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + includeOutputs: ['**/*'], + excludeOutputs: ['**/bin.js'], + }), + ), + ).toEqual([ + 'dist/index.js', + 'dist/chunks/chunk-U6O5K65G.js', + 'dist/chunks/feature-2-X2YVDBQK.js', + ]); + }); + + it('should prioritize exclude over include', () => { + expect( + selectBundles(stats, { + ...empty, + includeOutputs: ['**/dist/index.js'], + excludeOutputs: ['**/dist/index.js'], + }), + ).toStrictEqual({}); + }); + + it('should select by input files (Include Input)', () => { + expect( + Object.keys( + selectBundles(stats, { ...empty, includeInputs: ['**/feature-2.ts'] }), + ), + ).toEqual(['dist/index.js', 'dist/chunks/feature-2-X2YVDBQK.js']); + }); + + it('should select by utility files (Include Input)', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + includeInputs: ['**/utils/format.ts'], + }), + ), + ).toEqual([ + 'dist/index.js', + 'dist/bin.js', + 'dist/chunks/chunk-U6O5K65G.js', + ]); + }); + + it('should exclude by input files (Include/Exclude Input)', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + includeOutputs: ['**/*'], + excludeInputs: ['**/feature-2.ts'], + }), + ), + ).toEqual(['dist/bin.js', 'dist/chunks/chunk-U6O5K65G.js']); + }); + + it('should exclude utility files', () => { + const result = selectBundles(stats, { + ...empty, + includeOutputs: ['**/*'], + excludeInputs: ['**/utils/**'], + }); + Object.values(result).forEach( + (output) => + output?.inputs && + expect( + Object.keys(output.inputs).every((path) => !path.includes('utils')), + ).toBe(true), + ); + }); + + it('should handle complex filtering (Include/Exclude Mixed)', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + includeOutputs: ['**/index.js', '**/chunks/**'], + excludeOutputs: ['**/bin.js'], + excludeInputs: ['**/utils/**'], + }), + ), + ).not.toContain('dist/bin.js'); + }); + + it('should combine include patterns with OR logic', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + includeOutputs: ['**/index.js', '**/bin.js'], + excludeInputs: ['**/feature-2.ts'], + }), + ), + ).toEqual(['dist/bin.js']); + }); + + // Dependency Inclusion Tests + it('should filter inputs in matchingOnly mode', () => { + const result = selectBundles(stats, { + ...empty, + mode: 'matchingOnly', + includeInputs: ['**/utils/format.ts'], + }); + Object.values(result).forEach( + (output) => + output?.inputs && + expect( + Object.keys(output.inputs).every((path) => + path.includes('format.ts'), + ), + ).toBe(true), + ); + }); + + it('should exclude bundler overhead in matchingOnly mode', () => { + const result = selectBundles(stats, { + ...empty, + mode: 'matchingOnly', + includeInputs: ['**/feature-1.ts'], + }); + Object.values(result).forEach((output) => { + if (output?.inputs) { + const inputBytes = Object.values(output.inputs).reduce( + (sum, input) => sum + (input?.bytes || 0), + 0, + ); + expect(output.bytes).toBeLessThanOrEqual(inputBytes); + } + }); + }); + + it('should include full bundle with overhead (Mode: bundle)', () => { + const result = selectBundles(stats, { + ...empty, + mode: 'bundle', + includeOutputs: ['**/dist/index.js'], + }); + expect([ + result['dist/index.js']?.bytes, + Object.keys(result).length, + ]).toEqual([5000, 1]); + }); + + it('should preserve bundled inputs (Mode: bundle)', () => { + expect( + Object.keys( + selectBundles(stats, { + ...empty, + mode: 'bundle', + includeOutputs: ['**/dist/bin.js'], + })['dist/bin.js']?.inputs || {}, + ), + ).toHaveLength(4); + }); + + it('should include static imports (Mode: withStartupDeps)', () => { + const result = selectBundles(stats, { + ...empty, + mode: 'withStartupDeps', + includeOutputs: ['**/dist/index.js'], + }); + expect([ + !!result['dist/chunks/chunk-U6O5K65G.js'], + !!result['dist/chunks/feature-2-X2YVDBQK.js'], + ]).toEqual([true, false]); + }); + + it('should exclude static imports by pattern (Mode: withStartupDeps)', () => { + expect( + selectBundles(stats, { + ...empty, + mode: 'withStartupDeps', + includeOutputs: ['**/dist/index.js'], + excludeOutputs: ['**/chunks/**'], + })['dist/chunks/chunk-U6O5K65G.js'], + ).toBeUndefined(); + }); + + it('should include all imports (Mode: withAllDeps)', () => { + const result = selectBundles(stats, { + ...empty, + mode: 'withAllDeps', + includeOutputs: ['**/dist/index.js'], + }); + expect([ + !!result['dist/chunks/chunk-U6O5K65G.js'], + !!result['dist/chunks/feature-2-X2YVDBQK.js'], + ]).toEqual([true, true]); + }); + + it('should exclude dependencies that match exclude patterns (Mode: withAllDeps)', () => { + expect( + selectBundles(stats, { + ...empty, + mode: 'withAllDeps', + includeOutputs: ['**/dist/index.js'], + excludeOutputs: ['**/chunks/**'], + }), + ).toStrictEqual({ 'dist/index.js': stats['dist/index.js'] }); + }); + + it('should handle nested dependency chains (Mode: withAllDeps)', () => { + const nestedStats = { + 'dist/nested.js': { + path: 'dist/nested.js', + bytes: 1000, + inputs: {}, + imports: [{ path: 'dist/level1.js', kind: 'import-statement' }], + }, + 'dist/level1.js': { + path: 'dist/level1.js', + bytes: 500, + inputs: {}, + imports: [{ path: 'dist/level2.js', kind: 'dynamic-import' }], + }, + 'dist/level2.js': { path: 'dist/level2.js', bytes: 200, inputs: {} }, + } as unknown as UnifiedStats; + + expect( + Object.keys( + selectBundles(nestedStats, { + ...empty, + mode: 'withAllDeps', + includeOutputs: ['**/nested.js'], + }), + ), + ).toEqual(['dist/nested.js', 'dist/level1.js']); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.ts b/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.ts new file mode 100644 index 0000000..3957b70 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.ts @@ -0,0 +1,384 @@ +import type { AuditOutput, PluginArtifactOptions } from '@code-pushup/models'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; +import { normalizeRange } from '../normalize.js'; +import type { + PluginDependencyTreeOptions, + PluginInsightsTableOptions, + PluginScoringOptions, + PluginSelectionOptions, +} from '../types.js'; +import { generateAuditOutputs } from './audits/audit-outputs.js'; +import type { InsightsTableConfig } from './audits/details/table.js'; +import type { DependencyTreeConfig } from './audits/details/tree.js'; +import { DEFAULT_PENALTY } from './audits/scoring.js'; +import type { SelectionConfig } from './audits/selection.js'; +import type { + BundleStatsConfig, + GroupingRule, + SupportedBundlers, +} from './types.js'; +import type { UnifiedStats } from './unify/unified-stats.types.js'; +import { unifyBundlerStats as unifyEsbuildStats } from './unify/unify.esbuild.js'; +import { unifyBundlerStats as unifyRsbuildStats } from './unify/unify.rsbuild.js'; +import { unifyBundlerStats as unifySondaStats } from './unify/unify.sonda.js'; +import { unifyBundlerStats as unifyViteStats } from './unify/unify.vite.js'; +import { unifyBundlerStats as unifyWebpackStats } from './unify/unify.webpack.js'; + +export type BundleStatsRunnerConfig = { + bundler: SupportedBundlers; + bundleStatsConfigs: BundleStatsConfig[]; +} & PluginArtifactOptions; + +/** + * Validates basic structure of bundle stats data. + */ +function validateStatsStructure( + stats: unknown, + artefactsPath: string, +): asserts stats is Record { + if (!stats) { + throw new Error(`Bundle stats file is null or undefined: ${artefactsPath}`); + } + + if (typeof stats !== 'object') { + throw new TypeError( + `Bundle stats file has invalid structure: ${artefactsPath}`, + ); + } +} + +/** + * Validates bundler-specific properties in stats data. + */ +function validateBundlerSpecificProperties( + stats: Record, + artefactsPath: string, + bundler: SupportedBundlers, +): void { + switch (bundler) { + case 'esbuild': + if (!('outputs' in stats)) { + throw new Error( + `Bundle stats file missing 'outputs' property for esbuild: ${artefactsPath}`, + ); + } + if (!stats['outputs']) { + throw new Error( + `Bundle stats outputs is null or undefined in file: ${artefactsPath}`, + ); + } + break; + case 'webpack': + case 'rsbuild': + if ( + !('assets' in stats) || + !('chunks' in stats) || + !('modules' in stats) + ) { + throw new Error( + `Bundle stats file missing required ${bundler} properties (assets, chunks, modules): ${artefactsPath}`, + ); + } + break; + case 'vite': + if (!('assets' in stats) || !('chunks' in stats)) { + throw new Error( + `Bundle stats file missing required vite properties (assets, chunks): ${artefactsPath}`, + ); + } + break; + case 'sonda': + if (!('resources' in stats) || !('connections' in stats)) { + throw new Error( + `Bundle stats file missing required sonda properties (resources, connections): ${artefactsPath}`, + ); + } + break; + default: + throw new Error(`Unsupported bundler: ${bundler}`); + } +} + +/** + * Validates bundle stats data structure based on bundler type. Ensures stats and required properties are properly defined. + */ +export function validateBundleStats( + stats: unknown, + artefactsPath: string, + bundler: SupportedBundlers, +): void { + validateStatsStructure(stats, artefactsPath); + validateBundlerSpecificProperties(stats, artefactsPath, bundler); +} + +type BundlerStats = Record; +type UnifyOptions = Record; + +/** + * Returns the appropriate unify function based on bundler type. Provides bundler-specific stats processing. + */ +export function getUnifyFunction( + bundler: SupportedBundlers, +): (stats: BundlerStats, options?: UnifyOptions) => UnifiedStats { + switch (bundler) { + case 'esbuild': + return unifyEsbuildStats as ( + stats: BundlerStats, + options?: UnifyOptions, + ) => UnifiedStats; + case 'webpack': + return unifyWebpackStats as ( + stats: BundlerStats, + options?: UnifyOptions, + ) => UnifiedStats; + case 'rsbuild': + return unifyRsbuildStats as ( + stats: BundlerStats, + options?: UnifyOptions, + ) => UnifiedStats; + case 'vite': + return unifyViteStats as ( + stats: BundlerStats, + options?: UnifyOptions, + ) => UnifiedStats; + case 'sonda': + return unifySondaStats as ( + stats: BundlerStats, + options?: UnifyOptions, + ) => UnifiedStats; + default: + throw new Error(`Unsupported bundler: ${bundler}`); + } +} + +/** + * Merges dependency tree configurations from audit and plugin levels. + * Groups merge (global + local), pruning overwrites (local takes precedence). + */ +export function mergeDependencyTreeConfig( + auditConfig: DependencyTreeConfig | undefined, + pluginOptions: PluginDependencyTreeOptions | undefined, +): DependencyTreeConfig | undefined { + // Only hide if audit config explicitly disables + if (auditConfig?.enabled === false) { + return undefined; + } + + // If global options exist, always show them (unless disabled above) + if (pluginOptions) { + return { + // Groups logic: false = hide, array = overwrite global, undefined = use global + groups: (() => { + // Only hide if explicitly set to false + if (auditConfig?.groups === false) { + return []; + } + // If audit defines groups, use them (overwrite global) + if (auditConfig?.groups !== undefined) { + return auditConfig.groups as GroupingRule[]; + } + // Otherwise, use global groups + return pluginOptions?.groups ?? []; + })(), + // Pruning overwrites - local takes precedence over global + pruning: { + maxDepth: 2, + maxChildren: 20, // Default max children for dependency tree + pathLength: 60, + ...pluginOptions?.pruning, + ...auditConfig?.pruning, + }, + mode: auditConfig?.mode ?? 'onlyMatching', + }; + } + + // If no global options but config exists, use config + if (auditConfig) { + return { + // Groups fallback - use audit groups or empty array if false + groups: auditConfig.groups === false ? [] : (auditConfig.groups ?? []), + // Pruning fallback - use audit pruning with defaults + pruning: { + maxDepth: 2, + maxChildren: 10, + pathLength: 60, + ...auditConfig?.pruning, + }, + mode: auditConfig.mode ?? 'onlyMatching', + }; + } + + return undefined; +} + +/** + * Merges selection configurations with hybrid strategy. Excludes merge for safety, includes overwrite for scope clarity. + */ +export function mergeSelectionConfig( + auditConfig: SelectionConfig | undefined, + pluginOptions?: PluginSelectionOptions, +): SelectionConfig { + return { + // mode from audit config takes precedence + mode: auditConfig?.mode == null ? 'bundle' : auditConfig.mode, + + // Include arrays overwrite - config takes precedence for scope clarity + includeOutputs: auditConfig?.includeOutputs ?? [], + includeInputs: auditConfig?.includeInputs ?? [], + + // Exclude arrays merge - merging exclusions is safe and expected + excludeOutputs: [ + ...(pluginOptions?.excludeOutputs ?? []), + ...(auditConfig?.excludeOutputs ?? []), + ], + excludeInputs: [ + ...(pluginOptions?.excludeInputs ?? []), + ...(auditConfig?.excludeInputs ?? []), + ], + }; +} + +/** + * Merges scoring configurations with hybrid strategy. Penalty blacklist merges to combine blocked patterns. + */ +export function mergeScoringConfig( + auditConfig: BundleStatsConfig['scoring'] | undefined, + pluginOptions: PluginScoringOptions | undefined, +): BundleStatsConfig['scoring'] { + if (auditConfig?.penalty === false) { + return auditConfig; + } + + if (!auditConfig) { + return pluginOptions as BundleStatsConfig['scoring']; + } + + const pluginPenalty = pluginOptions?.penalty; + const normalizedPluginPenalty = pluginPenalty + ? { + ...pluginPenalty, + artefactSize: pluginPenalty.artefactSize + ? normalizeRange(pluginPenalty.artefactSize) + : undefined, + } + : undefined; + + return { + ...auditConfig, + penalty: { + ...DEFAULT_PENALTY, + ...normalizedPluginPenalty, + ...auditConfig?.penalty, + // Blacklist merges - combine blocked patterns from both sources + blacklist: [ + ...(normalizedPluginPenalty?.blacklist ?? []), + ...(auditConfig?.penalty?.blacklist ?? []), + ], + }, + }; +} + +/** + * Merges insights configurations with fallback strategy. Uses audit-level when defined, falls back to global when undefined, hides when false. + */ +export function mergeInsightsConfig( + auditConfig: InsightsTableConfig | false | undefined, + pluginOptions: InsightsTableConfig | false | undefined, +): InsightsTableConfig | false | undefined { + if (auditConfig === false) { + return undefined; + } + + // Insights override - audit-level completely replaces plugin-level when defined + if (auditConfig !== undefined) { + return auditConfig; + } + + // Handle false plugin options + if (pluginOptions === false) { + return undefined; + } + + return pluginOptions; +} + +/** + * Creates a bundle stats audit runner that processes bundler output and generates audit results. + * Supports multiple bundlers (esbuild, webpack, rsbuild) with dynamic module loading. + */ +export async function bundleStatsRunner( + opts: BundleStatsRunnerConfig, +): Promise<() => Promise> { + const { + artifactsPaths, + generateArtifactsCommand, + bundleStatsConfigs, + bundler, + } = opts; + + return async () => { + if (artifactsPaths && generateArtifactsCommand) { + const { command, args } = + typeof generateArtifactsCommand === 'string' + ? { command: generateArtifactsCommand, args: undefined } + : generateArtifactsCommand; + try { + await executeProcess({ + command, + args, + }); + } catch (error) { + throw new Error( + `Failed to generate artefacts for plugin bundle-stats. command: ${command} args: ${args} error: ${error}`, + ); + } + } + + if (Array.isArray(artifactsPaths)) { + throw new TypeError( + 'The bundle stats plugin does not support multiple artifact paths. Request feature on GitHub.', + ); + } + + const stats = await readJsonFile(artifactsPaths); + // @TODO implement zod schema + validateBundleStats(stats, artifactsPaths, bundler); + + const unifyBundlerStats = getUnifyFunction(bundler); + const unifiedBundleStats = unifyBundlerStats(stats as BundlerStats, {}); + + return generateAuditOutputs(unifiedBundleStats, bundleStatsConfigs); + }; +} + +export function mergeAuditConfigs( + configs: BundleStatsConfig[], + options: { + dependencyTree?: PluginDependencyTreeOptions; + selection?: PluginSelectionOptions; + scoring?: PluginScoringOptions; + insightsTable?: PluginInsightsTableOptions; + }, +): BundleStatsConfig[] { + return configs.map((config) => { + const { insightsTable: configInsights, ...configWithoutInsights } = config; + + return { + ...configWithoutInsights, + dependencyTree: mergeDependencyTreeConfig( + config.dependencyTree, + options.dependencyTree, + ), + selection: mergeSelectionConfig(config.selection, options.selection), + scoring: mergeScoringConfig(config.scoring, options.scoring), + ...(configInsights === false + ? {} + : { + insightsTable: mergeInsightsConfig( + configInsights, + options.insightsTable, + ), + }), + }; + }); +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.unit.test.ts new file mode 100644 index 0000000..8a9ce60 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.unit.test.ts @@ -0,0 +1,552 @@ +import { describe, expect, it } from 'vitest'; +import type { PluginSelectionOptions } from '../types.js'; +import type { PenaltyConfig } from './audits/scoring.js'; +import type { SelectionConfig } from './audits/selection.js'; +import { + mergeAuditConfigs, + mergeDependencyTreeConfig, + mergeInsightsConfig, + mergeScoringConfig, + mergeSelectionConfig, +} from './bundle-stats-runner.js'; +import type { GroupingRule } from './types.js'; + +const testScoring = { + mode: 'onlyMatching' as const, + totalSize: [0, 1000] as [number, number], + penalty: { warningWeight: 0.1, errorWeight: 0.2 } as PenaltyConfig, +}; +const emptySelection: SelectionConfig = { + mode: 'matchingOnly' as const, + includeOutputs: [], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], +}; + +describe('mergeDependencyTreeConfig', () => { + it('should return undefined when both global and config are undefined', () => { + expect(mergeDependencyTreeConfig(undefined, undefined)).toBeUndefined(); + }); + + it('should use config when global is undefined', () => { + const auditConfig = { + groups: [ + { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule, + ], + }; + const result = mergeDependencyTreeConfig(auditConfig, undefined); + + expect(result?.groups).toHaveLength(1); + expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject( + { includeInputs: ['**/*.ts'] }, + ); + }); + + it('should return undefined when config.enabled is false', () => { + const auditConfig = { enabled: false, groups: [] }; + const pluginOptions = { + groups: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + }; + + expect( + mergeDependencyTreeConfig(auditConfig, pluginOptions), + ).toBeUndefined(); + }); + + it('should merge when global options provided and config undefined', () => { + const pluginOptions = { + groups: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + }; + const result = mergeDependencyTreeConfig(undefined, pluginOptions); + + expect(result?.groups).toHaveLength(1); + expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject( + { includeInputs: ['**/*.js'] }, + ); + }); + + it('should merge when both global and config options provided', () => { + const auditConfig = { + groups: [ + { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule, + ], + }; + const pluginOptions = { + groups: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + }; + const result = mergeDependencyTreeConfig(auditConfig, pluginOptions); + + expect(result?.groups).toHaveLength(1); + expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject( + { includeInputs: ['**/*.ts'] }, + ); + }); + + it('should overwrite pruning options (config takes precedence)', () => { + const auditConfig = { pruning: { maxDepth: 5 } }; + const pluginOptions = { pruning: { maxDepth: 3 } }; + const result = mergeDependencyTreeConfig(auditConfig, pluginOptions); + + expect(result?.pruning?.maxDepth).toBe(5); + }); + + it('should provide DEFAULT pruning options when no options provided', () => { + const auditConfig = { groups: [] }; + const result = mergeDependencyTreeConfig(auditConfig, undefined); + + expect(result?.pruning).toBeDefined(); + }); +}); + +describe('mergeSelectionConfig', () => { + it('should merge plugin and audit selection patterns', () => { + const auditConfig = { + mode: 'matchingOnly' as const, + includeOutputs: ['main.js'], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }; + const pluginOptions = { + excludeOutputs: ['*.map'], + excludeInputs: [], + } as PluginSelectionOptions; + const result = mergeSelectionConfig(auditConfig, pluginOptions); + + expect(result).toMatchObject({ + includeOutputs: ['main.js'], + excludeOutputs: ['*.map'], + }); + }); + + it('should handle empty plugin options', () => { + const auditConfig = { + mode: 'matchingOnly' as const, + includeOutputs: [], + excludeOutputs: ['dev.js'], + includeInputs: [], + excludeInputs: [], + }; + const result = mergeSelectionConfig(auditConfig); + + expect(result).toMatchObject({ + excludeOutputs: ['dev.js'], + }); + }); + + it('should merge multiple arrays correctly', () => { + const auditConfig = { + mode: 'matchingOnly' as const, + includeOutputs: ['main.js'], + excludeOutputs: [], + includeInputs: [], + excludeInputs: ['temp.js'], + }; + const pluginOptions = { + excludeOutputs: ['*.map'], + excludeInputs: ['test/**'], + } as PluginSelectionOptions; + const result = mergeSelectionConfig(auditConfig, pluginOptions); + + expect(result).toMatchObject({ + includeOutputs: ['main.js'], + excludeOutputs: ['*.map'], + excludeInputs: ['test/**', 'temp.js'], + }); + }); + + it('should handle undefined config selection', () => { + const pluginOptions = { + excludeOutputs: ['*.map'], + excludeInputs: [], + } as PluginSelectionOptions; + const result = mergeSelectionConfig(undefined, pluginOptions); + + expect(result).toMatchObject({ + includeOutputs: [], + excludeOutputs: ['*.map'], + }); + }); + + it('should handle empty exclude arrays', () => { + const auditConfig = { + mode: 'matchingOnly' as const, + includeOutputs: [], + excludeOutputs: [], + includeInputs: [], + excludeInputs: [], + }; + const pluginOptions = { + excludeOutputs: [], + excludeInputs: [], + } as PluginSelectionOptions; + const result = mergeSelectionConfig(auditConfig, pluginOptions); + + expect(result).toMatchObject(emptySelection); + }); + + it('should merge exclude patterns correctly', () => { + const auditConfig = emptySelection; + const pluginOptions = { + excludeOutputs: ['*.map'], + excludeInputs: ['*.test.js'], + } as PluginSelectionOptions; + const result = mergeSelectionConfig(auditConfig, pluginOptions); + + expect(result.excludeOutputs).toStrictEqual(['*.map']); + expect(result.excludeInputs).toStrictEqual(['*.test.js']); + }); +}); + +describe('mergeScoringConfig', () => { + it('should return config when config.penalty is false', () => { + const auditConfig = { + mode: 'onlyMatching' as const, + totalSize: [0, 1000] as [number, number], + penalty: false as const, + }; + const pluginOptions = { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 2, + } as PenaltyConfig, + }; + + expect(mergeScoringConfig(auditConfig, pluginOptions)).toStrictEqual({ + mode: 'onlyMatching', + totalSize: [0, 1000], + penalty: false, + }); + }); + + it('should return options when config is undefined', () => { + const pluginOptions = { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 2, + } as PenaltyConfig, + }; + + expect(mergeScoringConfig(undefined, pluginOptions)).toStrictEqual( + pluginOptions, + ); + }); + + it('should merge when both config and options provided', () => { + const auditConfig = { + mode: 'onlyMatching' as const, + totalSize: [0, 1000] as [number, number], + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 3, + } as PenaltyConfig, + }; + const pluginOptions = { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + threshold: 100, + } as PenaltyConfig, + }; + const result = mergeScoringConfig(auditConfig, pluginOptions); + + expect(result?.penalty).toMatchObject({ factor: 3, threshold: 100 }); + }); + + it('should merge penalty blacklists from both sources', () => { + const auditConfig = { + mode: 'onlyMatching' as const, + totalSize: [0, 1000] as [number, number], + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + blacklist: ['config-pattern'], + } as PenaltyConfig, + }; + const pluginOptions = { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + blacklist: ['global-pattern'], + } as PenaltyConfig, + }; + const result = mergeScoringConfig(auditConfig, pluginOptions); + + expect((result?.penalty as any)?.blacklist).toStrictEqual([ + 'global-pattern', + 'config-pattern', + ]); + }); + + it('should overwrite other penalty properties (config takes precedence)', () => { + const auditConfig = { + mode: 'onlyMatching' as const, + totalSize: [0, 1000] as [number, number], + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 3, + threshold: 500, + } as PenaltyConfig, + }; + const pluginOptions = { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 2, + threshold: 100, + } as PenaltyConfig, + }; + const result = mergeScoringConfig(auditConfig, pluginOptions); + + expect((result?.penalty as any)?.factor).toBe(3); + expect((result?.penalty as any)?.threshold).toBe(500); + }); + + it('should handle undefined global scoring', () => { + const auditConfig = { + mode: 'onlyMatching' as const, + totalSize: [0, 1000] as [number, number], + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 2, + } as PenaltyConfig, + }; + const result = mergeScoringConfig(auditConfig, undefined); + + expect((result?.penalty as any)?.factor).toBe(2); + }); +}); + +describe('mergeInsightsConfig', () => { + it('should return undefined when config is false', () => { + const pluginOptions = { + groups: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + }; + + expect(mergeInsightsConfig(false, pluginOptions)).toBeUndefined(); + }); + + it('should merge arrays when both global and config provided', () => { + const auditConfig = { + groups: [ + { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule, + ], + }; + const pluginOptions = { + groups: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + }; + + // Function overrides (doesn't merge) - auditConfig takes precedence + const result = mergeInsightsConfig(auditConfig, pluginOptions); + expect( + result && typeof result === 'object' && 'groups' in result + ? result.groups + : [], + ).toHaveLength(1); + expect( + result && typeof result === 'object' && 'groups' in result + ? result.groups?.[0] + : {}, + ).toMatchObject({ includeInputs: ['**/*.ts'] }); + }); + + it('should use global when config is undefined', () => { + const pluginOptions = { + groups: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + }; + + expect(mergeInsightsConfig(undefined, pluginOptions)).toStrictEqual({ + groups: [{ includeInputs: ['**/*.js'], title: 'JavaScript' }], + }); + }); + + it('should use config when global is undefined', () => { + const auditConfig = { + groups: [ + { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule, + ], + }; + + expect(mergeInsightsConfig(auditConfig, undefined)).toStrictEqual({ + groups: [{ includeInputs: ['**/*.ts'], title: 'TypeScript' }], + }); + }); + + it('should return undefined when both are undefined', () => { + expect(mergeInsightsConfig(undefined, undefined)).toBeUndefined(); + }); + + it('should handle false in both global and config', () => { + expect(mergeInsightsConfig(false, false)).toBeUndefined(); + }); +}); + +describe('mergeAuditConfigs', () => { + it('should return empty array when given empty configs', () => { + expect(mergeAuditConfigs([], {})).toStrictEqual([]); + }); + + it('should map over multiple configs correctly', () => { + const configs = [ + { + slug: 'audit-1', + title: 'First', + selection: emptySelection, + scoring: testScoring, + }, + { + slug: 'audit-2', + title: 'Second', + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const result = mergeAuditConfigs(configs, {}); + + expect(result).toHaveLength(2); + expect(result[0]?.slug).toBe('audit-1'); + expect(result[1]?.slug).toBe('audit-2'); + }); + + it('should set selection property correctly', () => { + const configs = [ + { + slug: 'test', + title: 'Test', + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const options = { + selection: { excludeOutputs: ['*.test.js'] } as PluginSelectionOptions, + }; + const result = mergeAuditConfigs(configs, options); + + expect(result[0]?.selection).toBeDefined(); + expect(result[0]?.selection.excludeOutputs).toStrictEqual(['*.test.js']); + }); + + it('should set scoring property correctly', () => { + const configs = [ + { + slug: 'test', + title: 'Test', + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const options = { + scoring: { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + } satisfies PenaltyConfig, + }, + }; + const result = mergeAuditConfigs(configs, options); + + expect(result[0]?.scoring).toBeDefined(); + }); + + it('should include insightsTable when config.insightsTable is not false', () => { + const configs = [ + { + slug: 'test', + title: 'Test', + insightsTable: [ + { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule, + ], + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const result = mergeAuditConfigs(configs, {}); + + expect(result[0]).toHaveProperty('insightsTable'); + expect(result[0]?.insightsTable).toHaveLength(1); + }); + + it('should exclude insightsTable when config.insightsTable is false', () => { + const configs = [ + { + slug: 'test', + title: 'Test', + insightsTable: false, + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const result = mergeAuditConfigs(configs, {}); + + expect(result[0]).not.toHaveProperty('insightsTable'); + }); + + it('should handle empty options object', () => { + const configs = [ + { + slug: 'test', + title: 'Test', + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const result = mergeAuditConfigs(configs, {}); + + expect(result[0]).toMatchObject({ + slug: 'test', + selection: { + mode: 'matchingOnly', + includeOutputs: [], + includeInputs: [], + excludeOutputs: [], + excludeInputs: [], + }, + }); + expect((result[0] as any).artefactTree).toBeUndefined(); + }); + + it('should handle partial options object', () => { + const configs = [ + { + slug: 'test', + title: 'Test', + selection: emptySelection, + scoring: testScoring, + }, + ] as any; + const options = { + scoring: { + penalty: { + warningWeight: 0.1, + errorWeight: 0.2, + factor: 1.5, + } as PenaltyConfig, + }, + }; + const result = mergeAuditConfigs(configs, options); + + expect(result[0]).toMatchObject({ + slug: 'test', + scoring: expect.any(Object), + }); + expect((result[0] as any).artefactTree).toBeUndefined(); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/constants.ts b/packages/plugin-bundle-stats/src/lib/runner/constants.ts new file mode 100644 index 0000000..2cbdcd5 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/constants.ts @@ -0,0 +1,19 @@ +import type { GroupingRule } from './types.js'; + +export type { GroupingRule }; + +/** + * Default grouping rules for bundle stats analysis. + * These rules help categorize and organize bundle assets by common patterns. + */ +export const DEFAULT_GROUPING: GroupingRule[] = [ + { + includeInputs: ['projects/**/*'], + }, + { + includeInputs: ['packages/**/*'], + }, + { + includeInputs: ['**/node_modules/@*/**', '**/node_modules/**'], + }, +]; diff --git a/packages/plugin-bundle-stats/src/lib/runner/types.ts b/packages/plugin-bundle-stats/src/lib/runner/types.ts new file mode 100644 index 0000000..48161ad --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/types.ts @@ -0,0 +1,92 @@ +import type { Audit } from '@code-pushup/models'; +import type { + PluginDependencyTreeOptions, + PluginScoringOptions, + PluginSelectionOptions, +} from '../types.js'; +import type { InsightsTableConfig } from './audits/details/table.js'; +import type { DependencyTreeConfig } from './audits/details/tree.js'; +import type { ScoringConfig } from './audits/scoring.js'; +import type { SelectionConfig } from './audits/selection.js'; + +export type SupportedBundlers = + | 'webpack' + | 'vite' + | 'esbuild' + | 'rsbuild' + | 'sonda'; + +export type MinMax = [number, number]; + +export type PatternList = readonly string[]; + +export type AuditOptions = Required> & + Partial>; + +export type BundleStatsConfig = AuditOptions & { + selection: SelectionConfig; + scoring: ScoringConfig; + dependencyTree?: DependencyTreeConfig; + insightsTable?: InsightsTableConfig | false; +}; + +export type PluginArtefactOptions = { + generateArtefacts?: { + command: string; + args: string[]; + }; + artefactsPath: string; + bundler: SupportedBundlers; +}; + +export type BundleStatsRunnerConfig = { + audits: BundleStatsConfig[]; + scoring?: PluginScoringOptions; + dependencyTree?: PluginDependencyTreeOptions; + insightsTable?: InsightsTableConfig; + selection?: PluginSelectionOptions; +} & PluginArtefactOptions; + +type OptionalGroupingRule = { + title?: string; + icon?: string; + numSegments?: number; +}; + +export type GroupingRule = OptionalGroupingRule & { + includeInputs: string | PatternList; + excludeInputs?: string | PatternList; +}; + +export type LogicalGroupingRule = Omit & { + maxDepth: 1; +}; + +export type MinimalBundleStats = { + name: string; + total: number; + chunks: ChunkBundleStats[]; +}; + +export type ChunkBundleStats = { + name: string; + size: number; + modules: ModuleBundleStats[]; +}; + +export type ModuleBundleStats = { + name: string; + size: number; +}; + +export type Grouping = { + title: string; + patterns: string | PatternList; + icon?: string; + maxDepth?: number; +}; + +export type Insight = { + pattern: string | PatternList; + label: string; +}; diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unified-stats.types.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unified-stats.types.ts new file mode 100644 index 0000000..d00ed37 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unified-stats.types.ts @@ -0,0 +1,27 @@ +export type SupportedImportKind = 'static' | 'dynamic'; + +export type UnifiedStatsImport = { + path: string; + kind: string; + /** + * The "original" property contains the exact import statement as it was written in the source code, + * while "path" contains the resolved absolute file path after webpack processing. + */ + original?: string; +}; + +export type UnifiedStatsInput = { + bytes: number; + imports?: UnifiedStatsImport[]; + format?: string; +}; + +export type UnifiedStatsBundle = { + path: string; + bytes: number; + inputs?: Record; + entryPoint?: string; + imports?: UnifiedStatsImport[]; +}; + +export type UnifiedStats = Record; diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.ts new file mode 100644 index 0000000..83fb103 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.ts @@ -0,0 +1,140 @@ +import { minimatch } from 'minimatch'; +import type { + UnifiedStats, + UnifiedStatsBundle, + UnifiedStatsImport, +} from './unified-stats.types.js'; + +export type EsBuildImportKind = 'import-statement' | 'dynamic-import'; + +export type EsBuildInputImport = { + path: string; + kind: EsBuildImportKind; + original: string; +}; + +export type EsBuildOutputImport = { + path: string; + kind: EsBuildImportKind; + external?: boolean; + original?: string; +}; + +export type EsBuildInput = { + bytes: number; + imports: EsBuildInputImport[]; + format?: string; +}; + +export type EsBuildOutput = { + bytes: number; + inputs?: Record; + entryPoint?: string; + imports?: EsBuildOutputImport[]; + exports?: string[]; +}; + +export type EsBuildCoreStats = { + outputs: Record; + inputs: Record; +}; + +export type EsBuildUnifyOptions = { + excludeOutputs?: string[]; +}; + +/** + * Checks if path matches any exclude pattern. Filters unwanted files from bundle stats. + */ +function shouldExcludeOutput( + outputPath: string, + excludePatterns: string[], +): boolean { + return excludePatterns.some((pattern) => minimatch(outputPath, pattern)); +} + +export function unifyBundlerStats( + stats: EsBuildCoreStats, + options: EsBuildUnifyOptions, +): UnifiedStats { + const { excludeOutputs = ['**/*.map', '**/*.d.ts'] } = options; + + const outputKeys = Object.keys(stats.outputs); + const result: UnifiedStats = {}; + + for (const outputKey of outputKeys) { + const outputName = outputKey!; + const outputInfo = stats.outputs[outputName]; + if (!outputInfo) { + continue; + } + + // Skip outputs that match exclude patterns + if (shouldExcludeOutput(outputName, excludeOutputs)) { + continue; + } + + const { + bytes, + entryPoint, + imports, + exports, + inputs: outputInputs, + ...additionalProps + } = outputInfo; + + const unifiedOutput: UnifiedStatsBundle = { + path: outputName, + bytes, + }; + + if (entryPoint !== undefined) { + unifiedOutput.entryPoint = entryPoint; + } + + unifiedOutput.imports = imports + ? imports.map((imp) => { + const unifiedImport: UnifiedStatsImport = { + path: imp.path, + kind: imp.kind, + }; + + if ('original' in imp && typeof imp.original === 'string') { + unifiedImport.original = imp.original; + } + + return unifiedImport; + }) + : []; + + Object.assign(unifiedOutput, additionalProps); + + if (outputInputs) { + const inputKeys = Object.keys(outputInputs); + if (inputKeys.length > 0) { + const inputs: Record = {}; + + for (const inputKey of inputKeys) { + const inputPath = inputKey!; + const outputInputInfo = outputInputs[inputPath]; + + if (outputInputInfo?.bytesInOutput !== undefined) { + inputs[inputPath] = { + bytes: outputInputInfo.bytesInOutput, + }; + } + } + + unifiedOutput.inputs = inputs; + } else { + unifiedOutput.inputs = {}; + } + } else { + unifiedOutput.inputs = {}; + } + + result[outputName] = unifiedOutput; + } + + return result; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.unit.test.ts new file mode 100644 index 0000000..196c061 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.unit.test.ts @@ -0,0 +1,261 @@ +import { describe, expect, it } from 'vitest'; +import { unifyBundlerStats, type EsBuildCoreStats } from './unify.esbuild.js'; + +describe('unifyBundlerStats', () => { + it('should only consider outputs and provide default values', () => { + const esbuildStats: EsBuildCoreStats = { + inputs: {}, + outputs: { + 'dist/index.js': { + bytes: 100, + }, + }, + }; + expect(unifyBundlerStats(esbuildStats, {})).toStrictEqual({ + 'dist/index.js': { + path: 'dist/index.js', + bytes: 100, + imports: [], + inputs: {}, + }, + }); + }); + + it('should parse inputs correctly', () => { + expect( + unifyBundlerStats( + { + inputs: {}, + outputs: { + 'dist/index.js': { + bytes: 100, + inputs: { + 'src/index.ts': { + bytesInOutput: 100, + }, + }, + }, + }, + }, + {}, + ), + ).toStrictEqual({ + 'dist/index.js': expect.objectContaining({ + inputs: { + 'src/index.ts': { + bytes: 100, + }, + }, + }), + }); + }); + + it('should parse imports correctly', () => { + expect( + unifyBundlerStats( + { + inputs: {}, + outputs: { + 'dist/index.js': { + bytes: 100, + imports: [ + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + ], + }, + }, + }, + {}, + ), + ).toStrictEqual({ + 'dist/index.js': expect.objectContaining({ + imports: [ + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + ], + }), + }); + }); + + it('should preserve original import paths when present', () => { + expect( + unifyBundlerStats( + { + inputs: {}, + outputs: { + 'dist/index.js': { + bytes: 100, + imports: [ + { + path: 'node_modules/rxjs/dist/esm/internal/util/isFunction.js', + kind: 'import-statement', + original: './util/isFunction', + }, + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + ], + }, + }, + }, + {}, + ), + ).toStrictEqual({ + 'dist/index.js': expect.objectContaining({ + imports: [ + { + path: 'node_modules/rxjs/dist/esm/internal/util/isFunction.js', + kind: 'import-statement', + original: './util/isFunction', + }, + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + ], + }), + }); + }); + + it('should unify esbuild stats into unified stats structure', () => { + const esbuildStats: EsBuildCoreStats = { + inputs: {}, + outputs: { + 'dist/index.js': { + imports: [ + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + { + path: 'dist/chunks/feature-2-X2YVDBQK.js', + kind: 'dynamic-import', + }, + ], + exports: ['default', 'indexOnlyFunction'], + entryPoint: 'src/index.ts', + inputs: { + 'src/index.ts': { + bytesInOutput: 350, + }, + }, + bytes: 496, + }, + 'dist/bin.js': { + imports: [ + { + path: 'dist/chunks/chunk-WIJM4GGD.js', + kind: 'import-statement', + }, + ], + exports: [], + entryPoint: 'src/bin.ts', + inputs: { + 'src/bin.ts': { + bytesInOutput: 366, + }, + }, + bytes: 479, + }, + 'dist/chunks/chunk-WIJM4GGD.js': { + imports: [], + exports: ['calculate', 'externalFunction'], + inputs: { + 'src/lib/utils/format.ts': { + bytesInOutput: 269, + }, + 'src/lib/feature-1.ts': { + bytesInOutput: 269, + }, + 'src/lib/utils/math.ts': { + bytesInOutput: 145, + }, + }, + bytes: 806, + }, + 'dist/chunks/feature-2-X2YVDBQK.js': { + imports: [], + exports: ['chart'], + entryPoint: 'src/lib/feature-2.ts', + inputs: { + 'src/lib/feature-2.ts': { + bytesInOutput: 38, + }, + }, + bytes: 82, + }, + }, + }; + + expect(unifyBundlerStats(esbuildStats, {})).toStrictEqual({ + 'dist/bin.js': { + bytes: 479, + entryPoint: 'src/bin.ts', + imports: [ + { + kind: 'import-statement', + path: 'dist/chunks/chunk-WIJM4GGD.js', + }, + ], + inputs: { + 'src/bin.ts': { + bytes: 366, + }, + }, + path: 'dist/bin.js', + }, + 'dist/chunks/chunk-WIJM4GGD.js': { + bytes: 806, + imports: [], + inputs: { + 'src/lib/feature-1.ts': { + bytes: 269, + }, + 'src/lib/utils/format.ts': { + bytes: 269, + }, + 'src/lib/utils/math.ts': { + bytes: 145, + }, + }, + path: 'dist/chunks/chunk-WIJM4GGD.js', + }, + 'dist/chunks/feature-2-X2YVDBQK.js': { + bytes: 82, + entryPoint: 'src/lib/feature-2.ts', + imports: [], + inputs: { + 'src/lib/feature-2.ts': { + bytes: 38, + }, + }, + path: 'dist/chunks/feature-2-X2YVDBQK.js', + }, + 'dist/index.js': { + bytes: 496, + entryPoint: 'src/index.ts', + imports: [ + { + kind: 'import-statement', + path: 'dist/chunks/chunk-WIJM4GGD.js', + }, + { + kind: 'dynamic-import', + path: 'dist/chunks/feature-2-X2YVDBQK.js', + }, + ], + inputs: { + 'src/index.ts': { + bytes: 350, + }, + }, + path: 'dist/index.js', + }, + }); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.ts new file mode 100644 index 0000000..9b8e60d --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.ts @@ -0,0 +1,236 @@ +import type { + UnifiedStats, + UnifiedStatsBundle, +} from './unified-stats.types.js'; + +export type RsbuildImportKind = 'import-statement' | 'dynamic-import'; + +export type RsbuildReason = { + moduleIdentifier: string | null; + module: string | null; + moduleName: string | null; + type: string; + userRequest: string; + loc: string; + active: boolean; + moduleId: string | null; + resolvedModuleId: string | null; +}; + +export type RsbuildAsset = { + type: string; + name: string; + size: number; + emitted: boolean; + cached: boolean; + chunkNames: string[]; + chunkIdHints: string[]; + chunks: string[]; + auxiliaryChunks: string[]; +}; + +export type RsbuildModule = { + type: string; + moduleType: string; + size: number; + sizes: Record; + built: boolean; + codeGenerated: boolean; + buildTimeExecuted: boolean; + cached: boolean; + identifier: string; + name: string; + nameForCondition?: string; + index: number; + preOrderIndex: number; + index2: number; + postOrderIndex: number; + cacheable: boolean; + optional: boolean; + orphan: boolean; + dependent?: boolean; + issuer?: string | null; + issuerName?: string | null; + issuerPath?: { + identifier: string; + name: string; + id: string; + }[]; + failed: boolean; + errors: number; + warnings: number; + id: string; + issuerId?: string; + chunks: string[]; + assets: string[]; + reasons: RsbuildReason[]; + usedExports: string[] | null; + providedExports?: string[]; + optimizationBailout: string[]; + depth: number; +}; + +export type RsbuildChunk = { + type: string; + rendered: boolean; + initial: boolean; + entry: boolean; + reason?: string; + size: number; + sizes: Record; + names: string[]; + idHints: string[]; + runtime: string[]; + files: string[]; + auxiliaryFiles: string[]; + hash: string; + childrenByOrder: Record; + id: string; + siblings: string[]; + parents: string[]; + children: string[]; + modules: RsbuildModule[]; + origins: { + module: string; + moduleIdentifier: string; + moduleName: string; + loc: string; + request: string; + moduleId: string; + }[]; +}; + +export type RsbuildEntrypoint = { + name: string; + chunks: string[]; + assets: { name: string; size: number }[]; + filteredAssets: number; + assetsSize: number; + auxiliaryAssets: { name: string; size: number }[]; + auxiliaryAssetsSize: number; + children: Record; + childAssets: Record; + isOverSizeLimit: boolean; +}; + +export type RsbuildCoreStats = { + name: string; + hash: string; + version: string; + rspackVersion: string; + time: number; + builtAt: number; + publicPath: string; + outputPath: string; + assetsByChunkName: Record; + assets: RsbuildAsset[]; + chunks: RsbuildChunk[]; + modules: RsbuildModule[]; + entrypoints: Record; + namedChunkGroups: Record; + errors: unknown[]; + errorsCount: number; + warnings: unknown[]; + warningsCount: number; + children: unknown[]; +}; + +export function unifyBundlerStats(stats: RsbuildCoreStats): UnifiedStats { + const result: UnifiedStats = {}; + + const chunksMap = new Map(); + for (const chunk of stats.chunks) { + chunksMap.set(chunk.id, chunk); + } + + for (const asset of stats.assets) { + if (!asset.name.endsWith('.js')) { + continue; + } + + const unifiedOutput: UnifiedStatsBundle = { + path: asset.name, + bytes: asset.size, + imports: [], + inputs: {}, + }; + + for (const [_entryName, entrypoint] of Object.entries(stats.entrypoints)) { + if ( + entrypoint.assets.some((entryAsset) => entryAsset.name === asset.name) + ) { + const entryChunks = entrypoint.chunks; + for (const chunkId of entryChunks) { + const chunk = chunksMap.get(chunkId); + if (chunk?.entry) { + const entryModule = chunk.modules.find((module) => + module.reasons.some((reason) => reason.type === 'entry'), + ); + if (entryModule) { + unifiedOutput.entryPoint = entryModule.name; + break; + } + } + } + break; + } + } + + for (const chunkId of asset.chunks) { + const chunk = chunksMap.get(chunkId); + if (!chunk) { + continue; + } + + for (const module of chunk.modules) { + if (module.moduleType === 'runtime') { + continue; + } + + if (unifiedOutput.inputs) { + unifiedOutput.inputs[module.name] = { + bytes: module.size, + }; + } + + for (const reason of module.reasons) { + if (reason.type === 'import()') { + if (unifiedOutput.imports) { + unifiedOutput.imports.push({ + path: reason.userRequest, + kind: 'dynamic-import', + original: reason.userRequest, + }); + } + } else if ( + (reason.type === 'esm import' || + reason.type === 'esm import specifier') && + unifiedOutput.imports + ) { + unifiedOutput.imports.push({ + path: reason.userRequest, + kind: 'import-statement', + original: reason.userRequest, + }); + } + } + } + } + + if (unifiedOutput.imports) { + const uniqueImports = unifiedOutput.imports.filter( + (importItem, index, self) => + index === + self.findIndex( + (item) => + item.path === importItem.path && item.kind === importItem.kind, + ), + ); + unifiedOutput.imports = uniqueImports; + } + + result[asset.name] = unifiedOutput; + } + + return result; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.unit.test.ts new file mode 100644 index 0000000..b9333f2 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.unit.test.ts @@ -0,0 +1,583 @@ +import { describe, expect, it } from 'vitest'; +import { unifyBundlerStats, type RsbuildCoreStats } from './unify.rsbuild.js'; + +describe('unifyBundlerStats', () => { + it('should transform realistic rsbuild stats with multiple assets, chunks, and complex module dependencies', () => { + const rsbuildStats: RsbuildCoreStats = { + name: 'web', + hash: 'f7f35d6bcb429212', + version: '5.75.0', + rspackVersion: '1.4.6', + time: 18, + builtAt: 1_752_462_348_764, + publicPath: '/', + outputPath: '/dist/rsbuild', + assetsByChunkName: { + index: ['static/js/index.js'], + }, + assets: [ + { + type: 'asset', + name: 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js', + size: 79_545, + emitted: true, + cached: false, + chunkNames: [], + chunkIdHints: ['vendors'], + chunks: ['vendors-node_modules_minimatch_dist_esm_index_js'], + auxiliaryChunks: [], + }, + { + type: 'asset', + name: 'static/js/index.js', + size: 38_142, + emitted: true, + cached: false, + chunkNames: ['index'], + chunkIdHints: [], + chunks: ['index'], + auxiliaryChunks: [], + }, + { + type: 'asset', + name: 'static/js/async/src_lib_feature-2_ts.js', + size: 708, + emitted: true, + cached: false, + chunkNames: [], + chunkIdHints: [], + chunks: ['src_lib_feature-2_ts'], + auxiliaryChunks: [], + }, + { + type: 'asset', + name: 'index.html', + size: 242, + emitted: true, + cached: false, + chunkNames: [], + chunkIdHints: [], + chunks: [], + auxiliaryChunks: [], + }, + ], + chunks: [ + { + type: 'chunk', + rendered: true, + initial: true, + entry: true, + size: 1384, + sizes: { + javascript: 1384, + runtime: 32_421, + }, + names: ['index'], + idHints: [], + runtime: ['index'], + files: ['static/js/index.js'], + auxiliaryFiles: ['static/js/index.js.map'], + hash: '9529fef35c1c4eed', + childrenByOrder: {}, + id: 'index', + siblings: [], + parents: [], + children: [ + 'src_lib_feature-2_ts', + 'vendors-node_modules_minimatch_dist_esm_index_js', + ], + modules: [ + { + type: 'module', + moduleType: 'javascript/auto', + size: 461, + sizes: { + javascript: 461, + }, + built: true, + codeGenerated: true, + buildTimeExecuted: false, + cached: false, + identifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + name: './src/index.ts', + nameForCondition: '/src/index.ts', + index: 0, + preOrderIndex: 0, + index2: 3, + postOrderIndex: 3, + cacheable: true, + optional: false, + orphan: false, + dependent: false, + failed: false, + errors: 0, + warnings: 0, + id: './src/index.ts', + chunks: ['index'], + assets: [], + reasons: [ + { + moduleIdentifier: null, + module: null, + moduleName: null, + type: 'entry', + userRequest: './src/index.ts', + loc: 'index', + active: true, + moduleId: null, + resolvedModuleId: null, + }, + ], + usedExports: null, + providedExports: ['default', 'indexOnlyFunction'], + optimizationBailout: [], + depth: 0, + }, + { + type: 'module', + moduleType: 'javascript/auto', + size: 376, + sizes: { + javascript: 376, + }, + built: true, + codeGenerated: true, + buildTimeExecuted: false, + cached: false, + identifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-1.ts', + name: './src/lib/feature-1.ts', + nameForCondition: '/src/lib/feature-1.ts', + index: 1, + preOrderIndex: 1, + index2: 1, + postOrderIndex: 1, + cacheable: true, + optional: false, + orphan: false, + dependent: true, + issuer: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + issuerName: './src/index.ts', + failed: false, + errors: 0, + warnings: 0, + id: './src/lib/feature-1.ts', + issuerId: './src/index.ts', + chunks: ['index'], + assets: [], + reasons: [ + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + module: './src/index.ts', + moduleName: './src/index.ts', + type: 'esm import', + userRequest: './lib/feature-1', + loc: '1:0-51', + active: true, + moduleId: './src/index.ts', + resolvedModuleId: './src/index.ts', + }, + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + module: './src/index.ts', + moduleName: './src/index.ts', + type: 'esm import specifier', + userRequest: './lib/feature-1', + loc: '6:79-95', + active: true, + moduleId: './src/index.ts', + resolvedModuleId: './src/index.ts', + }, + ], + usedExports: null, + providedExports: ['default', 'externalFunction'], + optimizationBailout: [], + depth: 1, + }, + { + type: 'module', + moduleType: 'javascript/auto', + size: 172, + sizes: { + javascript: 172, + }, + built: true, + codeGenerated: true, + buildTimeExecuted: false, + cached: false, + identifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/utils/math.ts', + name: './src/lib/utils/math.ts', + nameForCondition: '/src/lib/utils/math.ts', + index: 3, + preOrderIndex: 3, + index2: 2, + postOrderIndex: 2, + cacheable: true, + optional: false, + orphan: false, + dependent: true, + issuer: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + issuerName: './src/index.ts', + failed: false, + errors: 0, + warnings: 0, + id: './src/lib/utils/math.ts', + issuerId: './src/index.ts', + chunks: ['index'], + assets: [], + reasons: [ + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + module: './src/index.ts', + moduleName: './src/index.ts', + type: 'esm import', + userRequest: './lib/utils/math', + loc: '2:0-45', + active: true, + moduleId: './src/index.ts', + resolvedModuleId: './src/index.ts', + }, + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + module: './src/index.ts', + moduleName: './src/index.ts', + type: 'esm import specifier', + userRequest: './lib/utils/math', + loc: '6:30-39', + active: true, + moduleId: './src/index.ts', + resolvedModuleId: './src/index.ts', + }, + ], + usedExports: null, + providedExports: ['add', 'calculate', 'multiply'], + optimizationBailout: [], + depth: 1, + }, + ], + origins: [ + { + module: '', + moduleIdentifier: '', + moduleName: '', + loc: 'index', + request: './src/index.ts', + moduleId: 'index', + }, + ], + }, + { + type: 'chunk', + rendered: true, + initial: false, + entry: false, + size: 147, + sizes: { + javascript: 147, + }, + names: [], + idHints: [], + runtime: ['index'], + files: ['static/js/async/src_lib_feature-2_ts.js'], + auxiliaryFiles: ['static/js/async/src_lib_feature-2_ts.js.map'], + hash: '30813a925289ba1f', + childrenByOrder: {}, + id: 'src_lib_feature-2_ts', + siblings: ['vendors-node_modules_minimatch_dist_esm_index_js'], + parents: ['index'], + children: [], + modules: [ + { + type: 'module', + moduleType: 'javascript/auto', + size: 147, + sizes: { + javascript: 147, + }, + built: true, + codeGenerated: true, + buildTimeExecuted: false, + cached: false, + identifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts', + name: './src/lib/feature-2.ts', + nameForCondition: '/src/lib/feature-2.ts', + index: 4, + preOrderIndex: 4, + index2: 12, + postOrderIndex: 12, + cacheable: true, + optional: false, + orphan: false, + dependent: false, + issuer: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + issuerName: './src/index.ts', + failed: false, + errors: 0, + warnings: 0, + id: './src/lib/feature-2.ts', + issuerId: './src/index.ts', + chunks: ['src_lib_feature-2_ts'], + assets: [], + reasons: [ + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + module: './src/index.ts', + moduleName: './src/index.ts', + type: 'import()', + userRequest: './lib/feature-2', + loc: '4:28-53', + active: true, + moduleId: './src/index.ts', + resolvedModuleId: './src/index.ts', + }, + ], + usedExports: null, + providedExports: ['chart'], + optimizationBailout: [], + depth: 1, + }, + ], + origins: [ + { + module: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + moduleName: './src/index.ts', + loc: '4:28-53', + request: './lib/feature-2', + moduleId: './src/index.ts', + }, + ], + }, + { + type: 'chunk', + rendered: true, + initial: false, + entry: false, + reason: 'split chunk (cache group: defaultVendors)', + size: 75_559, + sizes: { + javascript: 75_559, + }, + names: [], + idHints: ['vendors'], + runtime: ['index'], + files: [ + 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js', + ], + auxiliaryFiles: [ + 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js.map', + ], + hash: '204484fe4072555f', + childrenByOrder: {}, + id: 'vendors-node_modules_minimatch_dist_esm_index_js', + siblings: ['src_lib_feature-2_ts'], + parents: ['index'], + children: [], + modules: [ + { + type: 'module', + moduleType: 'javascript/esm', + size: 39_098, + sizes: { + javascript: 39_098, + }, + built: true, + codeGenerated: true, + buildTimeExecuted: false, + cached: false, + identifier: + 'javascript/esm|/node_modules/minimatch/dist/esm/index.js', + name: '../../../../../node_modules/minimatch/dist/esm/index.js', + nameForCondition: '/node_modules/minimatch/dist/esm/index.js', + index: 5, + preOrderIndex: 5, + index2: 11, + postOrderIndex: 11, + cacheable: true, + optional: false, + orphan: false, + dependent: false, + issuer: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts', + issuerName: './src/lib/feature-2.ts', + failed: false, + errors: 0, + warnings: 0, + id: '../../../../../node_modules/minimatch/dist/esm/index.js', + issuerId: './src/lib/feature-2.ts', + chunks: ['vendors-node_modules_minimatch_dist_esm_index_js'], + assets: [], + reasons: [ + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts', + module: './src/lib/feature-2.ts', + moduleName: './src/lib/feature-2.ts', + type: 'esm import', + userRequest: 'minimatch', + loc: '1:0-38', + active: true, + moduleId: './src/lib/feature-2.ts', + resolvedModuleId: './src/lib/feature-2.ts', + }, + { + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts', + module: './src/lib/feature-2.ts', + moduleName: './src/lib/feature-2.ts', + type: 'esm import specifier', + userRequest: 'minimatch', + loc: '3:11-20', + active: true, + moduleId: './src/lib/feature-2.ts', + resolvedModuleId: './src/lib/feature-2.ts', + }, + ], + usedExports: null, + providedExports: [ + 'AST', + 'GLOBSTAR', + 'Minimatch', + 'braceExpand', + 'defaults', + 'escape', + 'filter', + 'makeRe', + 'match', + 'minimatch', + 'sep', + 'unescape', + ], + optimizationBailout: [], + depth: 2, + }, + ], + origins: [ + { + module: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + moduleIdentifier: + 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts', + moduleName: './src/index.ts', + loc: '4:28-53', + request: './lib/feature-2', + moduleId: './src/index.ts', + }, + ], + }, + ], + modules: [], + entrypoints: { + index: { + name: 'index', + chunks: ['index'], + assets: [{ name: 'static/js/index.js', size: 38_142 }], + filteredAssets: 0, + assetsSize: 38_142, + auxiliaryAssets: [{ name: 'static/js/index.js.map', size: 45_982 }], + auxiliaryAssetsSize: 45_982, + children: {}, + childAssets: {}, + isOverSizeLimit: false, + }, + }, + namedChunkGroups: { + index: { + name: 'index', + chunks: ['index'], + assets: [{ name: 'static/js/index.js', size: 38_142 }], + filteredAssets: 0, + assetsSize: 38_142, + auxiliaryAssets: [{ name: 'static/js/index.js.map', size: 45_982 }], + auxiliaryAssetsSize: 45_982, + children: {}, + childAssets: {}, + isOverSizeLimit: false, + }, + }, + errors: [], + errorsCount: 0, + warnings: [], + warningsCount: 0, + children: [], + }; + + const result = unifyBundlerStats(rsbuildStats); + + expect(result).toEqual({ + 'static/js/index.js': { + path: 'static/js/index.js', + bytes: 38_142, + imports: [ + { + path: './lib/feature-1', + kind: 'import-statement', + original: './lib/feature-1', + }, + { + path: './lib/utils/math', + kind: 'import-statement', + original: './lib/utils/math', + }, + ], + inputs: { + './src/index.ts': { + bytes: 461, + }, + './src/lib/feature-1.ts': { + bytes: 376, + }, + './src/lib/utils/math.ts': { + bytes: 172, + }, + }, + entryPoint: './src/index.ts', + }, + 'static/js/async/src_lib_feature-2_ts.js': { + path: 'static/js/async/src_lib_feature-2_ts.js', + bytes: 708, + imports: [ + { + path: './lib/feature-2', + kind: 'dynamic-import', + original: './lib/feature-2', + }, + ], + inputs: { + './src/lib/feature-2.ts': { + bytes: 147, + }, + }, + }, + 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js': { + path: 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js', + bytes: 79_545, + imports: [ + { + path: 'minimatch', + kind: 'import-statement', + original: 'minimatch', + }, + ], + inputs: { + '../../../../../node_modules/minimatch/dist/esm/index.js': { + bytes: 39_098, + }, + }, + }, + }); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.ts new file mode 100644 index 0000000..e7876f9 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.ts @@ -0,0 +1,260 @@ +import { minimatch } from 'minimatch'; +import type { + UnifiedStats, + UnifiedStatsBundle, + UnifiedStatsImport, +} from './unified-stats.types.js'; + +export type SondaResourceKind = 'asset' | 'filesystem'; +export type SondaResourceType = 'script' | 'style' | 'font' | 'image' | 'other'; +const IMPORT_KIND = 'import' as const; +const ENTRYPOINT_KIND = 'entrypoint' as const; +const DYNAMIC_IMPORT_KIND = 'dynamic-import' as const; + +export type SondaConnectionKind = + | typeof IMPORT_KIND + | typeof ENTRYPOINT_KIND + | typeof DYNAMIC_IMPORT_KIND; + +export type SondaResource = { + kind: SondaResourceKind; + name: string; + type: SondaResourceType; + uncompressed: number; + gzip?: number; + brotli?: number; + format?: string; +}; + +export type SondaConnection = { + kind: SondaConnectionKind; + source: string; + target: string; + original: string | null; +}; + +export type SondaCoreStats = { + metadata: { + version: string; + integration: string; + sources: boolean; + gzip: boolean; + brotli: boolean; + }; + resources: SondaResource[]; + connections: SondaConnection[]; + dependencies: unknown[]; + issues: unknown[]; + sourcemaps: unknown[]; +}; + +export type SondaUnifyOptions = { + excludeOutputs?: string[]; +}; + +/** + * Checks if path matches any exclude pattern. Filters unwanted files from bundle stats. + */ +function shouldExcludeOutput( + outputPath: string, + excludePatterns: string[], +): boolean { + return excludePatterns.some((pattern) => minimatch(outputPath, pattern)); +} + +const UNIFIED_DYNAMIC_IMPORT = 'dynamic-import' as const; +const UNIFIED_IMPORT_STATEMENT = 'import-statement' as const; + +type UnifiedImportKind = + | typeof UNIFIED_DYNAMIC_IMPORT + | typeof UNIFIED_IMPORT_STATEMENT; + +/** + * Converts Sonda connection kind to unified import kind + */ +function mapConnectionKind(kind: SondaConnectionKind): UnifiedImportKind { + return kind === DYNAMIC_IMPORT_KIND + ? UNIFIED_DYNAMIC_IMPORT + : UNIFIED_IMPORT_STATEMENT; +} + +export function unifyBundlerStats( + stats: SondaCoreStats, + options: SondaUnifyOptions, +): UnifiedStats { + const { excludeOutputs = ['**/*.map', '**/*.d.ts'] } = options; + + // Filter asset resources (outputs) + const assets = stats.resources.filter((r) => r.kind === 'asset'); + const filesystemResources = stats.resources.filter( + (r) => r.kind === 'filesystem', + ); + + // Build a map of entrypoints: output -> source + const entryPointMap = new Map(); + for (const conn of stats.connections) { + if (conn.kind === ENTRYPOINT_KIND) { + entryPointMap.set(conn.target, conn.source); + } + } + + // Build a map of imports for each output + const outputImportsMap = new Map(); + const outputInputsMap = new Map>(); + + // Process connections to build import relationships + for (const conn of stats.connections) { + if (conn.kind === IMPORT_KIND || conn.kind === DYNAMIC_IMPORT_KIND) { + // Find which output this source belongs to by tracing entrypoints + const sourceFile = conn.source; + + // For each asset, check if this source is part of its dependency tree + for (const asset of assets) { + const entryPoint = entryPointMap.get(asset.name); + if ( + entryPoint && + isPartOfDependencyTree(sourceFile, entryPoint, stats.connections) + ) { + const imports = outputImportsMap.get(asset.name) || []; + imports.push({ + path: conn.target, + kind: mapConnectionKind(conn.kind), + ...(conn.original && { original: conn.original }), + }); + outputImportsMap.set(asset.name, imports); + } + } + } + } + + // Build inputs map for each output + for (const asset of assets) { + const entryPoint = entryPointMap.get(asset.name); + if (entryPoint) { + const inputsMap = new Map(); + + // Add the entry point itself + const entryResource = filesystemResources.find( + (r) => r.name === entryPoint, + ); + if (entryResource) { + inputsMap.set(entryPoint, entryResource.uncompressed); + } + + // Add all dependencies + const deps = getAllDependencies(entryPoint, stats.connections); + for (const dep of deps) { + const depResource = filesystemResources.find((r) => r.name === dep); + if (depResource) { + inputsMap.set(dep, depResource.uncompressed); + } + } + + outputInputsMap.set(asset.name, inputsMap); + } + } + + const result: UnifiedStats = {}; + + for (const asset of assets) { + // Skip outputs that match exclude patterns + if (shouldExcludeOutput(asset.name, excludeOutputs)) { + continue; + } + + const unifiedOutput: UnifiedStatsBundle = { + path: asset.name, + bytes: asset.uncompressed, + imports: outputImportsMap.get(asset.name) || [], + inputs: {}, + }; + + const entryPoint = entryPointMap.get(asset.name); + if (entryPoint) { + unifiedOutput.entryPoint = entryPoint; + } + + const inputsMap = outputInputsMap.get(asset.name); + if (inputsMap) { + for (const [inputPath, bytes] of inputsMap) { + unifiedOutput.inputs![inputPath] = { bytes }; + } + } + + result[asset.name] = unifiedOutput; + } + + return result; +} + +/** + * Check if a source file is part of the dependency tree of an entry point + */ +function isPartOfDependencyTree( + source: string, + entryPoint: string, + connections: SondaConnection[], +): boolean { + if (source === entryPoint) { + return true; + } + + const visited = new Set(); + const queue = [entryPoint]; + + while (queue.length > 0) { + const current = queue.shift()!; + if (visited.has(current)) { + continue; + } + visited.add(current); + + if (current === source) { + return true; + } + + // Find all imports from current + for (const conn of connections) { + if ( + conn.source === current && + (conn.kind === IMPORT_KIND || conn.kind === DYNAMIC_IMPORT_KIND) + ) { + queue.push(conn.target); + } + } + } + + return false; +} + +/** + * Get all dependencies of a source file + */ +function getAllDependencies( + source: string, + connections: SondaConnection[], +): string[] { + const deps = new Set(); + const visited = new Set(); + const queue = [source]; + + while (queue.length > 0) { + const current = queue.shift()!; + if (visited.has(current)) { + continue; + } + visited.add(current); + + for (const conn of connections) { + if ( + conn.source === current && + (conn.kind === IMPORT_KIND || conn.kind === DYNAMIC_IMPORT_KIND) + ) { + deps.add(conn.target); + queue.push(conn.target); + } + } + } + + return [...deps]; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.unit.test.ts new file mode 100644 index 0000000..b634230 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.unit.test.ts @@ -0,0 +1,465 @@ +import { describe, expect, it } from 'vitest'; +import { type SondaCoreStats, unifyBundlerStats } from './unify.sonda.js'; + +describe('unifyBundlerStats (Sonda)', () => { + it('should handle minimal stats with single asset', () => { + const sondaStats: SondaCoreStats = { + metadata: { + version: '0.10.1', + integration: 'esbuild', + sources: false, + gzip: false, + brotli: false, + }, + resources: [ + { + kind: 'asset', + name: 'dist/index.js', + type: 'script', + uncompressed: 100, + }, + ], + connections: [], + dependencies: [], + issues: [], + sourcemaps: [], + }; + + expect(unifyBundlerStats(sondaStats, {})).toStrictEqual({ + 'dist/index.js': { + path: 'dist/index.js', + bytes: 100, + imports: [], + inputs: {}, + }, + }); + }); + + it('should map entrypoints correctly', () => { + const sondaStats: SondaCoreStats = { + metadata: { + version: '0.10.1', + integration: 'esbuild', + sources: false, + gzip: false, + brotli: false, + }, + resources: [ + { + kind: 'asset', + name: 'dist/index.js', + type: 'script', + uncompressed: 100, + }, + { + kind: 'filesystem', + name: 'src/index.ts', + type: 'script', + format: 'esm', + uncompressed: 100, + }, + ], + connections: [ + { + kind: 'entrypoint', + source: 'src/index.ts', + target: 'dist/index.js', + original: null, + }, + ], + dependencies: [], + issues: [], + sourcemaps: [], + }; + + expect(unifyBundlerStats(sondaStats, {})).toStrictEqual({ + 'dist/index.js': { + path: 'dist/index.js', + bytes: 100, + entryPoint: 'src/index.ts', + imports: [], + inputs: { + 'src/index.ts': { + bytes: 100, + }, + }, + }, + }); + }); + + it('should parse imports and build dependency tree', () => { + const sondaStats: SondaCoreStats = { + metadata: { + version: '0.10.1', + integration: 'esbuild', + sources: false, + gzip: false, + brotli: false, + }, + resources: [ + { + kind: 'asset', + name: 'dist/index.js', + type: 'script', + uncompressed: 200, + }, + { + kind: 'filesystem', + name: 'src/index.ts', + type: 'script', + format: 'esm', + uncompressed: 100, + }, + { + kind: 'filesystem', + name: 'src/lib/utils.ts', + type: 'script', + format: 'esm', + uncompressed: 50, + }, + ], + connections: [ + { + kind: 'entrypoint', + source: 'src/index.ts', + target: 'dist/index.js', + original: null, + }, + { + kind: 'import', + source: 'src/index.ts', + target: 'src/lib/utils.ts', + original: './lib/utils', + }, + ], + dependencies: [], + issues: [], + sourcemaps: [], + }; + + expect(unifyBundlerStats(sondaStats, {})).toStrictEqual({ + 'dist/index.js': { + path: 'dist/index.js', + bytes: 200, + entryPoint: 'src/index.ts', + imports: [ + { + path: 'src/lib/utils.ts', + kind: 'import-statement', + original: './lib/utils', + }, + ], + inputs: { + 'src/index.ts': { + bytes: 100, + }, + 'src/lib/utils.ts': { + bytes: 50, + }, + }, + }, + }); + }); + + it('should handle dynamic imports', () => { + const sondaStats: SondaCoreStats = { + metadata: { + version: '0.10.1', + integration: 'esbuild', + sources: false, + gzip: false, + brotli: false, + }, + resources: [ + { + kind: 'asset', + name: 'dist/index.js', + type: 'script', + uncompressed: 150, + }, + { + kind: 'filesystem', + name: 'src/index.ts', + type: 'script', + format: 'esm', + uncompressed: 100, + }, + { + kind: 'filesystem', + name: 'src/lib/lazy.ts', + type: 'script', + format: 'esm', + uncompressed: 50, + }, + ], + connections: [ + { + kind: 'entrypoint', + source: 'src/index.ts', + target: 'dist/index.js', + original: null, + }, + { + kind: 'dynamic-import', + source: 'src/index.ts', + target: 'src/lib/lazy.ts', + original: './lib/lazy', + }, + ], + dependencies: [], + issues: [], + sourcemaps: [], + }; + + expect(unifyBundlerStats(sondaStats, {})).toStrictEqual({ + 'dist/index.js': { + path: 'dist/index.js', + bytes: 150, + entryPoint: 'src/index.ts', + imports: [ + { + path: 'src/lib/lazy.ts', + kind: 'dynamic-import', + original: './lib/lazy', + }, + ], + inputs: { + 'src/index.ts': { + bytes: 100, + }, + 'src/lib/lazy.ts': { + bytes: 50, + }, + }, + }, + }); + }); + + it('should exclude outputs matching patterns', () => { + const sondaStats: SondaCoreStats = { + metadata: { + version: '0.10.1', + integration: 'esbuild', + sources: false, + gzip: false, + brotli: false, + }, + resources: [ + { + kind: 'asset', + name: 'dist/index.js', + type: 'script', + uncompressed: 100, + }, + { + kind: 'asset', + name: 'dist/index.js.map', + type: 'other', + uncompressed: 200, + }, + ], + connections: [], + dependencies: [], + issues: [], + sourcemaps: [], + }; + + const result = unifyBundlerStats(sondaStats, { + excludeOutputs: ['**/*.map'], + }); + + expect(result).toStrictEqual({ + 'dist/index.js': { + path: 'dist/index.js', + bytes: 100, + imports: [], + inputs: {}, + }, + }); + expect(result['dist/index.js.map']).toBeUndefined(); + }); + + it('should handle complex multi-entry bundle with shared chunks', () => { + const sondaStats: SondaCoreStats = { + metadata: { + version: '0.10.1', + integration: 'esbuild', + sources: false, + gzip: false, + brotli: false, + }, + resources: [ + { + kind: 'asset', + name: 'dist/index.js', + type: 'script', + uncompressed: 496, + }, + { + kind: 'asset', + name: 'dist/bin.js', + type: 'script', + uncompressed: 479, + }, + { + kind: 'asset', + name: 'dist/chunks/chunk.js', + type: 'script', + uncompressed: 806, + }, + { + kind: 'filesystem', + name: 'src/index.ts', + type: 'script', + format: 'esm', + uncompressed: 350, + }, + { + kind: 'filesystem', + name: 'src/bin.ts', + type: 'script', + format: 'esm', + uncompressed: 366, + }, + { + kind: 'filesystem', + name: 'src/lib/feature-1.ts', + type: 'script', + format: 'esm', + uncompressed: 269, + }, + { + kind: 'filesystem', + name: 'src/lib/utils/format.ts', + type: 'script', + format: 'esm', + uncompressed: 269, + }, + { + kind: 'filesystem', + name: 'src/lib/utils/math.ts', + type: 'script', + format: 'esm', + uncompressed: 145, + }, + ], + connections: [ + { + kind: 'entrypoint', + source: 'src/index.ts', + target: 'dist/index.js', + original: null, + }, + { + kind: 'entrypoint', + source: 'src/bin.ts', + target: 'dist/bin.js', + original: null, + }, + { + kind: 'import', + source: 'src/index.ts', + target: 'src/lib/feature-1.ts', + original: './lib/feature-1', + }, + { + kind: 'import', + source: 'src/bin.ts', + target: 'src/lib/feature-1.ts', + original: './lib/feature-1', + }, + { + kind: 'import', + source: 'src/lib/feature-1.ts', + target: 'src/lib/utils/format.ts', + original: './utils/format', + }, + { + kind: 'import', + source: 'src/lib/feature-1.ts', + target: 'src/lib/utils/math.ts', + original: './utils/math', + }, + ], + dependencies: [], + issues: [], + sourcemaps: [], + }; + + const result = unifyBundlerStats(sondaStats, {}); + + expect(result['dist/index.js']).toStrictEqual({ + path: 'dist/index.js', + bytes: 496, + entryPoint: 'src/index.ts', + imports: [ + { + path: 'src/lib/feature-1.ts', + kind: 'import-statement', + original: './lib/feature-1', + }, + { + path: 'src/lib/utils/format.ts', + kind: 'import-statement', + original: './utils/format', + }, + { + path: 'src/lib/utils/math.ts', + kind: 'import-statement', + original: './utils/math', + }, + ], + inputs: { + 'src/index.ts': { + bytes: 350, + }, + 'src/lib/feature-1.ts': { + bytes: 269, + }, + 'src/lib/utils/format.ts': { + bytes: 269, + }, + 'src/lib/utils/math.ts': { + bytes: 145, + }, + }, + }); + + expect(result['dist/bin.js']).toStrictEqual({ + path: 'dist/bin.js', + bytes: 479, + entryPoint: 'src/bin.ts', + imports: [ + { + path: 'src/lib/feature-1.ts', + kind: 'import-statement', + original: './lib/feature-1', + }, + { + path: 'src/lib/utils/format.ts', + kind: 'import-statement', + original: './utils/format', + }, + { + path: 'src/lib/utils/math.ts', + kind: 'import-statement', + original: './utils/math', + }, + ], + inputs: { + 'src/bin.ts': { + bytes: 366, + }, + 'src/lib/feature-1.ts': { + bytes: 269, + }, + 'src/lib/utils/format.ts': { + bytes: 269, + }, + 'src/lib/utils/math.ts': { + bytes: 145, + }, + }, + }); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.vite.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.vite.ts new file mode 100644 index 0000000..31a9d5f --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.vite.ts @@ -0,0 +1,74 @@ +import type { + UnifiedStats, + UnifiedStatsBundle, +} from './unified-stats.types.js'; + +export type ViteAsset = { + name: string; + size: number; +}; + +export type ViteModule = { + name: string; + size: number; + chunks: string[]; +}; + +export type ViteChunk = { + id: string; + names: string[]; + files: string[]; + entry: boolean; + initial: boolean; +}; + +export type ViteCoreStats = { + builtAt: number; + assets: ViteAsset[]; + chunks: ViteChunk[]; + modules: ViteModule[]; +}; + +/** + * Converts Vite bundle stats to unified format. Processes assets, chunks, and modules for bundle analysis. + */ +export function unifyBundlerStats(stats: ViteCoreStats): UnifiedStats { + const result: UnifiedStats = {}; + + // Filter out non-JS assets (like source maps) + const jsAssets = stats.assets.filter((asset) => asset.name.endsWith('.js')); + + for (const asset of jsAssets) { + const unifiedOutput: UnifiedStatsBundle = { + path: asset.name, + bytes: asset.size, + imports: [], + inputs: {}, + }; + + // Find the chunk that contains this asset + const chunk = stats.chunks.find((c) => c.files.includes(asset.name)); + if (chunk) { + // Set entry point if it's an entry chunk + if (chunk.entry && chunk.names.length > 0) { + unifiedOutput.entryPoint = chunk.names[0]; + } + + // Find modules that belong to this chunk + const chunkModules = + stats.modules?.filter((module) => module.chunks.includes(chunk.id)) || + []; + + // Add inputs + for (const module of chunkModules) { + unifiedOutput.inputs![module.name] = { + bytes: module.size, + }; + } + } + + result[asset.name] = unifiedOutput; + } + + return result; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.ts new file mode 100644 index 0000000..17a2211 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.ts @@ -0,0 +1,160 @@ +import type { + UnifiedStats, + UnifiedStatsBundle, +} from './unified-stats.types.js'; + +export type WebpackImportKind = 'import-statement' | 'dynamic-import'; + +export type WebpackReason = { + moduleIdentifier: string | null; + module: string | null; + moduleName: string | null; + type: string; + userRequest: string; + loc: string; +}; + +export type WebpackAsset = { + name: string; + size: number; + chunks: string[]; + chunkNames: string[]; + emitted: boolean; + type: string; +}; + +export type WebpackModule = { + identifier: string; + name: string; + size: number; + chunks: string[]; + depth: number | null; + reasons: WebpackReason[]; + type: string; + moduleType: string; + issuer: string | null; + issuerName: string | null; + providedExports?: string[]; +}; + +export type WebpackChunk = { + id: string; + names: string[]; + files: string[]; + size: number; + modules: WebpackModule[]; + parents: string[]; + children: string[]; + entry: boolean; + initial: boolean; + runtime?: string[]; +}; + +export type WebpackEntrypoint = { + name: string; + chunks: string[]; + assets: { name: string; size: number }[]; +}; + +export type WebpackCoreStats = { + assets: WebpackAsset[]; + chunks: WebpackChunk[]; + modules: WebpackModule[]; + entrypoints: Record; +}; + +export function unifyBundlerStats(stats: WebpackCoreStats): UnifiedStats { + const result: UnifiedStats = {}; + + const chunksMap = new Map(); + for (const chunk of stats.chunks) { + chunksMap.set(chunk.id, chunk); + } + + for (const asset of stats.assets) { + const unifiedOutput: UnifiedStatsBundle = { + path: asset.name, + bytes: asset.size, + imports: [], + inputs: {}, + }; + + for (const [_entryName, entrypoint] of Object.entries(stats.entrypoints)) { + if ( + entrypoint.assets.some((entryAsset) => entryAsset.name === asset.name) + ) { + const entryChunks = entrypoint.chunks; + for (const chunkId of entryChunks) { + const chunk = chunksMap.get(chunkId); + if (chunk?.entry) { + const entryModule = chunk.modules.find((module) => + module.reasons.some((reason) => reason.type === 'entry'), + ); + if (entryModule) { + unifiedOutput.entryPoint = entryModule.name; + break; + } + } + } + break; + } + } + + for (const chunkId of asset.chunks) { + const chunk = chunksMap.get(chunkId); + if (!chunk) { + continue; + } + + for (const module of chunk.modules) { + if (module.type === 'runtime') { + continue; + } + + if (unifiedOutput.inputs) { + unifiedOutput.inputs[module.name] = { + bytes: module.size, + }; + } + + for (const reason of module.reasons) { + if (reason.type === 'import()') { + if (unifiedOutput.imports) { + unifiedOutput.imports.push({ + path: reason.userRequest, + kind: 'dynamic-import', + original: reason.userRequest, + }); + } + } else if ( + (reason.type === 'harmony side effect evaluation' || + reason.type === 'harmony import specifier') && + unifiedOutput.imports + ) { + unifiedOutput.imports.push({ + path: reason.userRequest, + kind: 'import-statement', + original: reason.userRequest, + }); + } + } + } + } + + if (unifiedOutput.imports) { + const uniqueImports = unifiedOutput.imports.filter( + (importItem, index, self) => + index === + self.findIndex( + (item) => + item.path === importItem.path && item.kind === importItem.kind, + ), + ); + unifiedOutput.imports = uniqueImports; + } + + result[asset.name] = unifiedOutput; + } + + return result; +} diff --git a/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.unit.test.ts b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.unit.test.ts new file mode 100644 index 0000000..327858a --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.unit.test.ts @@ -0,0 +1,101 @@ +import { describe, expect, it } from 'vitest'; +import { unifyBundlerStats, type WebpackCoreStats } from './unify.webpack.js'; + +describe('unifyBundlerStats', () => { + it('should transform basic webpack stats with assets and chunks', () => { + const webpackStats: WebpackCoreStats = { + assets: [ + { + name: 'bundle.js', + size: 16_823, + chunks: ['main'], + chunkNames: ['main'], + emitted: true, + type: 'asset', + }, + ], + chunks: [ + { + id: 'main', + names: ['main'], + files: ['bundle.js'], + size: 8415, + modules: [ + { + identifier: './src/index.ts', + name: './src/index.ts', + size: 463, + chunks: ['main'], + depth: 0, + reasons: [ + { + moduleIdentifier: null, + module: null, + moduleName: null, + type: 'entry', + userRequest: './src/index.ts', + loc: 'main', + }, + ], + type: 'module', + moduleType: 'javascript/auto', + issuer: null, + issuerName: null, + providedExports: ['default', 'indexOnlyFunction'], + }, + ], + parents: [], + children: [], + entry: true, + initial: true, + runtime: ['main'], + }, + ], + modules: [ + { + identifier: './src/index.ts', + name: './src/index.ts', + size: 463, + chunks: ['main'], + depth: 0, + reasons: [ + { + moduleIdentifier: null, + module: null, + moduleName: null, + type: 'entry', + userRequest: './src/index.ts', + loc: 'main', + }, + ], + type: 'module', + moduleType: 'javascript/auto', + issuer: null, + issuerName: null, + providedExports: ['default', 'indexOnlyFunction'], + }, + ], + entrypoints: { + main: { + name: 'main', + chunks: ['main'], + assets: [{ name: 'bundle.js', size: 16_823 }], + }, + }, + }; + + expect(unifyBundlerStats(webpackStats)).toStrictEqual({ + 'bundle.js': { + path: 'bundle.js', + bytes: 16_823, + imports: [], + inputs: { + './src/index.ts': { + bytes: 463, + }, + }, + entryPoint: './src/index.ts', + }, + }); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/runner/utils.ts b/packages/plugin-bundle-stats/src/lib/runner/utils.ts new file mode 100644 index 0000000..117f96e --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/runner/utils.ts @@ -0,0 +1,65 @@ +import { minimatch } from 'minimatch'; +import type { AuditOutput } from '@code-pushup/models'; +import { formatBytes } from '@code-pushup/utils'; +import type { BundleStatsConfig } from './types.js'; +import type { UnifiedStats } from './unify/unified-stats.types.js'; + +export function filterUnifiedTreeByConfig( + bundleStats: UnifiedStats, + config: BundleStatsConfig[], +): UnifiedStats { + return config.reduce((acc, configItem) => { + const filteredStats = filterUnifiedTreeByConfigSingle( + bundleStats, + configItem, + ); + return { ...acc, ...filteredStats }; + }, {}); +} + +export function filterUnifiedTreeByConfigSingle( + bundleStats: UnifiedStats, + config: BundleStatsConfig, +): UnifiedStats | null { + const { selection } = config; + const includePatterns = selection.includeOutputs ?? []; + const excludePatterns = selection.excludeOutputs ?? []; + + const filteredStats: UnifiedStats = {}; + + for (const [path, stats] of Object.entries(bundleStats)) { + const included = + includePatterns.length === 0 || + includePatterns.some((pattern: string) => minimatch(path, pattern)); + const excluded = excludePatterns.some((pattern: string) => + minimatch(path, pattern), + ); + + if (included && !excluded) { + filteredStats[path] = stats; + } + } + + return Object.keys(filteredStats).length > 0 ? filteredStats : null; +} + +export function createDisplayValue( + totalBytes: number, + fileCount: number, +): string { + const formattedBytes = formatBytes(totalBytes); + const formattedFileCount = `${fileCount} file${fileCount === 1 ? '' : 's'}`; + return `${formattedBytes} (${formattedFileCount})`; +} + +export function createEmptyAudit(config: BundleStatsConfig): AuditOutput { + return { + slug: config.slug, + score: 0, + value: 0, + displayValue: createDisplayValue(0, 0), + details: { + issues: [], + }, + }; +} diff --git a/packages/plugin-bundle-stats/src/lib/stats-generation.int.test.ts b/packages/plugin-bundle-stats/src/lib/stats-generation.int.test.ts new file mode 100644 index 0000000..76d4ae6 --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/stats-generation.int.test.ts @@ -0,0 +1,189 @@ +import { cp } from 'node:fs/promises'; +import path from 'node:path'; +import { beforeAll, describe, expect, it } from 'vitest'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + teardownTestFolder, +} from '@code-pushup/test-utils'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; + +const FIXTURES_DIR = path.join( + 'packages', + 'plugin-bundle-stats', + 'mocks', + 'fixtures', +); + +const tmpRoot = path.join(E2E_ENVIRONMENTS_DIR, 'plugin-bundle-stats'); + +const tmpTestOutputRoot = path.join(tmpRoot, TEST_OUTPUT_DIR); + +const fixtureSharedRoot = path.join(FIXTURES_DIR, 'node-minimal'); + +const SNAPSHOTS_DIR = path.join( + 'packages', + 'plugin-bundle-stats', + 'src', + 'lib', + '__snapshots__', +); + +describe.todo('esbuild stats generation', () => { + const tmpEsbuild = path.join(tmpTestOutputRoot, 'esbuild-stats'); + const esbuildDistDir = path.join(tmpEsbuild, 'dist'); + + beforeAll(async () => { + await cp(fixtureSharedRoot, tmpEsbuild, { + recursive: true, + }); + }); + + afterAll(async () => { + await teardownTestFolder(tmpEsbuild); + }); + + it('should create stats.json using esbuild', async () => { + // Copy esbuild configuration + await cp(path.join(FIXTURES_DIR, 'esbuild'), tmpEsbuild, { + recursive: true, + }); + + const { code } = await executeProcess({ + command: 'node', + args: ['esbuild.config.cjs'], + cwd: tmpEsbuild, + }); + + expect(code).toBe(0); + + const statsPath = path.join(esbuildDistDir, 'stats.json'); + const stats = (await readJsonFile(statsPath)) as Record; + + expect(stats).toEqual( + expect.objectContaining({ + inputs: expect.any(Object), + outputs: expect.objectContaining({ + 'dist/index.js': expect.any(Object), + 'dist/bin.js': expect.any(Object), + }), + }), + ); + + await cp(statsPath, path.join(SNAPSHOTS_DIR, 'esbuild.stats.json')); + }); +}); + +describe.todo('webpack stats generation', () => { + const tmpWebpack = path.join(tmpTestOutputRoot, 'webpack-stats'); + const webpackDistDir = path.join(tmpWebpack, 'dist'); + + beforeAll(async () => { + await cp(fixtureSharedRoot, tmpWebpack, { + recursive: true, + }); + }); + + afterAll(async () => { + await teardownTestFolder(tmpWebpack); + }); + + it('should create stats.json using webpack@5', async () => { + await cp(path.join(FIXTURES_DIR, 'webpack'), tmpWebpack, { + recursive: true, + }); + + const { code } = await executeProcess({ + command: 'node', + args: ['webpack-build.cjs'], + cwd: tmpWebpack, + }); + + expect(code).toBe(0); + + const statsPath = path.join(webpackDistDir, 'stats.json'); + const rawStats = (await readJsonFile(statsPath)) as Record; + + expect(rawStats).toEqual( + expect.objectContaining({ + modules: expect.arrayContaining([ + expect.objectContaining({ + name: expect.stringMatching(/src\/index/), + }), + expect.objectContaining({ + name: expect.stringMatching(/src\/utils/), + }), + ]), + assets: expect.arrayContaining([ + expect.objectContaining({ + name: expect.stringMatching(/bundle\.js/), + }), + ]), + }), + ); + + await cp(statsPath, path.join(SNAPSHOTS_DIR, 'webpack.stats.json')); + }); +}); + +describe.todo('rsbuild stats generation', () => { + const tmpRsbuild = path.join(tmpTestOutputRoot, 'rsbuild-stats'); + const rsbuildDistDir = path.join(tmpRsbuild, 'dist'); + + beforeAll(async () => { + await cp(fixtureSharedRoot, tmpRsbuild, { + recursive: true, + }); + }); + + afterAll(async () => { + await teardownTestFolder(tmpRsbuild); + }); + + it('should create stats.json using rsbuild', async () => { + await executeProcess({ + command: 'mkdir', + args: ['-p', 'dist'], + cwd: tmpRsbuild, + }); + + await cp(path.join(FIXTURES_DIR, 'rsbuild'), path.join(tmpRsbuild), { + recursive: true, + }); + + await cp(fixtureSharedRoot, path.join(tmpRsbuild, 'src'), { + recursive: true, + }); + + const { code } = await executeProcess({ + command: 'node', + args: ['rsbuild-build.cjs'], + cwd: tmpRsbuild, + }); + + expect(code).toBe(0); + + const statsPath = path.join(rsbuildDistDir, 'stats.json'); + const rawStats = (await readJsonFile(statsPath)) as Record; + + expect(rawStats).toEqual( + expect.objectContaining({ + modules: expect.arrayContaining([ + expect.objectContaining({ + name: expect.stringMatching(/src\/index/), + }), + expect.objectContaining({ + name: expect.stringMatching(/src\/utils/), + }), + ]), + assets: expect.arrayContaining([ + expect.objectContaining({ + name: expect.stringMatching(/bundle\.js/), + }), + ]), + }), + ); + + await cp(statsPath, path.join(SNAPSHOTS_DIR, 'rsbuild.stats.json')); + }); +}); diff --git a/packages/plugin-bundle-stats/src/lib/types.ts b/packages/plugin-bundle-stats/src/lib/types.ts new file mode 100644 index 0000000..35dd23d --- /dev/null +++ b/packages/plugin-bundle-stats/src/lib/types.ts @@ -0,0 +1,81 @@ +import type { Group, PluginArtifactOptions } from '@code-pushup/models'; +import type { InsightsTableConfig } from './runner/audits/details/table.js'; +import type { DependencyTreeConfig } from './runner/audits/details/tree.js'; +import type { PenaltyConfig, ScoringConfig } from './runner/audits/scoring.js'; +import type { SupportedBundlers } from './runner/types.js'; + +export type SelectionGeneralConfig = { + include?: string[]; + exclude?: string[]; +}; + +export type PluginDependencyTreeOptions = Omit< + Partial, + 'enabled' +>; + +export type DependencyTreeOptions = DependencyTreeConfig; + +export type SelectionOptions = SelectionGeneralConfig & { + mode?: 'bundle' | 'matchingOnly' | 'withStartupDeps' | 'withAllDeps'; + includeOutputs?: string[]; + excludeOutputs?: string[]; + includeInputs?: string[]; + excludeInputs?: string[]; + includeImports?: string[]; + excludeImports?: string[]; + includeEntryPoints?: string[]; + excludeEntryPoints?: string[]; +}; + +export type PluginSelectionOptions = Omit< + SelectionOptions, + | 'include' + | 'includeOutputs' + | 'includeInputs' + | 'includeImports' + | 'includeEntryPoints' +>; + +export type PenaltyOptions = Omit & { + artefactSize?: PenaltyConfig['artefactSize'] | number; +}; + +export type ScoringOptions = { + enabled?: boolean; + totalSize?: ScoringConfig['totalSize'] | number; + penalty?: PenaltyOptions; +}; + +export type PluginPenaltyOptions = Omit; + +export type PluginScoringOptions = { + penalty?: PluginPenaltyOptions; +}; + +export type InsightsTableOptions = InsightsTableConfig | false; +export type PluginInsightsTableOptions = InsightsTableConfig | false; + +export type BundleStatsAuditOptions = { + slug?: string; + title: string; + description?: string; + selection?: SelectionOptions; + scoring?: ScoringOptions; + dependencyTree?: DependencyTreeOptions; + insightsTable?: InsightsTableOptions; +}; + +export type PluginBundleStatsAuditOptions = { + selection?: PluginSelectionOptions; + scoring?: PluginScoringOptions; + dependencyTree?: PluginDependencyTreeOptions; + insightsTable?: PluginInsightsTableOptions; +}; + +export type PluginOptions = { + groups?: Group[]; + bundler: SupportedBundlers; + audits: BundleStatsAuditOptions[]; +} & PluginBundleStatsAuditOptions & + PluginArtifactOptions; diff --git a/packages/plugin-bundle-stats/tsconfig.json b/packages/plugin-bundle-stats/tsconfig.json new file mode 100644 index 0000000..893f9a9 --- /dev/null +++ b/packages/plugin-bundle-stats/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": ["vitest"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.test.json" + } + ] +} diff --git a/packages/plugin-bundle-stats/tsconfig.lib.json b/packages/plugin-bundle-stats/tsconfig.lib.json new file mode 100644 index 0000000..ef2f7e2 --- /dev/null +++ b/packages/plugin-bundle-stats/tsconfig.lib.json @@ -0,0 +1,16 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": ["node"] + }, + "include": ["src/**/*.ts"], + "exclude": [ + "vite.config.unit.ts", + "vite.config.integration.ts", + "src/**/*.test.ts", + "src/**/*.mock.ts", + "mocks/**/*.ts" + ] +} diff --git a/packages/plugin-bundle-stats/tsconfig.test.json b/packages/plugin-bundle-stats/tsconfig.test.json new file mode 100644 index 0000000..8400081 --- /dev/null +++ b/packages/plugin-bundle-stats/tsconfig.test.json @@ -0,0 +1,18 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"] + }, + "include": [ + "vitest.int.config.ts", + "vitest.unit.config.ts", + "mocks/**/*.ts", + "src/**/*.test.ts", + "src/**/*.test.tsx", + "src/**/*.test.js", + "src/**/*.test.jsx", + "src/**/*.d.ts", + "../../testing/test-setup/src/vitest.d.ts" + ] +} diff --git a/packages/plugin-bundle-stats/vitest.int.config.ts b/packages/plugin-bundle-stats/vitest.int.config.ts new file mode 100644 index 0000000..0d8f5fc --- /dev/null +++ b/packages/plugin-bundle-stats/vitest.int.config.ts @@ -0,0 +1,3 @@ +import { createIntTestConfig } from '../../testing/test-setup-config/src/index.js'; + +export default createIntTestConfig('plugin-bundle-stats'); diff --git a/packages/plugin-bundle-stats/vitest.unit.config.ts b/packages/plugin-bundle-stats/vitest.unit.config.ts new file mode 100644 index 0000000..d5bb087 --- /dev/null +++ b/packages/plugin-bundle-stats/vitest.unit.config.ts @@ -0,0 +1,3 @@ +import { createUnitTestConfig } from '../../testing/test-setup-config/src/index.js'; + +export default createUnitTestConfig('plugin-bundle-stats'); From c01213e83fe9e18e805df5a3bbcc8f83dc997eb3 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 10 Dec 2025 17:28:45 +0100 Subject: [PATCH 2/7] refactor: wip --- .../.eslint/eslint-report.json | 5272 ----------------- 1 file changed, 5272 deletions(-) delete mode 100644 packages/plugin-bundle-stats/.eslint/eslint-report.json diff --git a/packages/plugin-bundle-stats/.eslint/eslint-report.json b/packages/plugin-bundle-stats/.eslint/eslint-report.json deleted file mode 100644 index d8eccac..0000000 --- a/packages/plugin-bundle-stats/.eslint/eslint-report.json +++ /dev/null @@ -1,5272 +0,0 @@ -[ - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.large-angular.config.ts", - "messages": [ - { - "ruleId": null, - "nodeType": null, - "fatal": true, - "severity": 2, - "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.large-angular.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 1, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import bundleStatsPlugin from './src/index.js';\nimport { GroupingRule } from './src/lib/runner/types.js';\nimport { BundleStatsAuditOptions } from './src/lib/types.js';\n\ntype PatternList = string[];\n\nconst allFilesGroups: GroupingRule[] = [\n {\n title: 'Internal Packages',\n includeInputs: ['**/packages/**'],\n icon: '🟣',\n numSegments: 1,\n },\n {\n title: 'External Dependencies',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n numSegments: 1,\n },\n];\n\nconst allFilesAudit: BundleStatsAuditOptions = {\n slug: 'all-files',\n title: '🗂️ All Files',\n description: `\nAnalyzes **complete bundle composition**, identifies **architectural patterns**, tracks **package distribution**, and reveals **size contributors** across all bundle artifacts.`,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*'],\n excludeOutputs: ['**/*.map', '**/*.d.ts'],\n },\n insightsTable: {\n mode: 'all',\n groups: allFilesGroups,\n },\n dependencyTree: { enabled: false },\n};\n\nconst initialBundleSizeTableGroups: GroupingRule[] = [\n {\n title: 'Blacklisted/Deprecated',\n icon: '🚫',\n includeInputs: [\n '**/node_modules/lodash/**',\n '**/node_modules/zone.js/**',\n '**/node_modules/smoothscroll-polyfill/**',\n '**/node_modules/web-animations-js/**',\n '**/node_modules/decimal.js/**',\n '**/node_modules/@storybook/**',\n '**/node_modules/jest/**',\n '**/packages/themepark/**',\n ],\n },\n {\n title: 'Lazy-loaded',\n icon: '⏳',\n includeInputs: [\n '**/node_modules/socket.io-client/**',\n '**/node_modules/launchdarkly-js-client-sdk/**',\n '**/node_modules/@microsoft/**',\n '**/node_modules/ngx-scrollbar/**',\n '**/node_modules/howler/**',\n '**/node_modules/hls.js/**',\n '**/node_modules/lottie-web/**',\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/ua-parser-js/**',\n ],\n },\n {\n title: 'Angular',\n includeInputs: [\n '**/node_modules/*angular*/**',\n '**/node_modules/@ng*/**',\n '**/node_modules/@ngx-*/**',\n '**/node_modules/ngx-*/**',\n '**/node_modules/ng-*/**',\n ],\n icon: '🅰️',\n numSegments: 2,\n },\n {\n title: 'Third-party',\n icon: '📚',\n includeInputs: [\n '**/node_modules/react/**',\n '**/node_modules/lodash-es/**',\n '**/node_modules/rxjs/**',\n '**/node_modules/moment/**',\n '**/node_modules/dayjs/**',\n ],\n numSegments: 2,\n },\n {\n title: 'Product',\n icon: '🎮',\n includeInputs: [\n '**/packages/payments/**',\n '**/packages/casino/**',\n '**/packages/bingo/**',\n '**/packages/sports/**',\n '**/packages/poker/**',\n '**/packages/lottery/**',\n '**/packages/horseracing/**',\n '**/packages/oxygen/**',\n '**/packages/myaccount/**',\n '**/packages/promo/**',\n '**/packages/mokabingo/**',\n ],\n numSegments: 2,\n },\n {\n title: 'Internal utils',\n icon: '🔧',\n includeInputs: [\n '**/packages/design-system/**',\n '**/packages/utils/**',\n '**/packages/shared/**',\n '**/packages/common/**',\n ],\n },\n {\n title: 'Node modules',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n];\n\nconst initialBundleSizeTreeGroups: GroupingRule[] = [\n {\n includeInputs: ['**/node_modules/*angular*/**'],\n icon: '🅰️',\n numSegments: 2,\n },\n {\n title: 'Design System',\n includeInputs: ['**/packages/design-system/**'],\n icon: '🟣',\n },\n {\n title: 'Deprecated Theme',\n includeInputs: ['**/packages/themepark/**'],\n icon: '🚫',\n },\n {\n includeInputs: ['**/packages/**'],\n icon: '🟣',\n numSegments: 2,\n },\n {\n title: 'Payments',\n includeInputs: ['**/packages/payments/**'],\n icon: '💳',\n },\n {\n title: 'Casino',\n includeInputs: ['**/packages/casino/**'],\n icon: '🎰',\n },\n {\n title: 'Bingo',\n includeInputs: ['**/packages/bingo/**'],\n icon: '🎯',\n },\n {\n title: 'Sports',\n includeInputs: ['**/packages/sports/**'],\n icon: '⚽',\n },\n {\n title: 'Poker',\n includeInputs: ['**/packages/poker/**'],\n icon: '🃏',\n },\n {\n title: 'Lottery',\n includeInputs: ['**/packages/lottery/**'],\n icon: '🎲',\n },\n {\n title: 'Horse Racing',\n includeInputs: ['**/packages/horseracing/**'],\n icon: '🐎',\n },\n {\n title: 'Oxygen',\n includeInputs: ['**/packages/oxygen/**'],\n icon: '🫧',\n },\n {\n title: 'My Account',\n includeInputs: ['**/packages/myaccount/**'],\n icon: '👤',\n },\n {\n title: 'Promotions',\n includeInputs: ['**/packages/promo/**'],\n icon: '🎁',\n },\n {\n title: 'Moka Bingo',\n includeInputs: ['**/packages/mokabingo/**'],\n icon: '🎯',\n },\n {\n title: 'React',\n includeInputs: ['**/node_modules/react/**'],\n icon: '⚛️',\n },\n {\n title: 'Lodash ES',\n includeInputs: ['**/node_modules/lodash-es/**'],\n icon: '🔧',\n },\n {\n title: 'Node Modules',\n includeInputs: ['**/node_modules/**'],\n numSegments: 2,\n },\n];\n\nconst initialBundleSizeAudit: BundleStatsAuditOptions = {\n slug: 'initial-bundle-size',\n title: '🔥 Initial Bundle Size',\n description: `\nMonitors **critical loading performance**, enforces **size budgets**, detects **bloat sources**, and prevents **slow startup times** in main application bundles.`,\n selection: {\n mode: 'withStartupDeps',\n includeOutputs: ['**/main*.js', '**/polyfill*.js', '**/styles*.css'],\n excludeOutputs: ['**/*.map', '**/*.d.ts'],\n },\n scoring: {\n totalSize: 1_000_000,\n penalty: {\n artefactSize: [100, 100_000],\n },\n },\n insightsTable: {\n mode: 'all',\n groups: initialBundleSizeTableGroups,\n },\n dependencyTree: {\n groups: initialBundleSizeTreeGroups,\n },\n};\n\nconst blacklist = [\n // IMMEDIATE PRIORITY - Dead dependency, can be removed immediately\n {\n pattern: '**/node_modules/angular2-toaster/**',\n hint: '`angular2-toaster` is deprecated and unused. Please remove from package.json - already replaced by `ds-toast`.',\n },\n\n // HIGH PRIORITY - Full DS alternative available\n {\n pattern: '**/node_modules/ngx-float-ui/**',\n hint: '`ngx-float-ui` is being replaced by `ds-tooltip` for consistency and reduced dependencies. The DS tooltip supports 4 positions and 3 arrow positions with advanced overlay integration.',\n },\n\n // MEDIUM PRIORITY - DS alternatives available but need extensions\n {\n pattern: '**/node_modules/@angular-slider/ngx-slider/**',\n hint: '`@angular-slider/ngx-slider` adds significant bundle size. `ds-range-selector` is available but needs custom case extensions from HoneyBadgers team. For new code only: use `ds-range-selector`.',\n },\n\n {\n pattern: '**/node_modules/ngx-slider-v2/**',\n hint: '`ngx-slider-v2` bundle impact unknown and appears less maintained than @angular-slider/ngx-slider. `ds-range-selector` available but needs custom case extensions. For new code only: use `ds-range-selector`.',\n },\n\n {\n pattern: '**/node_modules/ngx-toastr/**',\n hint: '`ngx-toastr` adds significant bundle size. Consider `ds-toast` for new components. Service pattern migration pending - missing show/hide programmatic API. Contact HoneyBadgers team for service API.',\n },\n\n // LOW PRIORITY - Strategic migration candidates\n {\n pattern: '**/node_modules/@angular/material/dialog/**',\n hint: 'Consider `ds-modal` or `ds-dialog` for new components. Existing usage can remain until strategic migration phase due to complexity.',\n },\n\n {\n pattern: '**/node_modules/@angular/material/slider/**',\n hint: '`ds-range-selector` available but needs validation for Material slider compatibility and feature coverage. For new code only: use `ds-range-selector`.',\n },\n\n {\n pattern: '**/node_modules/@angular/material/bottom-sheet/**',\n hint: 'Consider `ds-modal` with bottom positioning for new components. Existing bottom-sheet usage can remain until strategic migration.',\n },\n];\n\nconst blacklistedFilesGroups: GroupingRule[] = [\n {\n title: 'Legacy/Deprecated',\n icon: '🕸️',\n includeInputs: [\n '**/node_modules/core-js/**',\n '**/node_modules/zone.js/**',\n '**/node_modules/smoothscroll-polyfill/**',\n '**/node_modules/web-animations-js/**',\n '**/node_modules/decimal.js/**',\n '**/node_modules/@storybook/**',\n '**/node_modules/jest/**',\n ],\n },\n {\n title: 'Blacklisted',\n icon: '🚫',\n includeInputs: [\n '**/node_modules/lodash/**',\n // New blacklisted dependencies with DS alternatives\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular-slider/ngx-slider/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular/material/dialog/**',\n '**/node_modules/@angular/material/slider/**',\n '**/node_modules/@angular/material/bottom-sheet/**',\n ],\n },\n];\n\nconst angularSpecificTableGroups: GroupingRule[] = [\n {\n includeInputs: [\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/angular2-toaster/**',\n ],\n icon: '🚨',\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular-slider/**',\n ],\n icon: '🚫',\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@ng-bootstrap/**',\n '**/node_modules/ng-circle-progress/**',\n ],\n icon: '🕸️',\n numSegments: 2,\n },\n {\n includeInputs: ['**/node_modules/ngx-float-ui/**'],\n icon: '⚠️',\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@angular/core/**',\n '**/node_modules/@angular/common/**',\n '**/node_modules/@angular/platform-browser/**',\n '**/node_modules/@angular/platform-browser-dynamic/**',\n '**/node_modules/@angular/forms/**',\n '**/node_modules/@angular/router/**',\n '**/node_modules/@angular/animations/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@angular/material/**',\n '**/node_modules/@angular/cdk/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@ngrx/**',\n '**/node_modules/@rx-angular/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/ngx-daterangepicker-material/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-scrollbar/**',\n ],\n numSegments: 2,\n },\n {\n includeInputs: [\n '**/node_modules/@ngx-translate/**',\n '**/node_modules/ng-dynamic-component/**',\n '**/node_modules/ng-in-viewport/**',\n '**/node_modules/ng-lazyload-image/**',\n '**/node_modules/angularx-qrcode/**',\n '**/node_modules/ngx-lottie/**',\n '**/node_modules/ngx-popperjs/**',\n '**/node_modules/@ngu/**',\n ],\n numSegments: 2,\n },\n {\n title: 'Other Angular Packages',\n includeInputs: [\n '**/node_modules/angular*/**',\n '**/node_modules/ng-*/**',\n '**/node_modules/ngx-*/**',\n '**/node_modules/@ng*/**',\n '**/node_modules/*angular*/**',\n ],\n },\n];\n\nconst angularSpecificTreeGroups: GroupingRule[] = angularSpecificTableGroups;\n\nconst angularSpecificAudit: BundleStatsAuditOptions = {\n slug: 'angular-ecosystem',\n title: '🅰️ Angular Ecosystem',\n description: `\n**Security-first Angular analysis**: Identifies **security vulnerabilities**, **blacklisted packages**, **deprecated dependencies**, and **oversized components** to ensure a secure and optimized Angular application.`,\n selection: {\n mode: 'matchingOnly',\n includeInputs: [\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular-slider/**',\n '**/node_modules/@ng-bootstrap/**',\n '**/node_modules/ng-circle-progress/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular/core/**',\n '**/node_modules/@angular/common/**',\n '**/node_modules/@angular/platform-browser/**',\n '**/node_modules/@angular/platform-browser-dynamic/**',\n '**/node_modules/@angular/forms/**',\n '**/node_modules/@angular/router/**',\n '**/node_modules/@angular/animations/**',\n '**/node_modules/@angular/material/**',\n '**/node_modules/@angular/cdk/**',\n '**/node_modules/@ngrx/**',\n '**/node_modules/@rx-angular/**',\n '**/node_modules/ngx-daterangepicker-material/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-scrollbar/**',\n '**/node_modules/@ngx-translate/**',\n '**/node_modules/ng-dynamic-component/**',\n '**/node_modules/ng-in-viewport/**',\n '**/node_modules/angularx-qrcode/**',\n '**/node_modules/ngx-lottie/**',\n '**/node_modules/ngx-popperjs/**',\n '**/node_modules/sports-animations/**',\n ],\n excludeInputs: ['**/*.map', '**/*.d.ts'],\n },\n insightsTable: {\n mode: 'onlyMatching',\n groups: angularSpecificTableGroups,\n },\n dependencyTree: {\n mode: 'onlyMatching',\n groups: angularSpecificTreeGroups,\n },\n};\n\nconst dependencyAuditBlacklistedGroup: GroupingRule = {\n icon: '🚫',\n includeInputs: [\n '**/node_modules/react/**',\n '**/node_modules/react-dom/**',\n '**/node_modules/lodash/**',\n '**/node_modules/underscore/**',\n '**/node_modules/@babel/**',\n '**/node_modules/moment/**',\n '**/node_modules/ng-lazyload-image/**',\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular-slider/ngx-slider/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular/material/dialog/**',\n '**/node_modules/@angular/material/slider/**',\n '**/node_modules/@angular/material/bottom-sheet/**',\n ],\n numSegments: 2,\n};\n\nconst dependencyAuditLegacyGroup: GroupingRule = {\n icon: '🕸️',\n includeInputs: [\n '**/node_modules/core-js/**',\n '**/node_modules/zone.js/**',\n '**/node_modules/smoothscroll-polyfill/**',\n '**/node_modules/decimal.js/**',\n ],\n numSegments: 2,\n};\n\nconst dependencyAuditAcceptedGroup: GroupingRule = {\n title: 'Accepted Dependencies',\n icon: '✅',\n includeInputs: [\n '**/node_modules/@module-federation/**',\n '**/node_modules/launchdarkly-js-client-sdk/**',\n '**/node_modules/socket.io-client/**',\n '**/node_modules/@microsoft/**',\n '**/node_modules/qrcode/**',\n '**/node_modules/dompurify/**',\n '**/node_modules/hammerjs/**',\n '**/node_modules/js-sha512/**',\n '**/node_modules/ua-parser-js/**',\n '**/node_modules/pixi-multistyle-text/**',\n '**/node_modules/howler/**',\n '**/node_modules/tslib/**',\n '**/node_modules/@incodetech/**',\n '**/node_modules/@emotion/**',\n '**/node_modules/scheduler/**',\n '**/node_modules/@jumio/**',\n '**/node_modules/moment-timezone/**',\n '**/node_modules/@pixi/**',\n '**/node_modules/gsap/**',\n '**/node_modules/qs/**',\n '**/node_modules/url/**',\n '**/node_modules/object-inspect/**',\n '**/node_modules/get-intrinsic/**',\n '**/node_modules/fontfaceobserver/**',\n '**/node_modules/earcut/**',\n '**/node_modules/pixi.js/**',\n '**/node_modules/sports-animations/**',\n '**/node_modules/konva/**',\n '**/node_modules/live-sports-visualization/**',\n '**/node_modules/@img-arena/**',\n '**/node_modules/@seontechnologies/**',\n '**/node_modules/jspdf/**',\n '**/node_modules/fflate/**',\n '**/node_modules/braintree-web/**',\n '**/node_modules/lodash-es/**',\n '**/node_modules/@floating-ui/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@rtms/**',\n '**/node_modules/@push-based/**',\n '**/node_modules/rxjs/**',\n '**/node_modules/bwin-tweenmax/**',\n '**/node_modules/swiper/**',\n '**/node_modules/bwin-winwheel/**',\n '**/node_modules/canvg/**',\n '**/node_modules/svg-pathdata/**',\n '**/node_modules/rgbcolor/**',\n '**/node_modules/stackblur-canvas/**',\n '**/node_modules/xml2js/**',\n '**/node_modules/buffer/**',\n '**/node_modules/sax/**',\n '**/node_modules/events/**',\n '**/node_modules/string_decoder/**',\n '**/node_modules/stream/**',\n '**/node_modules/primeng/**',\n '**/node_modules/ngx-daterangepicker-material/**',\n '**/node_modules/jspdf-autotable/**',\n '**/node_modules/dayjs/**',\n '**/node_modules/dexie/**',\n '**/node_modules/ng-lazyload-image/**',\n '**/node_modules/@opentelemetry/**',\n '**/node_modules/html2canvas/**',\n '**/node_modules/fastdom/**',\n '**/node_modules/base64-js/**',\n '**/node_modules/component-emitter/**',\n '**/node_modules/dijkstrajs/**',\n '**/node_modules/parseuri/**',\n '**/node_modules/has-symbols/**',\n '**/node_modules/function-bind/**',\n '**/node_modules/object-assign/**',\n '**/node_modules/raf/**',\n '**/node_modules/blob/**',\n '**/node_modules/ieee754/**',\n '**/node_modules/has-binary2/**',\n '**/node_modules/side-channel-weakmap/**',\n '**/node_modules/js-levenshtein/**',\n '**/node_modules/safe-buffer/**',\n '**/node_modules/detect-it/**',\n '**/node_modules/side-channel-list/**',\n '**/node_modules/timers/**',\n '**/node_modules/backo2/**',\n '**/node_modules/side-channel-map/**',\n '**/node_modules/encode-utf8/**',\n '**/node_modules/math-intrinsics/**',\n '**/node_modules/call-bind-apply-helpers/**',\n '**/node_modules/performance-now/**',\n '**/node_modules/custom-event-js/**',\n '**/node_modules/subsink/**',\n '**/node_modules/safe-buffer/**',\n '**/node_modules/detect-it/**',\n '**/node_modules/side-channel-list/**',\n '**/node_modules/timers/**',\n '**/node_modules/backo2/**',\n '**/node_modules/side-channel-map/**',\n '**/node_modules/encode-utf8/**',\n '**/node_modules/math-intrinsics/**',\n '**/node_modules/call-bind-apply-helpers/**',\n '**/node_modules/performance-now/**',\n '**/node_modules/custom-event-js/**',\n '**/node_modules/subsink/**',\n '**/node_modules/get-proto/**',\n '**/node_modules/yeast/**',\n '**/node_modules/es-errors/**',\n '**/node_modules/dunder-proto/**',\n '**/node_modules/side-channel/**',\n '**/node_modules/parseqs/**',\n '**/node_modules/mitt/**',\n '**/node_modules/arraybuffer.slice/**',\n '**/node_modules/component-bind/**',\n '**/node_modules/after/**',\n '**/node_modules/call-bound/**',\n '**/node_modules/gopd/**',\n '**/node_modules/socket.io-client/**',\n '**/node_modules/indexof/**',\n '**/node_modules/hasown/**',\n '**/node_modules/component-inherit/**',\n '**/node_modules/es-define-property/**',\n '**/node_modules/has-cors/**',\n '**/node_modules/to-array/**',\n '**/node_modules/es-object-atoms/**',\n '**/node_modules/xhr2/**',\n '**/node_modules/fast-json-patch/**',\n '**/node_modules/canvas-confetti/**',\n '**/node_modules/cssfilter/**',\n '**/node_modules/xss/**',\n '**/node_modules/cds-client/**',\n '**/node_modules/immer/**',\n '**/node_modules/resize-observer-polyfill/**',\n '**/node_modules/fontfaceobserver-es/**',\n '**/node_modules/@cloudflare/**',\n '**/node_modules/css-element-queries/**',\n '**/node_modules/blueimp-md5/**',\n '**/node_modules/isomorphic-rslog/**',\n '**/node_modules/@swimlane/**',\n '**/node_modules/lottie-web/**',\n '**/node_modules/ngx-scrollbar/**',\n '**/node_modules/ngx-device-detector/**',\n '**/node_modules/@ngrx/**',\n '**/node_modules/@ng-bootstrap/**',\n '**/node_modules/@rx-angular/**',\n '**/node_modules/@ngu/**',\n '**/node_modules/@angular/**',\n '**/node_modules/ng-circle-progress/**',\n '**/node_modules/ngx-popperjs/**',\n '**/node_modules/ng-dynamic-component/**',\n '**/node_modules/ng-in-viewport/**',\n '**/node_modules/angularx-qrcode/**',\n '**/node_modules/ngx-lottie/**',\n '**/node_modules/socket.io-client/**',\n ],\n numSegments: 1,\n};\n\nconst dependencyAuditNewGroup: GroupingRule = {\n icon: '🆕',\n includeInputs: '**/node_modules/**',\n excludeInputs: [\n ...dependencyAuditAcceptedGroup.includeInputs,\n ...dependencyAuditBlacklistedGroup.includeInputs,\n ...dependencyAuditLegacyGroup.includeInputs,\n ],\n numSegments: 2,\n};\n\nconst dependencyAuditTableGroups: GroupingRule[] = [\n dependencyAuditBlacklistedGroup,\n dependencyAuditLegacyGroup,\n dependencyAuditAcceptedGroup,\n dependencyAuditNewGroup,\n];\n\nconst dependencyAuditTreeGroups: GroupingRule[] = [\n dependencyAuditBlacklistedGroup,\n dependencyAuditLegacyGroup,\n dependencyAuditNewGroup,\n];\n\nconst dependencyAudit: BundleStatsAuditOptions = {\n slug: 'node-modules',\n title: '📦 Dependency Tracking',\n description: `\nDetects *newly added packages*, catches **forbidden dependencies**, monitors **3rd party costs**, and prevents **bundle bloat** from unreviewed dependencies.`,\n selection: {\n mode: 'matchingOnly',\n includeInputs: ['**/node_modules/**'],\n },\n insightsTable: {\n mode: 'onlyMatching',\n groups: dependencyAuditTableGroups,\n pruning: {\n // minSize: 2000,\n },\n },\n dependencyTree: {\n mode: 'onlyMatching',\n groups: [\n dependencyAuditBlacklistedGroup,\n dependencyAuditLegacyGroup,\n dependencyAuditNewGroup,\n ],\n pruning: {\n maxChildren: 150,\n },\n },\n};\n\nconst blacklistedFilesAudit: BundleStatsAuditOptions = {\n slug: 'blacklisted',\n title: '🚫 Blacklisted Files',\n description: `\nMonitors **blacklisted dependencies** and **deprecated packages** that are present in the bundle. This helps identify potential security risks and compliance issues.`,\n selection: {\n mode: 'matchingOnly',\n includeInputs: [\n '**/node_modules/angular2-toaster/**',\n '**/node_modules/ngx-float-ui/**',\n '**/node_modules/@angular-slider/ngx-slider/**',\n '**/node_modules/ngx-slider-v2/**',\n '**/node_modules/ngx-toastr/**',\n '**/node_modules/@angular/material/dialog/**',\n '**/node_modules/@angular/material/slider/**',\n '**/node_modules/@angular/material/bottom-sheet/**',\n ],\n },\n insightsTable: {\n mode: 'onlyMatching',\n groups: blacklistedFilesGroups,\n },\n dependencyTree: {\n mode: 'onlyMatching',\n groups: blacklistedFilesGroups,\n },\n};\n\nconst config = {\n plugins: [\n await bundleStatsPlugin({\n bundler: 'esbuild',\n artifactsPaths:\n './packages/plugin-bundle-stats/mocks/fixtures/stats/angular-large.stats.json',\n audits: [\n allFilesAudit,\n blacklistedFilesAudit,\n angularSpecificAudit,\n dependencyAudit,\n initialBundleSizeAudit,\n ],\n }),\n ],\n};\n\nexport default config;\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts", - "messages": [ - { - "ruleId": null, - "nodeType": null, - "fatal": true, - "severity": 2, - "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild-sonda.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 1, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { CoreConfig } from '../models/src/index.js';\nimport bundleStatsPlugin from './src';\n\nconst config: CoreConfig = {\n plugins: [\n await bundleStatsPlugin({\n artifactsPaths:\n 'packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.sonda-report.json',\n bundler: 'sonda',\n audits: [\n {\n slug: 'bundle-size',\n title: 'Bundle Size Analysis',\n description: 'Analyzes bundle size using Sonda report',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*.js'],\n },\n scoring: {\n totalSize: 100_000,\n },\n },\n ],\n }),\n ],\n categories: [\n {\n slug: 'performance',\n title: '⚡ Performance',\n description: 'Bundle performance analysis using Sonda',\n refs: [\n {\n type: 'audit',\n plugin: 'bundle-stats',\n slug: 'bundle-size',\n weight: 1,\n },\n ],\n },\n ],\n};\n\nexport default (async () => {\n return config;\n})();\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts", - "messages": [ - { - "ruleId": null, - "nodeType": null, - "fatal": true, - "severity": 2, - "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/code-pushup.minimal-esbuild.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 1, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { CoreConfig } from '../models/src/index.js';\nimport bundleStatsPlugin from './src';\nimport { MinMax } from './src/lib/runner/types';\nimport { BundleStatsAuditOptions } from './src/lib/types';\n\n/**\n * Execute code-pushup over Nx:\n * nx code-pushup:minimal plugin-bundle-stats\n */\n\n// ===== Selection Constants =====\nconst SELECTION_ALL_OUTPUTS = {\n includeOutputs: ['**/*'],\n};\n\nconst SELECTION_OUTPUTS_INDEX_FILE = ['**/index.ts'];\n\nconst SELECTION_ONE_FILE = {\n mode: 'bundle' as const,\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n};\n// ===== Scoring Constants =====\n\nconst THRESHOLD_ALWAYS_PASS_MAX = 100_000; // 100KB - much higher than actual bundle size\nconst THRESHOLD_ALWAYS_FAIL_MAX = 1;\nconst THRESHOLD_ALWAYS_FAIL_MIN = 1;\nconst THRESHOLD_ALWAYS_PASS_MIN = 0;\nconst THRESHOLD_ALWAYS_PASS_RANGE: MinMax = [\n THRESHOLD_ALWAYS_PASS_MIN,\n THRESHOLD_ALWAYS_PASS_MAX,\n];\n\nconst DISABLED = {\n enabled: false,\n totalSize: THRESHOLD_ALWAYS_PASS_MAX,\n};\n\nconst BASE_AUDIT_ALL_FILES = {\n selection: {\n mode: 'bundle' as const,\n includeOutputs: ['**/*.js'],\n },\n};\n\nconst BASE_AUDIT_ALL_FILES_SCORING_DISABLED = {\n selection: {\n mode: 'bundle' as const,\n includeOutputs: ['**/*.js'],\n },\n scoring: DISABLED,\n};\n\n// ===== Audit Groups =====\n\n// ===== Audits =====\n\n// ===== Selection Audits =====\nconst SELECTION_AUDIT_ICON = '🎯';\nconst SELECTION_AUDIT_PREFIX = 'selection';\n\n/**\n * Stats Data\n *\n * esbuild-minimal.stats.json\n * └── outputs\n * ├── dist/index.js // entryPoint: ../shared-source/src/index.ts (595 B)\n * │ ├── inputs\n * │ │ └── ../shared-source/src/index.ts (386 B)\n * │ └── imports\n * │ ├── dist/chunks/chunk-PKX4VJZC.js // import-statement\n * │ ├── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * │ └── dist/chunks/feature-2-SERQNJVR.js // dynamic-import\n * ├── dist/bin.js // entryPoint: ../shared-source/src/bin.ts (549 B)\n * │ ├── inputs\n * │ │ └── ../shared-source/src/bin.ts (373 B)\n * │ └── imports\n * │ ├── dist/chunks/chunk-PKX4VJZC.js // import-statement\n * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * ├── dist/chunks/chunk-PKX4VJZC.js // Main shared chunk (51.35 kB)\n * │ ├── inputs (13 files: node_modules + source)\n * │ │ ├── ../../../../../node_modules/balanced-match/index.js (1.51 kB)\n * │ │ ├── ../../../../../node_modules/brace-expansion/index.js (4.67 kB)\n * │ │ ├── ../../../../../node_modules/minimatch/dist/esm/*.js (6 files, ~42 kB total)\n * │ │ ├── ../shared-source/node_modules/my-lib/index.js (93 B)\n * │ │ ├── ../shared-source/src/lib/utils/format.ts (269 B)\n * │ │ ├── ../shared-source/src/lib/feature-1.ts (269 B)\n * │ │ ├── ../shared-source/src/lib/utils/math.ts (145 B)\n * │ │ └── ../shared-source/src/lib/utils/string.ts (54 B)\n * │ └── imports\n * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * ├── dist/chunks/feature-2-SERQNJVR.js // entryPoint: ../shared-source/src/lib/feature-2.ts (130 B)\n * │ ├── inputs\n * │ │ └── ../shared-source/src/lib/feature-2.ts (38 B)\n * │ └── imports\n * │ └── dist/chunks/chunk-SK6HMZ5B.js // import-statement\n * └── dist/chunks/chunk-SK6HMZ5B.js // ESM runtime helpers (1.33 kB)\n * ├── inputs: (empty - runtime code)\n * └── imports: (none)\n */\n\nconst SELECTION_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Selection - Mode Audits =====\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-bundle`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - Bundle`,\n description:\n 'Demonstrates bundle mode - standard selection with static imports.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n dependencyTree: {\n pruning: {\n minSize: 1000,\n },\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-matching-only`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - Matching Only`,\n description:\n 'Demonstrates matchingOnly mode - input filtering with size recalculation.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'matchingOnly',\n includeInputs: ['**/utils/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-startup`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - withStartupDeps`,\n description:\n 'Demonstrates withStartupDeps mode - includes static import dependencies.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'withStartupDeps',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-mode-with-all-deps`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Mode - withAllDeps`,\n description:\n 'Demonstrates withAllDeps mode - comprehensive tracking (static + dynamic).',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'withAllDeps',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n },\n\n // ===== Selection - Pattern Audits =====\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-output-include`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Output Include`,\n description: 'Demonstrates including only main chunk files.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: SELECTION_OUTPUTS_INDEX_FILE,\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-output-include-exclude`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Output Include and Exclude`,\n description:\n 'Demonstrates including and excluding chunk files to focus on entry points.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*.js'],\n excludeOutputs: ['**/chunks/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-input-include`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Input Include`,\n description: 'Demonstrates including only source lib files.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-PKX4VJZC.js'],\n includeInputs: ['**/src/lib/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-input-include-exclude`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Input Include and Exclude`,\n description:\n 'Demonstrates including source lib files but excluding node_modules.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeInputs: ['**/src/lib/**'],\n excludeInputs: ['**/node_modules/**'],\n },\n },\n {\n slug: `${SELECTION_AUDIT_PREFIX}-pattern-combined`,\n title: `${SELECTION_AUDIT_ICON} - Selection - Pattern - Combined`,\n description:\n 'Demonstrates combining multiple chunk types with pattern matching.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js', '**/chunks/feature-*.js'],\n },\n },\n];\n\nconst SCORING_AUDIT_ICON = '📏';\nconst SCORING_AUDIT_PREFIX = 'scoring';\n\nconst SCORING_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Scoring - General Audits =====\n {\n title: `${SCORING_AUDIT_ICON} - Scoring - General - Disabled`,\n description: 'Demonstrates disabled scoring.',\n slug: `${SCORING_AUDIT_PREFIX}-general-disabled`,\n ...BASE_AUDIT_ALL_FILES,\n scoring: {\n enabled: false,\n },\n },\n\n // ===== Scoring - Total Size Audits =====\n {\n slug: `${SCORING_AUDIT_PREFIX}-total-size-pass`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Pass`,\n description:\n 'Demonstrates threshold passing when total size is within range limits.',\n ...BASE_AUDIT_ALL_FILES,\n scoring: { totalSize: THRESHOLD_ALWAYS_PASS_MAX },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-total-size-too-big`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Too Big`,\n description:\n 'Demonstrates threshold failure when total size exceeds simple number limit.',\n ...BASE_AUDIT_ALL_FILES,\n scoring: { totalSize: THRESHOLD_ALWAYS_FAIL_MAX },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-total-size-too-small`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Total Size - Too Small`,\n description:\n 'Demonstrates threshold warning when total size is below minimum in range.',\n ...BASE_AUDIT_ALL_FILES,\n scoring: {\n totalSize: [THRESHOLD_ALWAYS_FAIL_MIN, THRESHOLD_ALWAYS_PASS_MAX],\n },\n },\n];\n\n// ===== Scoring with Penalty Audits =====\n\nconst SCORING_PENALTY_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Scoring - Penalty - Artefact Size =====\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-pass`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Pass`,\n description:\n 'Demonstrates penalty passing when all files are within size limits.',\n selection: SELECTION_ONE_FILE,\n scoring: {\n penalty: {\n artefactSize: THRESHOLD_ALWAYS_PASS_MAX,\n },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-pass-range`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Pass Range`,\n description: 'Demonstrates penalty passing with min/max range constraints.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: {\n artefactSize: [THRESHOLD_ALWAYS_PASS_MIN, THRESHOLD_ALWAYS_PASS_MAX],\n },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-too-big`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Too Big`,\n description: 'Demonstrates penalty failure when files exceed maximum size.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: { artefactSize: THRESHOLD_ALWAYS_FAIL_MAX },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-artefact-too-small`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Artefact Too Small`,\n description:\n 'Demonstrates penalty warning when files are below minimum size.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n totalSize: THRESHOLD_ALWAYS_PASS_MAX,\n penalty: {\n artefactSize: [THRESHOLD_ALWAYS_FAIL_MIN, THRESHOLD_ALWAYS_PASS_MAX],\n },\n },\n },\n\n // ===== Scoring - Penalty - Blacklist =====\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-blacklist-pass`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Blacklist Pass`,\n description:\n 'Demonstrates penalty passing when no blacklisted patterns match.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: { blacklist: ['**/non-existent-pattern/**'] },\n },\n },\n {\n slug: `${SCORING_AUDIT_PREFIX}-penalty-blacklist-fail`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Penalty - Blacklist Fail`,\n description:\n 'Demonstrates penalty failure when blacklisted patterns are found.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n penalty: { blacklist: ['**/*'] },\n },\n },\n\n {\n slug: `${SCORING_AUDIT_PREFIX}-mixed-options`,\n title: `${SCORING_AUDIT_ICON} - Scoring - Mixed Options`,\n description: 'Demonstrates mixed scoring options.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n scoring: {\n totalSize: 1_000_000,\n penalty: {\n artefactSize: 2_000_000,\n blacklist: ['**/src/lib/utils/math.ts'],\n },\n },\n },\n];\n\n// ===== Issues Audits =====\nconst ISSUES_AUDIT_PREFIX = 'issues';\nconst ISSUES_AUDIT_ICON = '🚨';\n\n// ===== Insights Audits =====\nconst INSIGHT_AUDIT_PREFIX = 'insights';\nconst INSIGHT_AUDIT_ICON = '📊';\n\nconst INSIGHT_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Insights - General Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-general-disabled`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - General - Disabled`,\n description: 'Demonstrates disabled insights table.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: false,\n },\n\n // ===== Insights - View Mode Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-view-mode-only-matching`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - View Mode - Only Matching`,\n description:\n 'Demonstrates onlyMatching mode - shows only files matching selection.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n mode: 'onlyMatching',\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-view-mode-all`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - View Mode - All`,\n description:\n 'Demonstrates all mode - shows all files regardless of selection.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n mode: 'all',\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n ],\n },\n },\n\n // ===== Insights - Pruning Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-pruning-max-children`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Pruning - Max Children`,\n description:\n 'Demonstrates maxChildren pruning - limits table entries shown.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'All Files',\n includeInputs: ['**/*'],\n icon: '📄',\n },\n ],\n pruning: { maxChildren: 3 },\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-pruning-min-size`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Pruning - Min Size`,\n description: 'Demonstrates minSize pruning - filters out small files.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Large Files Only',\n includeInputs: ['**/*'],\n icon: '📄',\n },\n ],\n pruning: { minSize: 1000 },\n },\n },\n\n // ===== Insights - Table Audits =====\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-table-grouping`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Table - Grouping`,\n description: 'Demonstrates how the bundle is grouped.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Math Utilities',\n includeInputs: ['**/math.ts'],\n icon: '🔧',\n },\n {\n title: 'Formatting Utilities',\n includeInputs: ['**/format.ts'],\n icon: '🔧',\n },\n {\n title: 'Feature 2',\n includeInputs: ['**/*feature-2*'],\n icon: '🧩',\n },\n {\n title: 'Entrypoints',\n includeInputs: ['src/index.ts', 'src/bin.ts'],\n icon: '🏁',\n },\n {\n title: 'Shared Chunks',\n includeInputs: ['dist/chunks/chunk-*.js'],\n icon: '🤝',\n },\n {\n title: 'Node Modules',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n {\n title: 'Distributables',\n includeInputs: ['dist/index.js', 'dist/bin.js'],\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-table-rest-group`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Table - Rest Group`,\n description:\n 'Demonstrates how all non-matching assets are grouped into the \"Rest\" row.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Feature 1',\n includeInputs: ['**/*feature-1*'],\n icon: '🧩',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-groups-pattern-only`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Pattern Only`,\n description:\n 'Demonstrates groups with include patterns only (no title or icon).',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n { includeInputs: ['**/src/**'] },\n { includeInputs: ['**/dist/**'] },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-groups-title-icon`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Title Icon`,\n description: 'Demonstrates groups with title and icon.',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n {\n title: 'Node Modules',\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${INSIGHT_AUDIT_PREFIX}-groups-path-segments`,\n title: `${INSIGHT_AUDIT_ICON} - Insights - Groups - Path Segments`,\n description:\n 'Demonstrates grouping by number of path segments (numSegments).',\n ...BASE_AUDIT_ALL_FILES_SCORING_DISABLED,\n insightsTable: {\n groups: [\n {\n includeInputs: ['**/node_modules/**', '**/node_modules/@*/**'],\n numSegments: 1,\n },\n ],\n },\n },\n];\n\n// ===== Tree Audits =====\nconst TREE_AUDIT_PREFIX = 'tree';\nconst TREE_AUDIT_ICON = '🌳';\n\nconst TREE_AUDITS: BundleStatsAuditOptions[] = [\n // ===== Tree - Disables =====\n {\n slug: `${TREE_AUDIT_PREFIX}-disables`,\n title: `${TREE_AUDIT_ICON} - Tree - Disables`,\n description:\n 'Shows how to explicitly disable dependency trees using enabled: false. You should see audit results but no ASCII tree structure, even when global dependencyTree config exists.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { enabled: false },\n },\n\n // ===== Tree - Mode =====\n {\n slug: `${TREE_AUDIT_PREFIX}-mode-all`,\n title: `${TREE_AUDIT_ICON} - Tree - Mode - All`,\n description:\n 'Demonstrates mode: \"all\" - shows complete file tree regardless of selection filters. Compare with onlyMatching to see the difference in which files appear in the tree.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/*'],\n },\n scoring: DISABLED,\n dependencyTree: {\n mode: 'all',\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-mode-onlymatching`,\n title: `${TREE_AUDIT_ICON} - Tree - Mode - OnlyMatching`,\n description:\n 'Demonstrates mode: \"onlyMatching\" (default) - tree only shows files that match the selection criteria. Files outside selection are hidden from tree display.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { mode: 'onlyMatching' },\n },\n\n // ===== Tree - Groups =====\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-include`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Include`,\n description:\n 'Demonstrates groups.include patterns organizing files by type. Shows how dependencies (📦) are grouped with clear visual separation. Uses selection filtering to focus only on node_modules files for a clean demonstration.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n mode: 'onlyMatching',\n pruning: {\n maxDepth: 3,\n },\n groups: [\n {\n includeInputs: ['**/node_modules/**'],\n title: 'Dependencies',\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-exclude`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Exclude`,\n description:\n 'Demonstrates the recommended approach: using selection excludeInputs to filter out node_modules files, combined with mode: \"onlyMatching\". While grouping can organize remaining files, selection filtering is the primary and most reliable way to exclude unwanted files from both table and tree displays.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n mode: 'onlyMatching',\n groups: [\n {\n includeInputs: ['**/index.js'],\n excludeInputs: ['**/node_modules/**'],\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-include-exclude`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Include & Exclude`,\n description:\n 'Shows combining include and exclude patterns for precise filtering. First group shows src files but excludes test files, second shows lib files but excludes test directories.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n includeInputs: ['**/src/**'],\n excludeInputs: ['**/node_modules/**'],\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-title`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Title`,\n description:\n 'Demonstrates groups.title property for custom section headers. Look for \"Source Files\" and \"Dependencies\" labels that replace default path-based grouping names.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n title: 'Source Files',\n includeInputs: ['**/src/**'],\n },\n {\n title: 'Dependencies',\n includeInputs: ['**/node_modules/**'],\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-icon`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - Icon`,\n description:\n 'Shows groups.icon property adding visual indicators to grouped sections. Look for 📄 icon next to source files and 📦 icon next to dependencies in the tree display.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n includeInputs: ['**/src/**'],\n icon: '📄',\n },\n {\n includeInputs: ['**/node_modules/**'],\n icon: '📦',\n },\n ],\n },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-groups-numsegments`,\n title: `${TREE_AUDIT_ICON} - Tree - Groups - NumSegments`,\n description:\n 'Demonstrates groups.numSegments for path-based grouping. Node modules are grouped by their top-level package name (1 segment), flattening deep nested structures like @scope/package.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: {\n groups: [\n {\n includeInputs: ['**/node_modules/**', '**/node_modules/@*/**'],\n numSegments: 1,\n },\n ],\n },\n },\n\n // ===== Tree - Pruning =====\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-maxchildren`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - MaxChildren`,\n description:\n 'Shows pruning.maxChildren: 2 limiting displayed children per node. Large directories will show only first 2 entries plus \"...X more items\" to prevent overwhelming output.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { maxChildren: 2 } },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-maxdepth`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - MaxDepth`,\n description:\n 'Demonstrates pruning.maxDepth: 1 limiting tree depth to prevent deep nesting. Only shows immediate children, deeper levels are truncated with continuation indicators.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { maxDepth: 1 } },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-minsize`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - MinSize`,\n description:\n 'Shows pruning.minSize: 1000 filtering out files smaller than 1KB. Small utility files and helpers are hidden, displaying only substantial files that impact bundle size.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { minSize: 1000 } },\n },\n {\n slug: `${TREE_AUDIT_PREFIX}-pruning-pathlength`,\n title: `${TREE_AUDIT_ICON} - Tree - Pruning - PathLength`,\n description:\n 'Demonstrates pruning.pathLength: 30 truncating long file paths for readability. Paths longer than 30 characters show as \"...filename.js\" to keep tree display compact.',\n selection: {\n mode: 'bundle',\n includeOutputs: ['**/chunks/chunk-*.js'],\n },\n scoring: DISABLED,\n dependencyTree: { pruning: { pathLength: 30 } },\n },\n];\n\nconst config: CoreConfig = {\n plugins: [\n await bundleStatsPlugin({\n artifactsPaths:\n 'packages/plugin-bundle-stats/mocks/fixtures/stats/esbuild-minimal.stats.json',\n bundler: 'esbuild',\n audits: [\n ...SCORING_AUDITS,\n ...SCORING_PENALTY_AUDITS,\n ...SELECTION_AUDITS,\n ...INSIGHT_AUDITS,\n ...TREE_AUDITS,\n ],\n groups: [\n {\n slug: 'selection-group',\n title: '🎯 Selection',\n description:\n 'Demonstrates different selection modes and pattern matching for bundle analysis.',\n refs: SELECTION_AUDITS.filter(audit => audit.slug).map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n {\n slug: 'scoring-group',\n title: '📏 Scoring',\n description:\n 'Shows scoring mechanisms including thresholds, penalties, and size constraints.',\n refs: [...SCORING_AUDITS, ...SCORING_PENALTY_AUDITS]\n .filter(audit => audit.slug)\n .map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n {\n slug: 'insights-group',\n title: '📊 Insights Table',\n description:\n 'Configures insights tables with grouping, pruning, and visualization options.',\n refs: INSIGHT_AUDITS.filter(audit => audit.slug).map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n {\n slug: 'tree-group',\n title: '🌳 Dependency Tree',\n description:\n 'Demonstrates dependency tree configurations with grouping and pruning strategies.',\n refs: TREE_AUDITS.filter(audit => audit.slug).map(audit => ({\n slug: audit.slug!,\n weight: 1,\n })),\n },\n ],\n }),\n ],\n categories: [\n {\n slug: 'performance',\n title: '⚡ Performance',\n description:\n 'Comprehensive bundle performance analysis including selection, scoring, insights, and dependency trees.',\n refs: [\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'selection-group',\n weight: 1,\n },\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'scoring-group',\n weight: 1,\n },\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'insights-group',\n weight: 1,\n },\n {\n type: 'group' as const,\n plugin: 'bundle-stats',\n slug: 'tree-group',\n weight: 1,\n },\n ],\n },\n ],\n};\n\nexport default (async () => {\n return config;\n})();\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/package.json", - "messages": [ - { - "ruleId": "@nx/dependency-checks", - "severity": 2, - "message": "The \"vite\" package is not used by \"plugin-bundle-stats\" project.", - "line": 29, - "column": 5, - "nodeType": "JSONProperty", - "messageId": "obsoleteDependency", - "endLine": 29, - "endColumn": 20, - "fix": { - "range": [872, 893], - "text": "" - } - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 1, - "fixableWarningCount": 0, - "source": "{\n \"name\": \"@code-pushup/bundle-stats-plugin\",\n \"version\": \"0.69.2\",\n \"license\": \"MIT\",\n \"description\": \"Code PushUp plugin for incrementally adopting strict compilation flags in TypeScript projects\",\n \"homepage\": \"https://github.com/code-pushup/cli/tree/main/packages/plugin-bundle-stats#readme\",\n \"bugs\": {\n \"url\": \"https://github.com/code-pushup/cli/issues?q=is%3Aissue%20state%3Aopen%20type%3ABug%20label%3A\\\"🧩%20bundle-stats-plugin\\\"\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/code-pushup/cli.git\",\n \"directory\": \"packages/plugin-bundle-stats\"\n },\n \"keywords\": [\n \"CLI\",\n \"Code PushUp\",\n \"plugin\",\n \"typescript\"\n ],\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"type\": \"module\",\n \"dependencies\": {\n \"@code-pushup/models\": \"0.92.1\",\n \"@code-pushup/utils\": \"0.92.1\",\n \"minimatch\": \"^10.0.1\",\n \"vite\": \"6.3.5\"\n },\n \"peerDependencies\": {},\n \"scripts\": {},\n \"devDependencies\": {\n \"@angular/cli\": \"^20.0.3\",\n \"typescript\": \"5.4\"\n }\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/index.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/bundle-stats-plugin.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/constants.ts", - "messages": [ - { - "ruleId": "max-lines", - "severity": 1, - "message": "File has too many lines (364). Maximum allowed is 300.", - "line": 306, - "column": 1, - "nodeType": null, - "messageId": "exceed", - "endLine": 380, - "endColumn": 1 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 4.", - "line": 373, - "column": 13, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 373, - "endColumn": 14 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 2, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { PruningConfig } from './runner/audits/details/tree.js';\nimport type { GroupingRule } from './runner/types.js';\n\n/**\n * Default grouping rules for bundle stats analysis.\n * These rules help categorize and organize bundle assets by common patterns.\n */\nexport const DEFAULT_GROUPING: GroupingRule[] = [\n {\n title: '@angular/*',\n includeInputs: ['**/node_modules/@angular/**'],\n icon: '🅰️',\n },\n {\n title: 'react',\n includeInputs: ['**/node_modules/react/**', '**/node_modules/react-dom/**'],\n icon: '⚛️',\n },\n {\n title: 'preact',\n includeInputs: ['**/node_modules/preact/**', '**/node_modules/preact-*/**'],\n icon: '🪐',\n },\n {\n title: 'vue',\n includeInputs: ['**/node_modules/vue/**', '**/node_modules/@vue/**'],\n icon: '💚',\n },\n {\n title: 'solid',\n includeInputs: [\n '**/node_modules/solid-js/**',\n '**/node_modules/solid-*/**',\n ],\n icon: '🟢',\n },\n {\n title: 'lit',\n includeInputs: ['**/node_modules/lit/**', '**/node_modules/lit-html/**'],\n icon: '💡',\n },\n {\n title: 'svelte',\n includeInputs: [\n '**/node_modules/svelte/**',\n '**/node_modules/@sveltejs/**',\n ],\n icon: '🧡',\n },\n {\n title: 'ember',\n includeInputs: [\n '**/node_modules/ember-source/**',\n '**/node_modules/ember-cli/**',\n ],\n icon: '🔥',\n },\n {\n title: 'backbone',\n includeInputs: ['**/node_modules/backbone/**'],\n icon: '🦴',\n },\n {\n title: 'alpine',\n includeInputs: ['**/node_modules/alpinejs/**'],\n icon: '🏔️',\n },\n {\n title: 'next.js',\n includeInputs: ['**/node_modules/next/**'],\n icon: '▲',\n },\n {\n title: 'nuxt',\n includeInputs: ['**/node_modules/nuxt/**', '**/node_modules/@nuxt/**'],\n icon: '💚',\n },\n {\n title: 'sveltekit',\n includeInputs: ['**/node_modules/@sveltejs/kit/**'],\n icon: '🏗️',\n },\n {\n title: 'remix',\n includeInputs: [\n '**/node_modules/remix/**',\n '**/node_modules/@remix-run/**',\n ],\n icon: '🌀',\n },\n {\n title: 'gatsby',\n includeInputs: ['**/node_modules/gatsby/**'],\n icon: '🚀',\n },\n {\n title: 'eleventy',\n includeInputs: ['**/node_modules/eleventy/**', '**/node_modules/@11ty/**'],\n icon: '1️⃣1️⃣',\n },\n {\n title: 'astro',\n includeInputs: ['**/node_modules/astro/**'],\n icon: '🌌',\n },\n {\n title: '@mui/*',\n includeInputs: ['**/node_modules/@mui/**'],\n icon: '🖼️',\n },\n {\n title: 'antd',\n includeInputs: [\n '**/node_modules/antd/**',\n '**/node_modules/@ant-design/**',\n ],\n icon: '🐜',\n },\n {\n title: 'chakra-ui',\n includeInputs: ['**/node_modules/@chakra-ui/**'],\n icon: '🧘',\n },\n {\n title: 'tailwindcss',\n includeInputs: ['**/node_modules/tailwindcss/**'],\n icon: '🌬️',\n },\n {\n title: 'bootstrap',\n includeInputs: ['**/node_modules/bootstrap/**'],\n icon: '👢',\n },\n {\n title: 'bulma',\n includeInputs: ['**/node_modules/bulma/**'],\n icon: '🍹',\n },\n {\n title: 'redux',\n includeInputs: ['**/node_modules/redux/**', '**/node_modules/@reduxjs/**'],\n icon: '🛠️',\n },\n {\n title: 'mobx',\n includeInputs: ['**/node_modules/mobx/**'],\n icon: '🧪',\n },\n {\n title: 'zustand',\n includeInputs: ['**/node_modules/zustand/**'],\n icon: '🧊',\n },\n {\n title: 'recoil',\n includeInputs: ['**/node_modules/recoil/**'],\n icon: '🎱',\n },\n {\n title: 'rxjs',\n includeInputs: ['**/node_modules/rxjs/**'],\n icon: '🔄',\n },\n {\n title: 'xstate',\n includeInputs: ['**/node_modules/xstate/**'],\n icon: '⚙️',\n },\n {\n title: 'react-router',\n includeInputs: [\n '**/node_modules/react-router/**',\n '**/node_modules/react-router-dom/**',\n ],\n icon: '🗺️',\n },\n {\n title: 'vue-router',\n includeInputs: ['**/node_modules/vue-router/**'],\n icon: '🗺️',\n },\n {\n title: 'webpack',\n includeInputs: ['**/node_modules/webpack/**'],\n icon: '📦',\n },\n {\n title: 'rollup',\n includeInputs: ['**/node_modules/rollup/**'],\n icon: '🔄',\n },\n {\n title: 'vite',\n includeInputs: ['**/node_modules/vite/**'],\n icon: '⚡️',\n },\n {\n title: 'parcel',\n includeInputs: [\n '**/node_modules/parcel/**',\n '**/node_modules/parcel-bundler/**',\n ],\n icon: '🎁',\n },\n {\n title: 'esbuild',\n includeInputs: ['**/node_modules/esbuild/**'],\n icon: '🏗️',\n },\n {\n title: 'snowpack',\n includeInputs: ['**/node_modules/snowpack/**'],\n icon: '❄️',\n },\n {\n title: 'jest',\n includeInputs: ['**/node_modules/jest/**'],\n icon: '🎯',\n },\n {\n title: 'mocha',\n includeInputs: ['**/node_modules/mocha/**'],\n icon: '☕️',\n },\n {\n title: 'chai',\n includeInputs: ['**/node_modules/chai/**'],\n icon: '🍵',\n },\n {\n title: 'cypress',\n includeInputs: ['**/node_modules/cypress/**'],\n icon: '🌪️',\n },\n {\n title: 'playwright',\n includeInputs: ['**/node_modules/playwright/**'],\n icon: '🎭',\n },\n {\n title: 'ava',\n includeInputs: ['**/node_modules/ava/**'],\n icon: '🐦',\n },\n {\n title: 'express',\n includeInputs: ['**/node_modules/express/**'],\n icon: '🚆',\n },\n {\n title: 'koa',\n includeInputs: ['**/node_modules/koa/**'],\n icon: '🍵',\n },\n {\n title: 'hapi',\n includeInputs: ['**/node_modules/@hapi/hapi/**'],\n icon: '🎉',\n },\n {\n title: 'fastify',\n includeInputs: ['**/node_modules/fastify/**'],\n icon: '🚀',\n },\n {\n title: '@nestjs/*',\n includeInputs: ['**/node_modules/@nestjs/**'],\n icon: '🔱',\n },\n {\n title: 'sails',\n includeInputs: ['**/node_modules/sails/**'],\n icon: '⛵️',\n },\n {\n title: 'loopback',\n includeInputs: ['**/node_modules/@loopback/**'],\n icon: '🔄',\n },\n {\n title: 'feathers',\n includeInputs: ['**/node_modules/feathers/**'],\n icon: '🪶',\n },\n {\n title: 'meteor',\n includeInputs: ['**/node_modules/meteor/**'],\n icon: '☄️',\n },\n {\n title: 'typeorm',\n includeInputs: ['**/node_modules/typeorm/**'],\n icon: '🗄️',\n },\n {\n title: '@prisma/*',\n includeInputs: ['**/node_modules/@prisma/**'],\n icon: '📐',\n },\n {\n title: 'sequelize',\n includeInputs: ['**/node_modules/sequelize/**'],\n icon: '🐆',\n },\n {\n title: 'mongoose',\n includeInputs: ['**/node_modules/mongoose/**'],\n icon: '🐭',\n },\n {\n title: 'graphql',\n includeInputs: ['**/node_modules/graphql/**'],\n icon: '🔮',\n },\n {\n title: '@apollo/*',\n includeInputs: ['**/node_modules/@apollo/**'],\n icon: '🛰️',\n },\n {\n title: 'axios',\n includeInputs: ['**/node_modules/axios/**'],\n icon: '🎣',\n },\n {\n title: 'socket.io',\n includeInputs: ['**/node_modules/socket.io/**'],\n icon: '🔌',\n },\n {\n title: 'eslint',\n includeInputs: ['**/node_modules/eslint/**'],\n icon: '🧹',\n },\n {\n title: 'prettier',\n includeInputs: ['**/node_modules/prettier/**'],\n icon: '🖌️',\n },\n {\n title: 'husky',\n includeInputs: ['**/node_modules/husky/**'],\n icon: '🐶',\n },\n {\n title: 'lint-staged',\n includeInputs: ['**/node_modules/lint-staged/**'],\n icon: '🐝',\n },\n {\n title: 'storybook',\n includeInputs: ['**/node_modules/@storybook/**'],\n icon: '📖',\n },\n {\n title: 'packages/*',\n includeInputs: ['packages/**/*'],\n // folder icon\n icon: '📁',\n },\n {\n title: 'Dependencies',\n includeInputs: ['**/node_modules/@*/**', '**/node_modules/**'],\n },\n];\n\n/**\n * Default pruning options for bundle stats analysis.\n * These settings control how the bundle tree is simplified and organized.\n */\nexport const DEFAULT_PRUNING: PruningConfig = {\n maxChildren: 10,\n maxDepth: 4,\n};\n\n/**\n * Plugin slug for bundle stats plugin\n */\nexport const BUNDLE_STATS_PLUGIN_SLUG = 'bundle-stats';\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/normalize.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'ExportedBundleStatsConfig' is defined but never used.", - "line": 3, - "column": 36, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 3, - "endColumn": 61 - }, - { - "ruleId": "no-duplicate-imports", - "severity": 1, - "message": "'./runner/audits/scoring.js' import is duplicated.", - "line": 7, - "column": 1, - "nodeType": "ImportDeclaration", - "messageId": "import", - "endLine": 7, - "endColumn": 62 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 28, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 30, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 37, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 37, - "endColumn": 77 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 42, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 42, - "endColumn": 78 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 55, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 58, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 61, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 63, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 64, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 64, - "endColumn": 78 - }, - { - "ruleId": "unicorn/no-array-push-push", - "severity": 1, - "message": "Do not call `Array#push()` multiple times.", - "line": 64, - "column": 13, - "nodeType": "Identifier", - "messageId": "error", - "endLine": 64, - "endColumn": 17, - "suggestions": [ - { - "messageId": "suggestion", - "fix": { - "range": [2380, 2468], - "text": " ` - Error: >\\`${formatBytes(max)}\\` - Exceeds size budget`\n );" - }, - "data": {}, - "desc": "Merge with previous one." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 66, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 66, - "endColumn": 77 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 69, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 69, - "endColumn": 75 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 5.", - "line": 89, - "column": 15, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 89, - "endColumn": 16 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'formatStandardizedTreeSection' has too many lines (77). Maximum allowed is 50.", - "line": 99, - "column": 1, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 184, - "endColumn": 2 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 109, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 109, - "endColumn": 40 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 113, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 113, - "endColumn": 73 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 116, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 116, - "endColumn": 68 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 119, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 119, - "endColumn": 62 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 122, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 122, - "endColumn": 66 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 131, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 131, - "endColumn": 27 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 136, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 136, - "endColumn": 39 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 139, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 139, - "endColumn": 36 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 151, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 151, - "endColumn": 66 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 153, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 153, - "endColumn": 58 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 173, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 173, - "endColumn": 64 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'formatStandardizedSelectionSection' has too many lines (51). Maximum allowed is 50.", - "line": 186, - "column": 1, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 245, - "endColumn": 2 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 192, - "column": 3, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 192, - "endColumn": 48 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 3.", - "line": 197, - "column": 17, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 197, - "endColumn": 18 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 3.", - "line": 201, - "column": 41, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 201, - "endColumn": 42 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 3.", - "line": 202, - "column": 51, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 202, - "endColumn": 52 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 204, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 204, - "endColumn": 59 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 216, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 216, - "endColumn": 59 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 3.", - "line": 222, - "column": 17, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 222, - "endColumn": 18 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 3.", - "line": 226, - "column": 40, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 226, - "endColumn": 41 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 3.", - "line": 227, - "column": 50, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 227, - "endColumn": 51 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 229, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 229, - "endColumn": 58 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 241, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 241, - "endColumn": 58 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 259, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 259, - "endColumn": 47 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 268, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 268, - "endColumn": 36 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 273, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 273, - "endColumn": 35 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 278, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 278, - "endColumn": 38 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 288, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 288, - "endColumn": 34 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 293, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 293, - "endColumn": 33 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 362, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 362, - "endColumn": 60 - }, - { - "ruleId": "max-lines", - "severity": 1, - "message": "File has too many lines (403). Maximum allowed is 300.", - "line": 365, - "column": 1, - "nodeType": null, - "messageId": "exceed", - "endLine": 495, - "endColumn": 1 - }, - { - "ruleId": "@typescript-eslint/consistent-type-assertions", - "severity": 2, - "message": "Always prefer const x: T = { ... }.", - "line": 365, - "column": 25, - "nodeType": "TSAsExpression", - "messageId": "unexpectedObjectTypeAssertion", - "endLine": 368, - "endColumn": 23, - "suggestions": [ - { - "messageId": "replaceObjectTypeAssertionWithSatisfies", - "data": { - "cast": "PenaltyConfig" - }, - "fix": { - "range": [11334, 11531], - "text": "{\n ...restPenalty, // Preserve all penalty properties including warningWeight, errorWeight\n ...(artefactSize ? { artefactSize: normalizeRange(artefactSize) } : {}),\n } satisfies PenaltyConfig" - }, - "desc": "Use const x = { ... } satisfies PenaltyConfig instead." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 387, - "column": 3, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 387, - "endColumn": 70 - } - ], - "suppressedMessages": [], - "errorCount": 30, - "fatalErrorCount": 0, - "warningCount": 16, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { Audit } from '@code-pushup/models';\nimport { formatBytes, slugify } from '@code-pushup/utils';\nimport type { BundleStatsConfig as ExportedBundleStatsConfig } from '../index.js';\nimport type { InsightsTableConfig } from './runner/audits/details/table.js';\nimport type { DependencyTreeConfig } from './runner/audits/details/tree.js';\nimport type { PenaltyConfig, ScoringConfig } from './runner/audits/scoring.js';\nimport { DEFAULT_PENALTY } from './runner/audits/scoring.js';\nimport type { SelectionConfig } from './runner/audits/selection.js';\nimport type { BundleStatsConfig, MinMax } from './runner/types.js';\nimport type {\n BundleStatsAuditOptions,\n PluginBundleStatsAuditOptions,\n PluginDependencyTreeOptions,\n PluginInsightsTableOptions,\n PluginScoringOptions,\n SelectionGeneralConfig,\n SelectionOptions,\n} from './types.js';\n\nfunction formatStandardizedScoringSection(scoring: ScoringConfig): string {\n const { totalSize, penalty } = scoring;\n const items: string[] = [];\n\n // Artefact Size section\n if (penalty && penalty.artefactSize) {\n const [min, max] = penalty.artefactSize;\n const weight = penalty.errorWeight || 0;\n items.push(\n ` - Artefact Size: >\\`${formatBytes(min)}\\` & <\\`${formatBytes(max)}\\`; weight: \\`${weight}\\``,\n );\n }\n\n // Blacklist section\n if (penalty && penalty.blacklist) {\n const count = penalty.blacklist.length;\n const weight = penalty.errorWeight || 0;\n items.push(` - Blacklist: \\`${count}\\` matches; weight: \\`${weight}\\``);\n }\n\n // Total Size section (if configured)\n if (totalSize && totalSize[1] !== Infinity) {\n items.push(` - Total Size: >\\`${formatBytes(totalSize[1])}\\` threshold`);\n }\n\n return items.length > 0 ? `- **Scoring:**\\n${items.join('\\n')}` : '';\n}\n\nfunction formatStandardizedIssuesSection(scoring: ScoringConfig): string {\n const { penalty } = scoring;\n const items: string[] = [];\n\n if (penalty) {\n // Check if this audit generates issues\n if (penalty.blacklist && penalty.blacklist.length > 0) {\n items.push(\n ` - Error: \\`1+\\` candidates - Violation detected, requires action`,\n ` - Info: \\`0\\` candidates - No violations found`,\n );\n } else if (penalty.artefactSize) {\n const [, max] = penalty.artefactSize;\n items.push(\n ` - Warning: <\\`${formatBytes(max)}\\` - Size acceptable but monitor growth`,\n );\n items.push(` - Error: >\\`${formatBytes(max)}\\` - Exceeds size budget`);\n } else {\n items.push(` - Info: \\`0\\` violations - Analysis only, no penalties`);\n }\n } else {\n items.push(` - Info: \\`0\\` violations - Analysis only, no penalties`);\n }\n\n return `- **Issues:**\\n${items.join('\\n')}`;\n}\n\nfunction formatStandardizedTableSection(\n insightsTable: InsightsTableConfig | undefined,\n): string {\n if (\n !insightsTable ||\n !insightsTable.groups ||\n insightsTable.groups.length === 0\n ) {\n return ''; // Hide empty table section\n }\n\n const groupItems = insightsTable.groups\n .filter(group => group.title)\n .map(group => `*${group.icon || ''}${group.title}*`)\n .slice(0, 5); // Limit to prevent overly long descriptions\n\n const groupsText =\n groupItems.length > 0\n ? `Detail listing of ${groupItems.join(', ')}`\n : 'Configured groups';\n\n return `- **Table:**\\n - Groups: ${groupsText}\\n - Rest: Other contributing modules`;\n}\n\nfunction formatStandardizedTreeSection(\n dependencyTree: DependencyTreeConfig | undefined,\n): string {\n if (!dependencyTree) {\n return ''; // Hide disabled tree section\n }\n\n const { pruning, groups, mode } = dependencyTree;\n\n // Format pruning settings\n let pruningText = 'Default settings';\n if (pruning) {\n const pruningParts: string[] = [];\n if (pruning.minSize) {\n pruningParts.push(`Min size: \\`${formatBytes(pruning.minSize)}\\``);\n }\n if (pruning.maxChildren) {\n pruningParts.push(`Max children: \\`${pruning.maxChildren}\\``);\n }\n if (pruning.maxDepth) {\n pruningParts.push(`Max depth: \\`${pruning.maxDepth}\\``);\n }\n if (pruning.pathLength) {\n pruningParts.push(`Path length: \\`${pruning.pathLength}\\``);\n }\n\n if (pruningParts.length > 0) {\n pruningText = pruningParts.join(', ');\n }\n }\n\n // Format groups\n let groupsText = 'None';\n if (groups && groups.length > 0) {\n const groupSummaries = groups.map(group => {\n const parts: string[] = [];\n if (group.title) {\n parts.push(`\"${group.title}\"`);\n }\n if (group.icon) {\n parts.push(`${group.icon}`);\n }\n if (group.includeInputs) {\n if (Array.isArray(group.includeInputs)) {\n const includePatterns = group.includeInputs\n .slice(0, 2)\n .map((p: string) => `\"${p}\"`)\n .join(', ');\n const moreCount =\n group.includeInputs.length > 2\n ? `, +${group.includeInputs.length - 2} more`\n : '';\n parts.push(`include: [${includePatterns}${moreCount}]`);\n } else {\n parts.push(`include: \"${group.includeInputs}\"`);\n }\n }\n if (\n group.excludeInputs &&\n (typeof group.excludeInputs === 'string'\n ? [group.excludeInputs]\n : group.excludeInputs\n ).length > 0\n ) {\n const excludeArray =\n typeof group.excludeInputs === 'string'\n ? [group.excludeInputs]\n : group.excludeInputs;\n const excludePatterns = excludeArray\n .slice(0, 1)\n .map((p: string) => `\"${p}\"`)\n .join(', ');\n const moreCount =\n excludeArray.length > 1 ? `, +${excludeArray.length - 1} more` : '';\n parts.push(`exclude: [${excludePatterns}${moreCount}]`);\n }\n return parts.join(' ');\n });\n groupsText = groupSummaries.join('; ');\n }\n\n // Format mode\n const modeText = mode || 'onlyMatching';\n\n return `- **Tree:**\\n - Mode: \\`${modeText}\\`\\n - Groups: ${groupsText}\\n - Pruning: ${pruningText}`;\n}\n\nfunction formatStandardizedSelectionSection(\n selection: SelectionConfig,\n): string {\n const items: string[] = [];\n\n // Selection mode\n items.push(` - Mode: \\`${selection.mode}\\``);\n\n // Output patterns\n if (selection.includeOutputs.length > 0) {\n const patterns = selection.includeOutputs\n .slice(0, 3)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.includeOutputs.length > 3\n ? ` (+${selection.includeOutputs.length - 3} more)`\n : '';\n items.push(` - Include Outputs: ${patterns}${extra}`);\n }\n\n if (selection.excludeOutputs.length > 0) {\n const patterns = selection.excludeOutputs\n .slice(0, 2)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.excludeOutputs.length > 2\n ? ` (+${selection.excludeOutputs.length - 2} more)`\n : '';\n items.push(` - Exclude Outputs: ${patterns}${extra}`);\n }\n\n // Input patterns\n if (selection.includeInputs.length > 0) {\n const patterns = selection.includeInputs\n .slice(0, 3)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.includeInputs.length > 3\n ? ` (+${selection.includeInputs.length - 3} more)`\n : '';\n items.push(` - Include Inputs: ${patterns}${extra}`);\n }\n\n if (selection.excludeInputs.length > 0) {\n const patterns = selection.excludeInputs\n .slice(0, 2)\n .map(p => `\\`${p}\\``)\n .join(', ');\n const extra =\n selection.excludeInputs.length > 2\n ? ` (+${selection.excludeInputs.length - 2} more)`\n : '';\n items.push(` - Exclude Inputs: ${patterns}${extra}`);\n }\n\n return `- **Selection:**\\n${items.join('\\n')}`;\n}\n\nexport function cleanTitleForSlug(title: string): string {\n return title\n .replace(/[^\\w\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .toLowerCase();\n}\n\nexport function prepareDescription(config: BundleStatsConfig): string {\n const { description, scoring, selection, dependencyTree, insightsTable } =\n config;\n\n // Start with the action paragraph (preserve existing custom descriptions)\n let enhancedDescription = description || '';\n\n // Only add standardized sections if we have a custom description\n if (enhancedDescription.trim()) {\n const sections: string[] = [];\n\n // Add standardized sections\n const scoringSection = formatStandardizedScoringSection(scoring);\n if (scoringSection) {\n sections.push(scoringSection);\n }\n\n const issuesSection = formatStandardizedIssuesSection(scoring);\n if (issuesSection) {\n sections.push(issuesSection);\n }\n\n const selectionSection = formatStandardizedSelectionSection(selection);\n if (selectionSection) {\n sections.push(selectionSection);\n }\n\n // Handle insightsTable which could be false\n const normalizedInsightsTable =\n insightsTable === false ? undefined : insightsTable;\n const tableSection = formatStandardizedTableSection(\n normalizedInsightsTable,\n );\n if (tableSection) {\n sections.push(tableSection);\n }\n\n const treeSection = formatStandardizedTreeSection(dependencyTree);\n if (treeSection) {\n sections.push(treeSection);\n }\n\n // Wrap config sections in details if any exist\n if (sections.length > 0) {\n const configContent = sections.join('\\n\\n');\n enhancedDescription += `\\n\\n
\\n⚙️ Configuration\\n\\n${configContent}\\n\\n
`;\n }\n }\n\n return enhancedDescription.trim() || '';\n}\n\n/**\n * Converts SelectionGeneralConfig to SelectionOptions by adding default empty arrays.\n */\nexport function selectionGeneralConfigToOptions(\n config: SelectionGeneralConfig,\n): SelectionOptions {\n return {\n ...config,\n mode: 'withStartupDeps',\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n includeImports: [],\n excludeImports: [],\n includeEntryPoints: [],\n excludeEntryPoints: [],\n };\n}\n\nexport function normalizeSelectionOptions(\n options: SelectionOptions | undefined,\n): SelectionConfig {\n if (options === undefined) {\n // Default: include all outputs for startup mode\n return {\n mode: 'withStartupDeps',\n includeOutputs: ['**/*'],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n }\n\n const globalInclude = options.include || [];\n const globalExclude = options.exclude || [];\n\n return {\n mode: options.mode || 'withStartupDeps',\n includeOutputs: [...(options.includeOutputs || []), ...globalInclude],\n excludeOutputs: [...(options.excludeOutputs || []), ...globalExclude],\n includeInputs: [...(options.includeInputs || []), ...globalInclude],\n excludeInputs: [...(options.excludeInputs || []), ...globalExclude],\n };\n}\n\nexport function normalizeBundleStatsOptions(\n auditOptions: BundleStatsAuditOptions,\n): BundleStatsConfig {\n const { slug, title, description, scoring, selection, ...restOptions } =\n auditOptions;\n const { penalty, totalSize } = scoring ?? {};\n\n // Use the proper selection normalization helper that merges global patterns\n const normalizedSelection = normalizeSelectionOptions(selection);\n\n let normalizedPenalty: false | PenaltyConfig | undefined;\n if (penalty && typeof penalty === 'object') {\n const { artefactSize, ...restPenalty } = penalty;\n normalizedPenalty = {\n ...restPenalty, // Preserve all penalty properties including warningWeight, errorWeight\n ...(artefactSize ? { artefactSize: normalizeRange(artefactSize) } : {}),\n } as PenaltyConfig;\n }\n\n const normalizedScoring: ScoringConfig = {\n mode: 'matchingWithStaticImports',\n totalSize: normalizeRange(totalSize ?? Infinity),\n penalty: normalizedPenalty,\n };\n\n const normalizedConfig: BundleStatsConfig = {\n slug: slug ?? slugify(title),\n title,\n description: description || '',\n selection: normalizedSelection,\n scoring: normalizedScoring,\n dependencyTree: restOptions.dependencyTree,\n insightsTable: restOptions.insightsTable,\n };\n\n normalizedConfig.description = prepareDescription(normalizedConfig);\n\n return normalizedConfig;\n}\n\n/**\n * Normalizes scoring options. Converts plugin-level scoring to runner scoring config.\n */\nexport function normalizeScoringOptions(\n options: PluginScoringOptions | undefined,\n): ScoringConfig | undefined {\n if (!options) {\n return undefined;\n }\n\n const { penalty } = options;\n\n return {\n mode: 'matchingWithStaticImports',\n totalSize: [0, Infinity], // Default range\n penalty: penalty\n ? {\n ...DEFAULT_PENALTY,\n ...penalty,\n artefactSize: penalty.artefactSize\n ? normalizeRange(penalty.artefactSize)\n : undefined,\n }\n : DEFAULT_PENALTY,\n };\n}\n\n/**\n * Normalizes dependency tree options from plugin configuration.\n * Groups array overwrites, pruning merges with defaults.\n */\nexport function normalizeDependencyTreeOptions(\n options: PluginDependencyTreeOptions | undefined,\n): DependencyTreeConfig {\n return {\n groups: options?.groups ?? [],\n pruning: {\n maxDepth: 2,\n maxChildren: 10,\n minSize: 1000,\n pathLength: 60,\n ...options?.pruning,\n },\n mode: options?.mode ?? 'onlyMatching',\n };\n}\n\n/**\n * Normalizes insights table options. Converts plugin-level options to runner config.\n */\nexport function normalizeInsightsTableOptions(\n options: PluginInsightsTableOptions | false | undefined,\n): InsightsTableConfig | undefined {\n if (options === false || options === undefined) {\n return undefined;\n }\n\n return {\n mode: options.mode || 'onlyMatching',\n groups: options.groups || [],\n pruning: options.pruning\n ? {\n enabled: options.pruning.enabled ?? false,\n maxChildren: options.pruning.maxChildren,\n minSize: options.pruning.minSize,\n }\n : undefined,\n };\n}\n\nexport function normalizeRange(range: MinMax | number): MinMax {\n if (typeof range === 'number') {\n return [0, range];\n }\n\n return range;\n}\n\nexport function getAuditsFromConfigs(configs: BundleStatsConfig[]): Audit[] {\n return configs.map(({ slug, title, description }) => ({\n slug,\n title,\n description,\n }));\n}\n\n/**\n * Normalizes complete plugin options. Centralizes all normalization logic.\n */\nexport function normalizeBundleStatsAuditOptions(\n auditOptions: BundleStatsAuditOptions[],\n pluginOptions: PluginBundleStatsAuditOptions,\n) {\n return {\n bundleStatsConfigs: auditOptions.map(normalizeBundleStatsOptions),\n scoring: normalizeScoringOptions(pluginOptions.scoring),\n dependencyTree: normalizeDependencyTreeOptions(\n pluginOptions.dependencyTree,\n ),\n insightsTable: normalizeInsightsTableOptions(pluginOptions.insightsTable),\n selection: pluginOptions.selection,\n };\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.ts", - "messages": [ - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 27, - "column": 3, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 27, - "endColumn": 15, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "time" - }, - "fix": { - "range": [1084, 1113], - "text": "" - }, - "desc": "Remove the console.time()." - } - ] - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 29, - "column": 3, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 29, - "endColumn": 18, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "timeEnd" - }, - "fix": { - "range": [1164, 1196], - "text": "" - }, - "desc": "Remove the console.timeEnd()." - } - ] - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 54, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 54, - "endColumn": 17, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "time" - }, - "fix": { - "range": [1845, 1896], - "text": "" - }, - "desc": "Remove the console.time()." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'groupingRules' is assigned a value but never used.", - "line": 57, - "column": 11, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 57, - "endColumn": 24 - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 63, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 63, - "endColumn": 20, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "timeEnd" - }, - "fix": { - "range": [2191, 2245], - "text": "" - }, - "desc": "Remove the console.timeEnd()." - } - ] - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 69, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 69, - "endColumn": 17, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "time" - }, - "fix": { - "range": [2364, 2420], - "text": "" - }, - "desc": "Remove the console.time()." - } - ] - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 71, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 71, - "endColumn": 20, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "timeEnd" - }, - "fix": { - "range": [2485, 2544], - "text": "" - }, - "desc": "Remove the console.timeEnd()." - } - ] - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 0, - "warningCount": 6, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { AuditOutput } from '@code-pushup/models';\nimport type { BundleStatsConfig } from '../types.js';\nimport type { UnifiedStats } from '../unify/unified-stats.types.js';\nimport { createDisplayValue, createEmptyAudit } from '../utils.js';\nimport { createAuditOutputDetails } from './details/audit-details.js';\nimport { getIssues } from './details/issues.js';\nimport { createBundleStatsScoring } from './scoring.js';\nimport { selectBundles } from './selection.js';\n\n/**\n * Calculates total bytes from unified stats tree. Aggregates byte counts across all artefacts.\n */\nexport function calculateTotalBytes(statsSlice: UnifiedStats): number {\n return Object.values(statsSlice).reduce((acc, curr) => acc + curr.bytes, 0);\n}\n\n/**\n * Creates audit output from processed tree data and configuration. Combines size scoring with penalty calculations from actual issues.\n */\nexport function createAuditOutput(\n statsSlice: UnifiedStats,\n config: BundleStatsConfig,\n): AuditOutput {\n const trees = Object.values(statsSlice);\n const totalBytes = calculateTotalBytes(statsSlice);\n\n console.time('⚡ GET_ISSUES');\n const issues = getIssues(statsSlice, config);\n console.timeEnd('⚡ GET_ISSUES');\n\n const calculateScore = createBundleStatsScoring({\n mode: config.scoring.mode,\n totalSize: config.scoring.totalSize,\n penalty: config.scoring.penalty,\n });\n\n return {\n slug: config.slug,\n score: calculateScore(totalBytes, issues),\n value: totalBytes,\n displayValue: createDisplayValue(totalBytes, trees.length),\n details: createAuditOutputDetails(issues, statsSlice, config),\n };\n}\n\n/**\n * Generates audit outputs from bundle stats tree and configurations\n */\nexport function generateAuditOutputs(\n bundleStatsTree: UnifiedStats,\n configs: BundleStatsConfig[],\n): AuditOutput[] {\n return configs.map(config => {\n console.time(`🔍 SELECT_BUNDLES - ${config.slug}`);\n\n // Extract grouping rules for feature mode filtering\n const groupingRules =\n config.insightsTable && typeof config.insightsTable === 'object'\n ? config.insightsTable.groups\n : undefined;\n\n const filteredTree = selectBundles(bundleStatsTree, config.selection);\n console.timeEnd(`🔍 SELECT_BUNDLES - ${config.slug}`);\n\n if (!filteredTree || Object.keys(filteredTree).length === 0) {\n return createEmptyAudit(config);\n }\n\n console.time(`📝 CREATE_AUDIT_OUTPUT - ${config.slug}`);\n const result = createAuditOutput(filteredTree, config);\n console.timeEnd(`📝 CREATE_AUDIT_OUTPUT - ${config.slug}`);\n\n return result;\n });\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/audit-outputs.unit.test.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/audit-details.ts", - "messages": [ - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 25, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 25, - "endColumn": 17, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "time" - }, - "fix": { - "range": [778, 819], - "text": "" - }, - "desc": "Remove the console.time()." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 26, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 26, - "endColumn": 74 - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 27, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 27, - "endColumn": 20, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "timeEnd" - }, - "fix": { - "range": [899, 943], - "text": "" - }, - "desc": "Remove the console.timeEnd()." - } - ] - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 38, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 38, - "endColumn": 17, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "time" - }, - "fix": { - "range": [1295, 1326], - "text": "" - }, - "desc": "Remove the console.time()." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 39, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 47, - "endColumn": 6 - }, - { - "ruleId": "no-console", - "severity": 1, - "message": "Unexpected console statement.", - "line": 48, - "column": 5, - "nodeType": "MemberExpression", - "messageId": "unexpected", - "endLine": 48, - "endColumn": 20, - "suggestions": [ - { - "messageId": "removeConsole", - "data": { - "propertyName": "timeEnd" - }, - "fix": { - "range": [1684, 1718], - "text": "" - }, - "desc": "Remove the console.timeEnd()." - } - ] - } - ], - "suppressedMessages": [], - "errorCount": 2, - "fatalErrorCount": 0, - "warningCount": 4, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { AuditDetails, Issue } from '@code-pushup/models';\nimport type { BundleStatsConfig } from '../../types.js';\nimport type { UnifiedStats } from '../../unify/unified-stats.types.js';\nimport { createInsightsTable } from './table.js';\nimport { createTree } from './tree.js';\n\n/**\n * Creates audit details containing issues, insights table, and artifact tree based on configuration.\n * Assembles comprehensive output details for bundle analysis reporting.\n */\nexport function createAuditOutputDetails(\n issues: Issue[],\n statsSlice: UnifiedStats,\n config: BundleStatsConfig,\n): AuditDetails {\n const details: AuditDetails = {\n issues,\n };\n\n if (\n config.insightsTable &&\n config.insightsTable.groups &&\n config.insightsTable.groups.length > 0\n ) {\n console.time('📊 CREATE_INSIGHTS_TABLE');\n details.table = createInsightsTable(statsSlice, config.insightsTable);\n console.timeEnd('📊 CREATE_INSIGHTS_TABLE');\n }\n\n // Check if dependency tree is enabled (default: enabled if config exists)\n const isTreeEnabled =\n config.dependencyTree &&\n typeof config.dependencyTree === 'object' &&\n (!('enabled' in config.dependencyTree) ||\n config.dependencyTree.enabled !== false);\n\n if (isTreeEnabled && typeof config.dependencyTree === 'object') {\n console.time('🌳 CREATE_TREE');\n details.trees = [\n createTree(statsSlice, {\n title: config.slug,\n mode: config.dependencyTree.mode ?? 'onlyMatching',\n pruning: config.dependencyTree.pruning ?? {},\n groups: config.dependencyTree.groups ?? [],\n selection: config.selection, // Pass selection config for onlyMatching filtering\n }),\n ];\n console.timeEnd('🌳 CREATE_TREE');\n }\n\n return details;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/formatting.ts", - "messages": [ - { - "ruleId": "import/no-cycle", - "severity": 2, - "message": "Dependency cycle detected.", - "line": 1, - "column": 1, - "nodeType": "ImportDeclaration", - "endLine": 7, - "endColumn": 24 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 37, - "column": 14, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 37, - "endColumn": 23 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: -2.", - "line": 60, - "column": 33, - "nodeType": "UnaryExpression", - "messageId": "noMagic", - "endLine": 60, - "endColumn": 35 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 83, - "column": 3, - "nodeType": "ForStatement", - "messageId": "generic", - "endLine": 95, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 83, - "column": 8, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 83, - "endColumn": 17 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 98, - "column": 3, - "nodeType": "ForStatement", - "messageId": "generic", - "endLine": 106, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 98, - "column": 8, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 98, - "endColumn": 35 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 129, - "column": 21, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 129, - "endColumn": 41 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 137, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 148, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 158, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 169, - "endColumn": 4 - } - ], - "suppressedMessages": [], - "errorCount": 3, - "fatalErrorCount": 0, - "warningCount": 7, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import {\n extractConcreteSegments,\n extractPathSlice,\n findSegmentIndex,\n normalizePathForMatching,\n splitPathSegments,\n} from './grouping.js';\n\n// Regex cache to avoid recreating the same regex patterns\nconst REGEX_CACHE = new Map();\n\nfunction getCachedRegex(pattern: string): RegExp {\n const cached = REGEX_CACHE.get(pattern);\n if (cached) {\n return cached;\n }\n\n const regex = new RegExp(`${pattern}\\\\/([^\\\\/]+)`);\n REGEX_CACHE.set(pattern, regex);\n return regex;\n}\n\nexport function removeFileExtension(name: string): string {\n return name.replace(/\\.(js|ts|jsx|tsx|css|scss|json)$/, '');\n}\n\nexport function isGenericName(name: string): boolean {\n return name === 'index' || name === 'main' || name === '';\n}\n\nexport function extractScopedPackage(\n path: string,\n): { scope: string; package?: string } | null {\n const match = path.match(/@([^/]+)(?:\\/([^/]+))?/);\n if (match) {\n return {\n scope: match[1]!,\n package: match[2],\n };\n }\n return null;\n}\n\nexport function extractMeaningfulPathPart(path: string): string | null {\n const parts = splitPathSegments(path.replace(/^\\.\\//, ''));\n\n if (parts.length === 0) {\n return null;\n }\n\n const lastPart = parts.at(-1);\n if (lastPart) {\n const withoutExt = removeFileExtension(lastPart);\n if (withoutExt && !isGenericName(withoutExt)) {\n return withoutExt;\n }\n }\n\n if (parts.length > 1) {\n const secondLast = parts.at(-2);\n if (secondLast && !isGenericName(secondLast)) {\n return secondLast;\n }\n }\n\n return null;\n}\n\nexport function cleanupGroupName(groupName: string): string {\n const scopedPackage = extractScopedPackage(groupName);\n if (scopedPackage) {\n return scopedPackage.package\n ? `@${scopedPackage.scope}/${scopedPackage.package}`\n : `@${scopedPackage.scope}`;\n }\n\n const segments = splitPathSegments(groupName);\n if (segments.length === 0) {\n return groupName;\n }\n\n // For scoped packages, try to extract the scope and package\n for (let i = 0; i < segments.length; i++) {\n const segment = segments[i];\n if (!segment) {\n continue;\n }\n\n // Handle scoped packages like @angular/router\n if (segment.startsWith('@') && i + 1 < segments.length) {\n const scopeName = segment.slice(1);\n const packageName = segments[i + 1];\n return packageName ? `@${scopeName}/${packageName}` : `@${scopeName}`;\n }\n }\n\n // Extract the last meaningful segment (the actual package/folder name)\n for (let i = segments.length - 1; i >= 0; i--) {\n const segment = segments[i];\n if (!segment || isGenericName(segment)) {\n continue;\n }\n\n // Return the first meaningful segment we find from the end\n return segment;\n }\n\n const withoutExt = removeFileExtension(groupName);\n if (isGenericName(withoutExt)) {\n return groupName;\n }\n\n return withoutExt || groupName;\n}\n\nexport function extractGroupKeyFromPattern(\n filePath: string,\n pattern: string,\n maxDepth?: number,\n): string | null {\n const normalizedPath = normalizePathForMatching(filePath);\n const concreteSegments = extractConcreteSegments(pattern);\n\n if (concreteSegments.length === 0) {\n return extractMeaningfulPathPart(normalizedPath);\n }\n\n if (maxDepth && maxDepth > 0 && concreteSegments.length > 0) {\n const keyPart = concreteSegments[0]!;\n const keyIndex = findSegmentIndex(filePath, keyPart);\n\n if (keyIndex !== -1) {\n return extractPathSlice(filePath, keyIndex, maxDepth);\n }\n }\n\n for (const segment of concreteSegments) {\n const regex = getCachedRegex(segment); // Use cached regex\n const match = filePath.match(regex) || normalizedPath.match(regex);\n\n if (match?.[1]) {\n const extracted = match[1];\n const cleaned = removeFileExtension(extracted);\n if (cleaned && !isGenericName(cleaned)) {\n return cleaned;\n }\n }\n }\n\n return null;\n}\n\nexport function deriveGroupTitle(\n path: string,\n patterns: readonly string[],\n fallbackTitle: string,\n): string {\n for (const pattern of patterns) {\n const concreteSegments = extractConcreteSegments(pattern);\n\n if (concreteSegments.includes(fallbackTitle)) {\n return fallbackTitle;\n }\n\n const groupName = extractGroupKeyFromPattern(path, pattern);\n if (groupName) {\n return cleanupGroupName(groupName);\n }\n }\n\n return fallbackTitle;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.ts", - "messages": [ - { - "ruleId": "import/no-cycle", - "severity": 2, - "message": "Dependency cycle detected.", - "line": 3, - "column": 1, - "nodeType": "ImportDeclaration", - "endLine": 7, - "endColumn": 26 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'ArtefactType' is defined but never used.", - "line": 8, - "column": 15, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 8, - "endColumn": 27 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 139, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 145, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 141, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 141, - "endColumn": 45 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 143, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 143, - "endColumn": 36 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 161, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 166, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 175, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 180, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 208, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 218, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 249, - "column": 7, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 249, - "endColumn": 35 - }, - { - "ruleId": "@typescript-eslint/consistent-type-assertions", - "severity": 2, - "message": "Always prefer const x: T = { ... }.", - "line": 252, - "column": 17, - "nodeType": "TSAsExpression", - "messageId": "unexpectedObjectTypeAssertion", - "endLine": 258, - "endColumn": 15, - "suggestions": [ - { - "messageId": "replaceObjectTypeAssertionWithSatisfies", - "data": { - "cast": "T" - }, - "fix": { - "range": [6366, 6493], - "text": "{\n title,\n bytes: 0,\n modules: 0,\n type: 'group',\n icon: rule.icon,\n } satisfies T" - }, - "desc": "Use const x = { ... } satisfies T instead." - } - ] - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 330, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 335, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 348, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 348, - "endColumn": 28 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 349, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 358, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.6.", - "line": 359, - "column": 41, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 359, - "endColumn": 44 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.5.", - "line": 363, - "column": 64, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 363, - "endColumn": 67 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'findCommonPath' has too many lines (70). Maximum allowed is 50.", - "line": 371, - "column": 1, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 448, - "endColumn": 2 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'findCommonPath' is defined but never used.", - "line": 371, - "column": 10, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 371, - "endColumn": 24 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 376, - "column": 29, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 376, - "endColumn": 38 - }, - { - "ruleId": "max-lines", - "severity": 1, - "message": "File has too many lines (489). Maximum allowed is 300.", - "line": 377, - "column": 1, - "nodeType": null, - "messageId": "exceed", - "endLine": 601, - "endColumn": 1 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 400, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 412, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 408, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 408, - "endColumn": 35 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 435, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 435, - "endColumn": 39 - }, - { - "ruleId": "no-param-reassign", - "severity": 2, - "message": "Assignment to property of function parameter 'acc'.", - "line": 435, - "column": 9, - "nodeType": "Identifier", - "messageId": "assignmentToFunctionParamProp", - "endLine": 435, - "endColumn": 12 - }, - { - "ruleId": "@typescript-eslint/consistent-type-assertions", - "severity": 2, - "message": "Always prefer const x: T = { ... }.", - "line": 439, - "column": 5, - "nodeType": "TSAsExpression", - "messageId": "unexpectedObjectTypeAssertion", - "endLine": 439, - "endColumn": 33, - "suggestions": [ - { - "messageId": "replaceObjectTypeAssertionWithSatisfies", - "data": { - "cast": "Record" - }, - "fix": { - "range": [11428, 11456], - "text": "{} satisfies Record" - }, - "desc": "Use const x = { ... } satisfies Record instead." - } - ] - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'applyGrouping' has too many lines (125). Maximum allowed is 50.", - "line": 453, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 600, - "endColumn": 2 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 462, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 462, - "endColumn": 31 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 465, - "column": 3, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 465, - "endColumn": 61 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 467, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 578, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'excludeInputs' is assigned a value but never used.", - "line": 471, - "column": 7, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 471, - "endColumn": 20 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 482, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 482, - "endColumn": 32 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 484, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 484, - "endColumn": 34 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 505, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 505, - "endColumn": 47 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 505, - "column": 11, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 505, - "endColumn": 36, - "suggestions": [ - { - "messageId": "suggestOptionalChain", - "fix": { - "range": [13564, 13565], - "text": "?" - }, - "desc": "Consider using the optional chain operator `?.` instead. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 527, - "column": 23, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 529, - "endColumn": 14 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 531, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 531, - "endColumn": 40 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 534, - "column": 9, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 534, - "endColumn": 36 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 565, - "column": 21, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 567, - "endColumn": 12 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 569, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 569, - "endColumn": 37 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 572, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 572, - "endColumn": 67 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 573, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 573, - "endColumn": 43 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 577, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 577, - "endColumn": 63 - } - ], - "suppressedMessages": [], - "errorCount": 24, - "fatalErrorCount": 0, - "warningCount": 17, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { minimatch } from 'minimatch';\nimport type { GroupingRule, LogicalGroupingRule } from '../../types.js';\nimport {\n cleanupGroupName,\n deriveGroupTitle,\n extractGroupKeyFromPattern,\n} from './formatting.js';\nimport type { ArtefactType, StatsNodeValues } from './types.js';\n\nexport type PatternMatcher = (path: string) => boolean;\n\n// Pattern cache to avoid recompiling the same patterns\nconst PATTERN_CACHE = new Map();\n\n/**\n * Normalizes patterns from string | PatternList to readonly string[].\n */\nfunction normalizePatterns(\n patterns?: string | readonly string[],\n): readonly string[] {\n if (!patterns) {\n return [];\n }\n\n const normalizedArray = typeof patterns === 'string' ? [patterns] : patterns;\n\n // Filter out any undefined, null, or empty string values\n return normalizedArray.filter(\n (pattern): pattern is string =>\n typeof pattern === 'string' && pattern.trim() !== '',\n );\n}\n\nexport type MatchOptions = {\n matchBase?: boolean;\n normalizeRelativePaths?: boolean;\n};\n\nexport type GroupData = Omit & {\n title: string;\n type: 'group';\n};\n\nexport type GroupManager = {\n groups: Map;\n findOrCreateGroup: (\n key: string,\n rule: LogicalGroupingRule,\n defaultTitle?: string,\n ) => T;\n getAllGroups: () => T[];\n getGroupsWithData: () => T[];\n};\n\nexport type StatsTreeNode = {\n children: StatsTreeNode[];\n name: string;\n values: StatsNodeValues;\n};\n\nexport type StatsTree = {\n root: StatsTreeNode;\n};\n\nconst DEFAULT_GROUP_NAME = 'Group';\n\nexport function splitPathSegments(path: string): string[] {\n return path.split('/').filter(part => part !== '');\n}\n\nexport function normalizePathForMatching(path: string): string {\n return path.replace(/\\.\\.\\//g, '').replace(/^\\/+/, '');\n}\n\n/**\n * Compiles pattern into cached matcher function. Avoids recompilation overhead.\n */\nexport function compilePattern(\n pattern: string,\n options: MatchOptions = {},\n): PatternMatcher {\n // Create cache key from pattern and options\n const cacheKey = `${pattern}|${JSON.stringify(options)}`;\n\n // Return cached pattern if available\n const cached = PATTERN_CACHE.get(cacheKey);\n if (cached) {\n return cached;\n }\n\n // Compile new pattern\n const matcher = (path: string) => {\n const minimatchOptions = options.matchBase ? { matchBase: true } : {};\n if (minimatch(path, pattern, minimatchOptions)) {\n return true;\n }\n if (options.normalizeRelativePaths) {\n const normalizedPath = normalizePathForMatching(path);\n return minimatch(normalizedPath, pattern, minimatchOptions);\n }\n return false;\n };\n\n // Cache and return\n PATTERN_CACHE.set(cacheKey, matcher);\n return matcher;\n}\n\n/**\n * Checks if path matches a GroupingRule using include/exclude logic\n */\nfunction matchesGroupingRule(\n path: string,\n rule: GroupingRule,\n options: MatchOptions = {},\n): boolean {\n const includePatterns = normalizePatterns(rule.includeInputs);\n const excludePatterns = normalizePatterns(rule.excludeInputs);\n\n return evaluatePathWithIncludeExclude(\n path,\n includePatterns,\n excludePatterns,\n options,\n );\n}\n\n/**\n * Separates patterns into include and exclude arrays. Exclude patterns start with !\n * @deprecated - Use the new include/exclude GroupingRule format instead\n */\nfunction separateIncludeExcludePatterns(patterns: readonly string[]): {\n includePatterns: string[];\n excludePatterns: string[];\n} {\n const includePatterns: string[] = [];\n const excludePatterns: string[] = [];\n\n for (const pattern of patterns) {\n if (pattern.startsWith('!')) {\n excludePatterns.push(pattern.slice(1)); // Remove ! prefix\n } else {\n includePatterns.push(pattern);\n }\n }\n\n return { includePatterns, excludePatterns };\n}\n\n/**\n * Evaluates path against include/exclude patterns using the same logic as selection system\n */\nfunction evaluatePathWithIncludeExclude(\n path: string,\n includePatterns: readonly string[],\n excludePatterns: readonly string[],\n options: MatchOptions = {},\n): boolean {\n // If exclude patterns exist, check if path matches any - if so, exclude it\n if (excludePatterns.length > 0) {\n for (const pattern of excludePatterns) {\n const matcher = compilePattern(pattern, options);\n if (matcher(path)) {\n return false;\n }\n }\n }\n\n // If no include patterns, include everything (after exclusion check)\n if (includePatterns.length === 0) {\n return true;\n }\n\n // Check if path matches any include pattern\n for (const pattern of includePatterns) {\n const matcher = compilePattern(pattern, options);\n if (matcher(path)) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function matchesAnyPattern(\n path: string,\n patterns: readonly string[],\n options: MatchOptions = {},\n): boolean {\n // Legacy support for old patterns array format\n const { includePatterns, excludePatterns } =\n separateIncludeExcludePatterns(patterns);\n return evaluatePathWithIncludeExclude(\n path,\n includePatterns,\n excludePatterns,\n options,\n );\n}\n\n/**\n * Finds first matching rule for path. Processes rules in forward order for top-down precedence.\n */\nexport function findMatchingRule(\n filePath: string,\n rules: GroupingRule[],\n): GroupingRule | null {\n for (const rule of rules) {\n if (\n rule &&\n matchesGroupingRule(filePath, rule, {\n matchBase: true,\n normalizeRelativePaths: true,\n })\n ) {\n return rule;\n }\n }\n return null;\n}\n\nexport function generateGroupKey(\n filePath: string,\n rule: GroupingRule,\n preferRuleTitle = false,\n): string {\n if (preferRuleTitle && rule.title) {\n return rule.title;\n }\n\n // For new include/exclude format, use the include patterns for title generation\n const includePatterns = normalizePatterns(rule.includeInputs);\n return deriveGroupTitle(\n filePath,\n includePatterns,\n rule.title || DEFAULT_GROUP_NAME,\n );\n}\n\nexport function createGroupManager(): GroupManager {\n const groups = new Map();\n return {\n groups,\n findOrCreateGroup(\n key: string,\n rule: LogicalGroupingRule,\n defaultTitle?: string,\n ): T {\n let group = groups.get(key);\n if (!group) {\n const title = rule.title || defaultTitle || key;\n group = {\n title,\n bytes: 0,\n modules: 0,\n type: 'group',\n icon: rule.icon,\n } as T;\n groups.set(key, group);\n }\n return group;\n },\n getAllGroups(): T[] {\n return [...groups.values()];\n },\n getGroupsWithData(): T[] {\n return [...groups.values()].filter(g => g.bytes > 0);\n },\n };\n}\n\nexport function toLogicalGroupingRule(rule: GroupingRule): LogicalGroupingRule {\n const { numSegments: maxDepth, ...rest } = rule;\n return { ...rest, maxDepth: 1 };\n}\n\nexport function findOrCreateGroupFromRule(\n groupManager: GroupManager,\n key: string,\n rule: GroupingRule,\n defaultTitle?: string,\n): T {\n const logicalRule = toLogicalGroupingRule(rule);\n return groupManager.findOrCreateGroup(key, logicalRule, defaultTitle);\n}\n\nexport function processForTable(\n filePath: string,\n rules: GroupingRule[],\n preferRuleTitle = true,\n): { rule: GroupingRule | null; groupKey: string | null } {\n const rule = findMatchingRule(filePath, rules);\n if (!rule) {\n return { rule: null, groupKey: null };\n }\n const groupKey = generateGroupKey(filePath, rule, preferRuleTitle);\n return { rule, groupKey };\n}\n\nexport function extractConcreteSegments(pattern: string): string[] {\n return splitPathSegments(pattern).filter(\n segment => segment !== '**' && segment !== '*' && !segment.includes('*'),\n );\n}\n\nexport function findSegmentIndex(filePath: string, segment: string): number {\n return splitPathSegments(filePath).indexOf(segment);\n}\n\nexport function extractPathSlice(\n filePath: string,\n startIndex: number,\n maxDepth?: number,\n): string {\n const pathParts = splitPathSegments(filePath);\n const endIndex = maxDepth\n ? Math.min(startIndex + maxDepth, pathParts.length)\n : pathParts.length;\n return pathParts.slice(startIndex, endIndex).join('/');\n}\n\nfunction extractIntelligentGroupKey(\n filePath: string,\n patterns: readonly string[],\n maxDepth: number,\n): string {\n const pathParts = splitPathSegments(filePath);\n\n // Try pattern-based extraction first\n for (const pattern of patterns) {\n const patternKey = extractGroupKeyFromPattern(filePath, pattern, maxDepth);\n if (patternKey) {\n return patternKey;\n }\n }\n\n // Fallback to simple depth-based extraction from the beginning of path\n if (pathParts.length >= maxDepth) {\n return pathParts.slice(0, maxDepth).join('/');\n }\n\n // If path is shorter than maxDepth, use the whole path\n return pathParts.join('/');\n}\n\nfunction checkForScopedPackages(paths: string[]): string | null {\n const scopeGroups = new Map();\n let totalScopedPaths = 0;\n for (const path of paths) {\n const scopedMatch = path.match(/.*\\/@([^/]+)\\/[^/]+/);\n if (scopedMatch) {\n const scope = scopedMatch[1];\n if (scope) {\n scopeGroups.set(scope, (scopeGroups.get(scope) || 0) + 1);\n totalScopedPaths++;\n }\n }\n }\n if (totalScopedPaths > paths.length * 0.6) {\n const dominantScope = [...scopeGroups.entries()].sort(\n ([, a], [, b]) => (b as number) - (a as number),\n )[0];\n if (dominantScope && dominantScope[1] > totalScopedPaths * 0.5) {\n return `@${dominantScope[0]}`;\n }\n return 'Scoped Packages';\n }\n return null;\n}\n\nfunction findCommonPath(paths: string[]): string {\n if (paths.length === 0) {\n return DEFAULT_GROUP_NAME;\n }\n if (paths.length === 1) {\n return deriveGroupTitle(paths[0]!, [], DEFAULT_GROUP_NAME);\n }\n\n const scopedPackagePattern = checkForScopedPackages(paths);\n if (scopedPackagePattern) {\n return scopedPackagePattern;\n }\n\n const commonRelativePrefix = paths.every(path => path.startsWith('../'))\n ? '../'\n : '';\n const normalizedPaths = paths.map(path => {\n const normalized = path.startsWith('../')\n ? path.replace(/^(\\.\\.\\/)+/, '')\n : path;\n return splitPathSegments(normalized);\n });\n\n const firstPath = normalizedPaths[0];\n if (!firstPath || firstPath.length === 0) {\n return DEFAULT_GROUP_NAME;\n }\n\n const commonSegments: string[] = [];\n for (const [i, segment] of firstPath.entries()) {\n if (!segment) {\n continue;\n }\n const isCommonToAll = normalizedPaths.every(\n pathSegments => pathSegments && pathSegments[i] === segment,\n );\n if (isCommonToAll) {\n commonSegments.push(segment);\n } else {\n break;\n }\n }\n\n if (commonSegments.length > 0) {\n const commonPath = `${commonRelativePrefix + commonSegments.join('/')}/**`;\n if (commonPath.includes('@*/') || commonPath.includes('*/')) {\n return DEFAULT_GROUP_NAME;\n }\n return commonPath;\n }\n\n const parentDirs = normalizedPaths\n .map(pathSegments => {\n const parentDir =\n pathSegments && pathSegments.length > 0\n ? pathSegments.slice(0, -1).pop()\n : undefined;\n return parentDir || '';\n })\n .filter(dir => dir.length > 0);\n\n const dirCounts = parentDirs.reduce(\n (acc, dir) => {\n if (dir) {\n acc[dir] = (acc[dir] || 0) + 1;\n }\n return acc;\n },\n {} as Record,\n );\n\n const mostCommonDir = Object.entries(dirCounts).sort(\n ([, a], [, b]) => (b as number) - (a as number),\n )[0]?.[0];\n return mostCommonDir\n ? `${commonRelativePrefix + mostCommonDir}/**`\n : DEFAULT_GROUP_NAME;\n}\n\n/**\n * Groups nodes by patterns at current level only. Organizes files into logical groups without recursive processing.\n */\nexport function applyGrouping(\n nodes: StatsTreeNode[],\n groups: GroupingRule[],\n): StatsTreeNode[] {\n if (!groups || groups.length === 0) {\n return [...nodes].sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n // Process nodes without recursive grouping - caller handles recursion\n let finalNodes = [...nodes];\n // Track original input nodes vs newly created group nodes\n const originalNodes = new Set(nodes);\n finalNodes.sort((a, b) => b.values.bytes - a.values.bytes);\n\n for (const group of groups) {\n const {\n title,\n includeInputs,\n excludeInputs,\n icon,\n numSegments: maxDepth,\n } = group;\n const nodesToGroup: StatsTreeNode[] = [];\n const remainingNodes: StatsTreeNode[] = [];\n\n finalNodes.forEach(node => {\n const matchingRule = findMatchingRule(node.name, [group]);\n if (matchingRule && originalNodes.has(node)) {\n // Only group original input nodes, not previously created group nodes\n nodesToGroup.push(node);\n } else {\n remainingNodes.push(node);\n }\n });\n\n if (nodesToGroup.length > 0) {\n const groupedNodes: StatsTreeNode[] = [];\n\n // When reduce is true, always create a single consolidated group\n const shouldCreateSingleGroup = !maxDepth || maxDepth === 0;\n\n if (!shouldCreateSingleGroup && maxDepth && maxDepth > 0) {\n const pathGroups = new Map();\n nodesToGroup.forEach(node => {\n const groupKey = extractIntelligentGroupKey(\n node.name,\n normalizePatterns(includeInputs),\n maxDepth,\n );\n if (!pathGroups.has(groupKey)) {\n pathGroups.set(groupKey, []);\n }\n pathGroups.get(groupKey)!.push(node);\n });\n\n pathGroups.forEach((nodesInGroup, groupPath) => {\n const totalBytes = nodesInGroup.reduce(\n (sum, node) => sum + node.values.bytes,\n 0,\n );\n const totalModules = nodesInGroup.reduce(\n (sum, node) => sum + node.values.modules,\n 0,\n );\n\n const folderNode: StatsTreeNode = {\n name: title || cleanupGroupName(groupPath),\n values: {\n path: groupPath,\n bytes: totalBytes,\n modules: totalModules,\n type: 'group',\n icon,\n },\n children: nodesInGroup.sort(\n (a, b) => b.values.bytes - a.values.bytes,\n ),\n };\n groupedNodes.push(folderNode);\n });\n } else {\n let effectiveTitle: string;\n if (title) {\n effectiveTitle = title;\n } else {\n const samplePath = nodesToGroup[0]?.name || '';\n effectiveTitle = deriveGroupTitle(\n samplePath,\n normalizePatterns(includeInputs),\n DEFAULT_GROUP_NAME,\n );\n }\n\n const totalBytes = nodesToGroup.reduce(\n (sum, node) => sum + node.values.bytes,\n 0,\n );\n const totalModules = nodesToGroup.reduce(\n (sum, node) => sum + node.values.modules,\n 0,\n );\n\n const groupNode: StatsTreeNode = {\n name: effectiveTitle,\n values: {\n path: '',\n bytes: totalBytes,\n modules: totalModules,\n type: 'group',\n icon,\n },\n // When reduce is true, don't show children - collapse to summary only\n children: nodesToGroup.sort(\n (a, b) => b.values.bytes - a.values.bytes,\n ),\n };\n groupedNodes.push(groupNode);\n }\n\n groupedNodes.sort((a, b) => b.values.bytes - a.values.bytes);\n remainingNodes.push(...groupedNodes);\n }\n\n finalNodes = remainingNodes;\n finalNodes.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n // Filter out files that are excluded by any group's exclude patterns\n return finalNodes.filter(node => {\n // Keep group nodes (created by grouping process)\n if (!originalNodes.has(node)) {\n return true;\n }\n\n // For original nodes, check if they're excluded by any group\n return !groups.some(group => {\n if (!group.excludeInputs || group.excludeInputs.length === 0) {\n return false;\n }\n\n const excludePatterns = normalizePatterns(group.excludeInputs);\n return excludePatterns.some(pattern => {\n const matcher = compilePattern(pattern);\n return matcher(node.name);\n });\n });\n });\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/grouping.unit.test.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'StatsTreeNode' is defined but never used.", - "line": 4, - "column": 8, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 4, - "endColumn": 21 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'applyGrouping' is defined but never used.", - "line": 5, - "column": 3, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 5, - "endColumn": 16 - } - ], - "suppressedMessages": [], - "errorCount": 2, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it } from 'vitest';\nimport type { GroupingRule } from '../../types.js';\nimport {\n type StatsTreeNode,\n applyGrouping,\n findMatchingRule,\n} from './grouping.js';\n\ndescribe('GroupingRule exclude logic', () => {\n it('should exclude paths that match exclude patterns even when they match include patterns', () => {\n const rule: GroupingRule = {\n includeInputs: '**/node_modules/**',\n excludeInputs: [\n '**/node_modules/react/**',\n '**/node_modules/@angular/**',\n ],\n };\n\n // These paths match include but should be excluded\n expect(findMatchingRule('node_modules/react/index.js', [rule])).toBeNull();\n expect(\n findMatchingRule('node_modules/@angular/core/index.js', [rule]),\n ).toBeNull();\n\n // This path matches include and is not excluded\n expect(findMatchingRule('node_modules/lodash/index.js', [rule])).toEqual(\n rule,\n );\n });\n\n it('should handle multiple exclude patterns', () => {\n const rule: GroupingRule = {\n includeInputs: '**/src/**',\n excludeInputs: ['**/*.test.ts', '**/*.spec.ts', '**/src/legacy/**'],\n };\n\n // These should be excluded\n expect(findMatchingRule('src/app.test.ts', [rule])).toBeNull();\n expect(findMatchingRule('src/utils.spec.ts', [rule])).toBeNull();\n expect(findMatchingRule('src/legacy/old-code.ts', [rule])).toBeNull();\n\n // This should match\n expect(findMatchingRule('src/app.ts', [rule])).toEqual(rule);\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 50_000.", - "line": 18, - "column": 38, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 18, - "endColumn": 44 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 71, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 76, - "endColumn": 4 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'checkBlacklistIssues' has too many lines (91). Maximum allowed is 50.", - "line": 199, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 302, - "endColumn": 2 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 212, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 219, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 229, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 236, - "endColumn": 8 - }, - { - "ruleId": "guard-for-in", - "severity": 2, - "message": "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", - "line": 242, - "column": 5, - "nodeType": "ForInStatement", - "messageId": "wrap", - "endLine": 257, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 242, - "column": 5, - "nodeType": "ForInStatement", - "messageId": "generic", - "endLine": 257, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 248, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 255, - "endColumn": 10 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 262, - "column": 5, - "nodeType": "ForStatement", - "messageId": "generic", - "endLine": 298, - "endColumn": 6 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 262, - "column": 10, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 262, - "endColumn": 19 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 263, - "column": 26, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 263, - "endColumn": 44 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 271, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 278, - "endColumn": 10 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 288, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 295, - "endColumn": 12 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'getIssues' has too many lines (66). Maximum allowed is 50.", - "line": 311, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 393, - "endColumn": 2 - }, - { - "ruleId": "guard-for-in", - "severity": 2, - "message": "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", - "line": 344, - "column": 3, - "nodeType": "ForInStatement", - "messageId": "wrap", - "endLine": 367, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 344, - "column": 3, - "nodeType": "ForInStatement", - "messageId": "generic", - "endLine": 367, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 345, - "column": 20, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 345, - "endColumn": 43 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 348, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 355, - "endColumn": 8 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 370, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 390, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'patternKey' is assigned a value but never used. Allowed unused elements of array destructuring must match /^_/u.", - "line": 371, - "column": 5, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 371, - "endColumn": 15 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 376, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 376, - "endColumn": 80 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 376, - "column": 42, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 376, - "endColumn": 51 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 380, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 388, - "endColumn": 8 - }, - { - "ruleId": "@typescript-eslint/max-params", - "severity": 1, - "message": "Function 'createBlacklistedPatternIssue' has too many parameters (5). Maximum allowed is 4.", - "line": 398, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 398, - "endColumn": 46 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'files' is defined but never used. Allowed unused args must match /^_/u.", - "line": 403, - "column": 3, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 403, - "endColumn": 8 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'collectBlacklistedPatterns' has too many lines (77). Maximum allowed is 50.", - "line": 418, - "column": 1, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 506, - "endColumn": 2 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 433, - "column": 24, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 433, - "endColumn": 60 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 435, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 435, - "endColumn": 38 - }, - { - "ruleId": "max-lines", - "severity": 1, - "message": "File has too many lines (351). Maximum allowed is 300.", - "line": 444, - "column": 1, - "nodeType": null, - "messageId": "exceed", - "endLine": 507, - "endColumn": 1 - }, - { - "ruleId": "guard-for-in", - "severity": 2, - "message": "The body of a for-in should be wrapped in an if statement to filter unwanted properties from the prototype.", - "line": 469, - "column": 5, - "nodeType": "ForInStatement", - "messageId": "wrap", - "endLine": 477, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 469, - "column": 5, - "nodeType": "ForInStatement", - "messageId": "generic", - "endLine": 477, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 482, - "column": 5, - "nodeType": "ForStatement", - "messageId": "generic", - "endLine": 504, - "endColumn": 6 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 482, - "column": 10, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 482, - "endColumn": 19 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 483, - "column": 26, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 483, - "endColumn": 44 - } - ], - "suppressedMessages": [], - "errorCount": 19, - "fatalErrorCount": 0, - "warningCount": 15, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { minimatch } from 'minimatch';\nimport type { Issue } from '@code-pushup/models';\nimport { formatBytes } from '@code-pushup/utils';\nimport type { BundleStatsConfig } from '../../types.js';\nimport type {\n UnifiedStats,\n UnifiedStatsBundle,\n} from '../../unify/unified-stats.types.js';\nimport type { BlacklistEntry, BlacklistPatternList } from '../scoring.js';\n\n// ===== PERFORMANCE OPTIMIZATIONS =====\n\n// Cache for blacklist pattern matches to avoid repeated minimatch calls\nconst BLACKLIST_PATTERN_CACHE = new Map();\n\n// Clear cache when it gets too large to prevent memory issues\nfunction clearCacheIfNeeded(): void {\n if (BLACKLIST_PATTERN_CACHE.size > 50_000) {\n BLACKLIST_PATTERN_CACHE.clear();\n }\n}\n\n// ===== ISSUE ICONS =====\n\nexport const ISSUE_ICONS = {\n TOO_LARGE: '🔺',\n TOO_SMALL: '🔻',\n BLACKLIST: '🚫',\n} as const;\n\n/**\n * Normalizes blacklist entry to extract pattern string and hint.\n */\nfunction normalizeBlacklistEntry(entry: BlacklistEntry): {\n pattern: string;\n hint?: string;\n} {\n if (typeof entry === 'string') {\n return { pattern: entry };\n }\n return { pattern: entry.pattern, hint: entry.hint };\n}\n\n/**\n * Optimized pattern matching with caching. Avoids repeated minimatch calls for same path-pattern pairs.\n */\nfunction matchesPattern(path: string, pattern: string): boolean {\n const cacheKey = `${path}|${pattern}`;\n\n const cached = BLACKLIST_PATTERN_CACHE.get(cacheKey);\n if (cached !== undefined) {\n return cached;\n }\n\n const result = minimatch(path, pattern, { matchBase: true });\n BLACKLIST_PATTERN_CACHE.set(cacheKey, result);\n\n return result;\n}\n\n/**\n * Checks if a path matches any of the given blacklist patterns. Enables pattern-based filtering with optimized caching.\n */\nfunction matchesBlacklistPattern(\n path: string,\n patterns: BlacklistPatternList,\n): { pattern: string; hint?: string } | null {\n // Clear cache periodically to prevent memory bloat\n clearCacheIfNeeded();\n\n for (const entry of patterns) {\n const { pattern, hint } = normalizeBlacklistEntry(entry);\n if (matchesPattern(path, pattern)) {\n return { pattern, hint };\n }\n }\n return null;\n}\n\n/**\n * Creates error issue for oversized artifact exceeding maximum threshold. Indicates unoptimized bundle or accidental check-in requiring optimization.\n *\n * @param outputPath - Path to the output file that exceeds size limit\n * @param bytes - Actual size of the artifact in bytes\n * @param maxSize - Maximum allowed size threshold in bytes\n * @returns Issue object with error severity and optimization recommendation\n *\n * @example\n * ```js\n * createTooLargeIssue('dist/bundle.js', 1048576, 500000)\n * // Returns: { message: \"🔺 `dist/bundle.js` is **1 MB** _(> 488 kB)_\", severity: 'error', ... }\n * ```\n */\nexport function createTooLargeIssue(\n outputPath: string,\n bytes: number,\n maxSize: number,\n): Issue {\n return {\n message: `${ISSUE_ICONS.TOO_LARGE} \\`${outputPath}\\` is **${formatBytes(bytes)}** _(> ${formatBytes(maxSize)})_`,\n severity: 'error',\n source: { file: outputPath },\n };\n}\n\n/**\n * Creates warning issue for undersized artifact below minimum threshold. Signals missing dependencies or incomplete build requiring verification.\n *\n * @param outputPath - Path to the output file that is below size limit\n * @param bytes - Actual size of the artifact in bytes\n * @param minSize - Minimum expected size threshold in bytes\n * @returns Issue object with warning severity and verification recommendation\n *\n * @example\n * ```js\n * createTooSmallIssue('dist/chunk.js', 512, 2048)\n * // Returns: { message: \"🔻 `dist/chunk.js` is **512 B** _(< 2 kB)_\", severity: 'warning', ... }\n * ```\n */\nexport function createTooSmallIssue(\n outputPath: string,\n bytes: number,\n minSize: number,\n): Issue {\n return {\n message: `${ISSUE_ICONS.TOO_SMALL} \\`${outputPath}\\` is **${formatBytes(bytes)}** _(< ${formatBytes(minSize)})_`,\n severity: 'warning',\n source: { file: outputPath },\n };\n}\n\n/**\n * Creates error issue for blacklisted import pattern match. Enforces dependency restrictions for security and architectural compliance.\n */\nexport function createBlacklistedIssue(\n importPath: string,\n outputPath: string,\n pattern: string,\n hint?: string,\n): Issue {\n const baseMessage = `${ISSUE_ICONS.BLACKLIST} \\`${importPath}\\` matches blacklist pattern \\`${pattern}\\``;\n const message = hint ? `${baseMessage} - ${hint}` : baseMessage;\n\n return {\n message,\n severity: 'error',\n source: { file: outputPath },\n };\n}\n\n/**\n * Validates artifact size against configured thresholds and returns appropriate issues. Ensures bundles stay within acceptable size ranges.\n *\n * @param outputPath - Path to the output file being checked\n * @param output - Output metadata containing size information\n * @param minSize - Minimum expected size threshold in bytes (optional)\n * @param maxSize - Maximum allowed size threshold in bytes (optional)\n * @returns Array of size-related issues found\n */\nexport function checkSizeIssues(\n outputPath: string,\n output: UnifiedStatsBundle,\n minSize?: number,\n maxSize?: number,\n): Issue[] {\n const outputBytes = output.bytes;\n\n if (maxSize !== undefined && outputBytes > maxSize) {\n return [createTooLargeIssue(outputPath, outputBytes, maxSize)];\n } else if (minSize !== undefined && outputBytes < minSize) {\n return [createTooSmallIssue(outputPath, outputBytes, minSize)];\n }\n\n return [];\n}\n\n/**\n * Scans artifact inputs and imports for blacklisted patterns and returns violation issues.\n * Enforces dependency restrictions across bundle contents.\n *\n * Searches for blacklisted paths in these locations:\n * 1. Primary File Path Locations:\n * - Object keys in the inputs section\n * - \"path\" properties in imports\n * - \"original\" properties in imports (exact import statements as written in source code)\n * 2. Entry Point Locations:\n * - \"entryPoint\" properties in chunk/output definitions\n * 3. Output File Locations:\n * - Output file paths (as object keys)\n * 4. Special Path Patterns:\n * - Disabled paths with \"(disabled):\" prefix\n * - Runtime paths with \"\" pattern\n *\n * @param outputPath - Path to the output file being scanned\n * @param output - Output metadata containing inputs and imports\n * @param blacklistPatterns - Array of blacklist patterns (strings or objects with hints)\n * @returns Array of blacklist-related issues found\n */\nexport function checkBlacklistIssues(\n outputPath: string,\n output: UnifiedStatsBundle,\n blacklistPatterns: BlacklistPatternList,\n): Issue[] {\n const issues: Issue[] = [];\n\n // 1. Check output path itself (object key in outputs section)\n const outputPathMatch = matchesBlacklistPattern(\n outputPath,\n blacklistPatterns,\n );\n if (outputPathMatch) {\n issues.push(\n createBlacklistedIssue(\n outputPath,\n outputPath,\n outputPathMatch.pattern,\n outputPathMatch.hint,\n ),\n );\n }\n\n // 2. Check entryPoint property\n if (output.entryPoint) {\n const entryPointMatch = matchesBlacklistPattern(\n output.entryPoint,\n blacklistPatterns,\n );\n if (entryPointMatch) {\n issues.push(\n createBlacklistedIssue(\n output.entryPoint,\n outputPath,\n entryPointMatch.pattern,\n entryPointMatch.hint,\n ),\n );\n }\n }\n\n // 3. Check input paths (object keys in inputs section)\n if (output.inputs) {\n for (const inputPath in output.inputs) {\n const matchedPattern = matchesBlacklistPattern(\n inputPath,\n blacklistPatterns,\n );\n if (matchedPattern) {\n issues.push(\n createBlacklistedIssue(\n inputPath,\n outputPath,\n matchedPattern.pattern,\n matchedPattern.hint,\n ),\n );\n }\n }\n }\n\n // 4. Check import paths and original import statements\n if (output.imports) {\n for (let i = 0; i < output.imports.length; i++) {\n const importInfo = output.imports[i]!;\n\n // Check resolved import path\n const importPathMatch = matchesBlacklistPattern(\n importInfo.path,\n blacklistPatterns,\n );\n if (importPathMatch) {\n issues.push(\n createBlacklistedIssue(\n importInfo.path,\n outputPath,\n importPathMatch.pattern,\n importPathMatch.hint,\n ),\n );\n }\n\n // Check original import statement (exact import as written in source code)\n if (importInfo.original) {\n const originalMatch = matchesBlacklistPattern(\n importInfo.original,\n blacklistPatterns,\n );\n if (originalMatch) {\n issues.push(\n createBlacklistedIssue(\n importInfo.original,\n outputPath,\n originalMatch.pattern,\n originalMatch.hint,\n ),\n );\n }\n }\n }\n }\n\n return issues;\n}\n\n/**\n * Generates comprehensive diagnostic issues for bundle artifacts including size violations and blacklisted imports. Provides actionable feedback for bundle optimization and dependency management.\n *\n * @param statsSlice - Unified bundle statistics containing output files and metadata\n * @param config - Bundle configuration with penalty options and diagnostic thresholds\n * @returns Array of diagnostic issues with severity levels and recommended actions\n */\nexport function getIssues(\n statsSlice: UnifiedStats,\n config: BundleStatsConfig,\n): Issue[] {\n // Clear cache at start of each audit run for clean state\n BLACKLIST_PATTERN_CACHE.clear();\n\n const issues: Issue[] = [];\n const { penalty = false } = config.scoring || { penalty: false };\n\n if (!penalty) {\n return issues;\n }\n\n const blacklistPatterns = penalty?.blacklist;\n const artefactSizeThresholds = penalty?.artefactSize;\n\n if (!blacklistPatterns?.length && !artefactSizeThresholds) {\n return issues;\n }\n\n const minArtifactSize = artefactSizeThresholds?.[0];\n const maxArtifactSize = artefactSizeThresholds?.[1];\n const hasBlacklist = blacklistPatterns && blacklistPatterns.length > 0;\n const hasSizeThresholds =\n minArtifactSize !== undefined || maxArtifactSize !== undefined;\n\n // Track unique blacklisted patterns per bundle to avoid duplicates\n const blacklistedPatterns = new Map<\n string,\n { pattern: string; hint?: string; files: string[]; outputPath: string }\n >();\n\n for (const outputPath in statsSlice) {\n const output = statsSlice[outputPath]!;\n\n if (hasSizeThresholds) {\n issues.push(\n ...checkSizeIssues(\n outputPath,\n output,\n minArtifactSize,\n maxArtifactSize,\n ),\n );\n }\n\n if (hasBlacklist) {\n // Collect blacklisted patterns without creating issues yet\n collectBlacklistedPatterns(\n outputPath,\n output,\n blacklistPatterns,\n blacklistedPatterns,\n );\n }\n }\n\n // Create unique issues for blacklisted patterns\n for (const [\n patternKey,\n { pattern, hint, files, outputPath },\n ] of blacklistedPatterns) {\n if (files.length === 1) {\n // Single file - show specific file name\n issues.push(createBlacklistedIssue(files[0]!, outputPath, pattern, hint));\n } else {\n // Multiple files - show pattern summary\n const summaryMessage = `Blacklisted modules matching \\`${pattern}\\` included in file`;\n issues.push(\n createBlacklistedPatternIssue(\n summaryMessage,\n outputPath,\n pattern,\n hint,\n files,\n ),\n );\n }\n }\n\n return issues;\n}\n\n/**\n * Creates error issue for multiple blacklisted files from same pattern. Consolidates multiple violations into single issue.\n */\nexport function createBlacklistedPatternIssue(\n summaryMessage: string,\n outputPath: string,\n pattern: string,\n hint?: string,\n files?: string[],\n): Issue {\n const baseMessage = `${ISSUE_ICONS.BLACKLIST} ${summaryMessage}`;\n const message = hint ? `${baseMessage} - ${hint}` : baseMessage;\n\n return {\n message,\n severity: 'error',\n source: { file: outputPath },\n };\n}\n\n/**\n * Collects blacklisted patterns without creating duplicate issues. Groups by pattern per bundle.\n */\nfunction collectBlacklistedPatterns(\n outputPath: string,\n output: UnifiedStatsBundle,\n blacklistPatterns: BlacklistPatternList,\n blacklistedPatterns: Map<\n string,\n { pattern: string; hint?: string; files: string[]; outputPath: string }\n >,\n): void {\n const addToPattern = (\n filePath: string,\n matchResult: { pattern: string; hint?: string },\n ) => {\n const patternKey = `${outputPath}:${matchResult.pattern}`;\n if (blacklistedPatterns.has(patternKey)) {\n const existing = blacklistedPatterns.get(patternKey)!;\n if (!existing.files.includes(filePath)) {\n existing.files.push(filePath);\n }\n } else {\n blacklistedPatterns.set(patternKey, {\n pattern: matchResult.pattern,\n hint: matchResult.hint,\n files: [filePath],\n outputPath,\n });\n }\n };\n\n // 1. Check output path itself (object key in outputs section)\n const outputPathMatch = matchesBlacklistPattern(\n outputPath,\n blacklistPatterns,\n );\n if (outputPathMatch) {\n addToPattern(outputPath, outputPathMatch);\n }\n\n // 2. Check entryPoint property\n if (output.entryPoint) {\n const entryPointMatch = matchesBlacklistPattern(\n output.entryPoint,\n blacklistPatterns,\n );\n if (entryPointMatch) {\n addToPattern(output.entryPoint, entryPointMatch);\n }\n }\n\n // 3. Check input paths (object keys in inputs section)\n if (output.inputs) {\n for (const inputPath in output.inputs) {\n const matchedPattern = matchesBlacklistPattern(\n inputPath,\n blacklistPatterns,\n );\n if (matchedPattern) {\n addToPattern(inputPath, matchedPattern);\n }\n }\n }\n\n // 4. Check import paths and original import statements\n if (output.imports) {\n for (let i = 0; i < output.imports.length; i++) {\n const importInfo = output.imports[i]!;\n\n // Check resolved import path\n const importPathMatch = matchesBlacklistPattern(\n importInfo.path,\n blacklistPatterns,\n );\n if (importPathMatch) {\n addToPattern(importInfo.path, importPathMatch);\n }\n\n // Check original import statement (exact import as written in source code)\n if (importInfo.original) {\n const originalMatch = matchesBlacklistPattern(\n importInfo.original,\n blacklistPatterns,\n );\n if (originalMatch) {\n addToPattern(importInfo.original, originalMatch);\n }\n }\n }\n }\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/issues.unit.test.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'afterEach' is defined but never used.", - "line": 1, - "column": 10, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 1, - "endColumn": 19 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'beforeEach' is defined but never used.", - "line": 1, - "column": 21, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 1, - "endColumn": 31 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'vi' is defined but never used.", - "line": 1, - "column": 55, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 1, - "endColumn": 57 - } - ], - "suppressedMessages": [], - "errorCount": 3, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';\nimport {\n checkBlacklistIssues,\n checkSizeIssues,\n createBlacklistedIssue,\n createTooLargeIssue,\n createTooSmallIssue,\n getIssues,\n} from './issues.js';\n\ndescribe('createTooLargeIssue', () => {\n it('should create error issue for oversized artifact', () => {\n expect(createTooLargeIssue('bundle.js', 1_048_576, 500_000)).toStrictEqual({\n severity: 'error',\n message: '🔺 `bundle.js` is **1 MB** _(> 488.28 kB)_',\n source: { file: 'bundle.js' },\n });\n });\n});\n\ndescribe('createTooSmallIssue', () => {\n it('should create warning issue for undersized artifact', () => {\n expect(createTooSmallIssue('chunk.js', 512, 2048)).toStrictEqual({\n severity: 'warning',\n message: '🔻 `chunk.js` is **512 B** _(< 2 kB)_',\n source: { file: 'chunk.js' },\n });\n });\n});\n\ndescribe('createBlacklistedIssue', () => {\n it('should create error issue for blacklisted import', () => {\n expect(\n createBlacklistedIssue('src/math.ts', 'dist/bundle.js', '**/*math*'),\n ).toStrictEqual({\n severity: 'error',\n message: '🚫 `src/math.ts` matches blacklist pattern `**/*math*`',\n source: { file: 'dist/bundle.js' },\n });\n });\n});\n\ndescribe('checkSizeIssues', () => {\n it('should return too large issue when file exceeds maxSize', () => {\n expect(\n checkSizeIssues(\n 'big.js',\n { path: 'big.js', bytes: 1000 },\n undefined,\n 500,\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should return too small issue when file is below minSize', () => {\n expect(\n checkSizeIssues(\n 'small.js',\n { path: 'small.js', bytes: 100 },\n 500,\n undefined,\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'warning' })]);\n });\n\n it('should return empty array when file is within size range', () => {\n expect(\n checkSizeIssues('ok.js', { path: 'ok.js', bytes: 750 }, 500, 1000),\n ).toStrictEqual([]);\n });\n});\n\ndescribe('checkBlacklistIssues', () => {\n it('should check output path itself for blacklist patterns', () => {\n expect(\n checkBlacklistIssues('a.js', { path: 'a.js', bytes: 1 }, ['a*']),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check output path itself for blacklist patterns with hint', () => {\n const issues = checkBlacklistIssues('a.js', { path: 'a.js', bytes: 1 }, [\n { pattern: 'a*', hint: 'Test hint message' },\n ]);\n expect(issues).toStrictEqual([\n expect.objectContaining({\n severity: 'error',\n message: expect.stringContaining('Test hint message'),\n }),\n ]);\n });\n\n it('should check entryPoint property for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n { path: 'out.js', bytes: 1, entryPoint: 'b.js' },\n ['b*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check input paths for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n { path: 'out.js', bytes: 1, inputs: { 'c.js': { bytes: 1 } } },\n ['c*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check import resolved paths for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n imports: [{ path: 'd.js', kind: 'static' }],\n },\n ['d*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should check import original statements for blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n imports: [{ path: 'x.js', kind: 'static', original: './e' }],\n },\n ['./e*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should return multiple issues when multiple paths match blacklist patterns', () => {\n expect(\n checkBlacklistIssues(\n 'f.js',\n {\n path: 'f.js',\n bytes: 1,\n inputs: { 'g.js': { bytes: 1 } },\n imports: [{ path: 'h.js', kind: 'static' }],\n },\n ['*'],\n ),\n ).toStrictEqual([\n expect.objectContaining({ severity: 'error' }),\n expect.objectContaining({ severity: 'error' }),\n expect.objectContaining({ severity: 'error' }),\n ]);\n });\n\n it('should match disabled paths with (disabled): prefix', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n inputs: { '(disabled):i.js': { bytes: 1 } },\n },\n ['*disabled*'],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n\n it('should match runtime paths with pattern', () => {\n expect(\n checkBlacklistIssues(\n 'out.js',\n {\n path: 'out.js',\n bytes: 1,\n imports: [{ path: '', kind: 'static' }],\n },\n [''],\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n});\n\ndescribe('getIssues', () => {\n it('should return empty array when no configuration is provided', () => {\n expect(getIssues({}, {} as any)).toStrictEqual([]);\n });\n\n it('should process multiple outputs and return issues', () => {\n expect(\n getIssues(\n {\n 'a.js': { path: 'a.js', bytes: 1 },\n 'b.js': { path: 'b.js', bytes: 2 },\n },\n {\n title: 'Test',\n slug: 'test',\n selection: { includeOutputs: ['**/*.js'] },\n scoring: {\n totalSize: [0, 1000],\n penalty: { blacklist: ['a*'] },\n },\n } as any,\n ),\n ).toStrictEqual([expect.objectContaining({ severity: 'error' })]);\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.ts", - "messages": [ - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'aggregateAndSortGroups' has too many lines (117). Maximum allowed is 50.", - "line": 40, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 190, - "endColumn": 2 - }, - { - "ruleId": "complexity", - "severity": 1, - "message": "Function 'aggregateAndSortGroups' has a complexity of 26. Maximum allowed is 20.", - "line": 40, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "complex", - "endLine": 190, - "endColumn": 2 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 63, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 72, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 74, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 74, - "endColumn": 26 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 84, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 98, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 88, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 96, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 90, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 94, - "endColumn": 13 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 104, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 142, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 111, - "column": 5, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 111, - "endColumn": 58 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 120, - "column": 7, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 120, - "endColumn": 50 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 131, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 131, - "endColumn": 32 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 132, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 132, - "endColumn": 25 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 145, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 175, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 154, - "column": 5, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 154, - "endColumn": 58 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 162, - "column": 7, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 162, - "endColumn": 50 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 172, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 172, - "endColumn": 36 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 186, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 186, - "endColumn": 45 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'createTable' has too many lines (64). Maximum allowed is 50.", - "line": 195, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 275, - "endColumn": 2 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 203, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 203, - "endColumn": 32 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 204, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 204, - "endColumn": 38 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 214, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 220, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 216, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 216, - "endColumn": 31 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 218, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 218, - "endColumn": 33 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 223, - "column": 5, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 223, - "endColumn": 34 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 227, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 227, - "endColumn": 41 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 245, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 256, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 251, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 255, - "endColumn": 7 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 260, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 264, - "endColumn": 7 - } - ], - "suppressedMessages": [], - "errorCount": 10, - "fatalErrorCount": 0, - "warningCount": 18, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { Table } from '@code-pushup/models';\nimport { formatBytes } from '@code-pushup/utils';\nimport type { GroupingRule } from '../../types.js';\nimport type { UnifiedStats } from '../../unify/unified-stats.types.js';\nimport {\n type GroupData,\n createGroupManager,\n findOrCreateGroupFromRule,\n processForTable,\n} from './grouping.js';\n\nconst DEFAULT_GROUP_NAME = 'Group';\nconst REST_GROUP_NAME = 'Rest';\n\n// Performance optimizations: Simple pattern cache only\nconst PATTERN_MATCH_CACHE = new Map<\n string,\n { rule: GroupingRule | null; groupKey: string | null }\n>();\n\nexport type SharedViewConfig = {\n enabled?: boolean;\n mode?: 'onlyMatching' | 'all';\n};\n\nexport type TablePruningConfig = {\n enabled?: boolean;\n maxChildren?: number;\n minSize?: number;\n};\n\nexport type InsightsTableConfig = SharedViewConfig & {\n groups: GroupingRule[];\n pruning?: TablePruningConfig;\n};\n\n/**\n * Simplified aggregation with algorithmic optimizations. Eliminates expensive nested operations and redundant pattern matching.\n */\nexport function aggregateAndSortGroups(\n statsSlice: UnifiedStats,\n insights: InsightsTableConfig,\n): { groups: GroupData[]; restGroup: { title: string; bytes: number } } {\n const groupingRules = insights.groups || [];\n\n // Early exit optimization\n if (groupingRules.length === 0) {\n const totalBytes = Object.values(statsSlice).reduce(\n (acc, { bytes }) => acc + bytes,\n 0,\n );\n return {\n groups: [],\n restGroup: { bytes: totalBytes, title: REST_GROUP_NAME },\n };\n }\n\n const groupManager = createGroupManager();\n PATTERN_MATCH_CACHE.clear();\n\n // Pre-create all possible groups to avoid repeated lookups\n const preCreatedGroups = new Map();\n for (const rule of groupingRules) {\n const effectiveTitle = rule.title || DEFAULT_GROUP_NAME;\n const group = findOrCreateGroupFromRule(\n groupManager,\n effectiveTitle,\n rule,\n effectiveTitle,\n );\n preCreatedGroups.set(effectiveTitle, group);\n }\n\n let totalRestBytes = 0;\n const outputEntries = Object.entries(statsSlice);\n\n // Single-pass processing: collect all inputs first, then process in batch\n const inputsToProcess: {\n inputPath: string;\n inputBytes: number;\n outputKey: string;\n }[] = [];\n\n for (const [outputKey, output] of outputEntries) {\n totalRestBytes += output.bytes;\n\n if (output.inputs) {\n for (const [inputPath, input] of Object.entries(output.inputs)) {\n if (input.bytes > 0) {\n inputsToProcess.push({\n inputPath,\n inputBytes: input.bytes,\n outputKey,\n });\n }\n }\n }\n }\n\n // Process all inputs in single optimized loop with early termination\n const outputBytesConsumed = new Map();\n const processedInputs = new Set(); // Track inputs that have been fully consumed\n\n for (const { inputPath, inputBytes, outputKey } of inputsToProcess) {\n // Skip inputs that have already been fully processed by a previous rule\n if (processedInputs.has(inputPath)) {\n continue;\n }\n\n // Use cached pattern matching\n let matchResult = PATTERN_MATCH_CACHE.get(inputPath);\n if (!matchResult) {\n matchResult = processForTable(inputPath, groupingRules, true);\n PATTERN_MATCH_CACHE.set(inputPath, matchResult);\n }\n\n const { rule, groupKey } = matchResult;\n if (rule && groupKey) {\n // Use pre-created group or create new\n let group = preCreatedGroups.get(groupKey);\n if (!group) {\n group = findOrCreateGroupFromRule(\n groupManager,\n groupKey,\n rule,\n rule.title || groupKey,\n );\n preCreatedGroups.set(groupKey, group);\n }\n\n group.bytes += inputBytes;\n group.modules += 1;\n\n // Track consumed bytes per output\n const consumed = outputBytesConsumed.get(outputKey) || 0;\n outputBytesConsumed.set(outputKey, consumed + inputBytes);\n totalRestBytes -= inputBytes;\n\n // Mark input as fully processed - no need to check it against other patterns\n processedInputs.add(inputPath);\n }\n }\n\n // Process remaining output bytes efficiently, skipping outputs with no remaining bytes\n for (const [outputKey, output] of outputEntries) {\n const consumedBytes = outputBytesConsumed.get(outputKey) || 0;\n const remainingBytes = output.bytes - consumedBytes;\n\n // Skip outputs that have been fully consumed by input processing\n if (remainingBytes <= 0) {\n continue;\n }\n\n let matchResult = PATTERN_MATCH_CACHE.get(outputKey);\n if (!matchResult) {\n matchResult = processForTable(outputKey, groupingRules, true);\n PATTERN_MATCH_CACHE.set(outputKey, matchResult);\n }\n\n const { rule, groupKey } = matchResult;\n if (rule && groupKey) {\n let group = preCreatedGroups.get(groupKey);\n if (!group) {\n group = findOrCreateGroupFromRule(\n groupManager,\n groupKey,\n rule,\n rule.title || groupKey,\n );\n preCreatedGroups.set(groupKey, group);\n }\n group.bytes += remainingBytes;\n totalRestBytes -= remainingBytes;\n }\n }\n\n const restGroup = {\n bytes: Math.max(0, totalRestBytes),\n title: REST_GROUP_NAME,\n };\n\n const groups = groupManager.getGroupsWithData();\n\n // Optimized sorting - only sort if we have multiple groups\n if (groups.length > 1) {\n groups.sort((a, b) => b.bytes - a.bytes);\n }\n\n return { groups, restGroup };\n}\n\n/**\n * Transforms aggregated group data into table format. Creates table rows from group statistics.\n */\nexport function createTable(\n groups: GroupData[],\n restGroup: { title: string; bytes: number },\n viewMode: 'onlyMatching' | 'all' = 'onlyMatching',\n pruning?: TablePruningConfig,\n): Table {\n const rows: { group: string; modules: string; size: string }[] = [];\n\n let processedGroups = groups;\n let processedRestGroup = restGroup;\n\n // Apply pruning if enabled\n if (pruning?.enabled) {\n const { minSize = 0, maxChildren } = pruning;\n\n // Filter groups by minimum size\n const keptGroups: GroupData[] = [];\n const prunedGroups: GroupData[] = [];\n\n for (const group of groups) {\n if (group.bytes >= minSize) {\n keptGroups.push(group);\n } else {\n prunedGroups.push(group);\n }\n }\n\n // Apply maxChildren limit\n let finalGroups = keptGroups;\n if (maxChildren && keptGroups.length > maxChildren) {\n finalGroups = keptGroups.slice(0, maxChildren);\n const excessGroups = keptGroups.slice(maxChildren);\n prunedGroups.push(...excessGroups);\n }\n\n // Add pruned groups to rest\n if (prunedGroups.length > 0) {\n const prunedBytes = prunedGroups.reduce(\n (sum, group) => sum + group.bytes,\n 0,\n );\n processedRestGroup = {\n title: REST_GROUP_NAME,\n bytes: restGroup.bytes + prunedBytes,\n };\n }\n\n processedGroups = finalGroups;\n }\n\n for (const group of processedGroups) {\n // Apply viewMode filtering\n if (viewMode === 'onlyMatching' && group.bytes === 0) {\n continue;\n }\n\n rows.push({\n group: group.icon ? `${group.icon} ${group.title}` : group.title,\n modules: group.modules.toString(),\n size: formatBytes(group.bytes),\n });\n }\n\n // Apply viewMode filtering to rest group\n if (processedRestGroup.bytes > 0 || viewMode === 'all') {\n rows.push({\n group: 'Rest',\n modules: '-',\n size: formatBytes(processedRestGroup.bytes),\n });\n }\n\n return {\n columns: [\n { key: 'group', label: 'Group', align: 'left' },\n { key: 'modules', label: 'Modules', align: 'right' },\n { key: 'size', label: 'Size', align: 'right' },\n ],\n rows,\n };\n}\n\n/**\n * Creates insights table from stats and grouping rules. Combines aggregation and table formatting.\n */\nexport function createInsightsTable(\n statsSlice: UnifiedStats,\n insights: InsightsTableConfig,\n): Table {\n const { groups, restGroup } = aggregateAndSortGroups(statsSlice, insights);\n return createTable(\n groups,\n restGroup,\n insights.mode || 'onlyMatching',\n insights.pruning,\n );\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/table.unit.test.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.ts", - "messages": [ - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 69, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 107, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 71, - "column": 5, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 71, - "endColumn": 42 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 76, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 89, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 78, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 87, - "endColumn": 13 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 92, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 92, - "endColumn": 68 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 97, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 106, - "endColumn": 7 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 110, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 110, - "endColumn": 59 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 123, - "column": 21, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 123, - "endColumn": 38 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 172, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 172, - "endColumn": 52 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 179, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 179, - "endColumn": 67 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'createTree' has too many lines (55). Maximum allowed is 50.", - "line": 207, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 283, - "endColumn": 2 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'selection' is assigned a value but never used.", - "line": 214, - "column": 41, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 214, - "endColumn": 50 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 25_000.", - "line": 217, - "column": 34, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 217, - "endColumn": 40 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 221, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 221, - "endColumn": 46 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 227, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 231, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 229, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 229, - "endColumn": 68 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 243, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 243, - "endColumn": 36 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 253, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 253, - "endColumn": 22 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 254, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 254, - "endColumn": 24 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 255, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 258, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 999.", - "line": 291, - "column": 35, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 291, - "endColumn": 38 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 999.", - "line": 292, - "column": 41, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 292, - "endColumn": 44 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 999.", - "line": 294, - "column": 39, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 294, - "endColumn": 42 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'pruneTreeRecursive' has too many lines (66). Maximum allowed is 50.", - "line": 302, - "column": 1, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 387, - "endColumn": 2 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 315, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 315, - "endColumn": 66 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 322, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 342, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 334, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 337, - "endColumn": 9 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 340, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 340, - "endColumn": 34 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 345, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 345, - "endColumn": 36 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 351, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 351, - "endColumn": 38 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 359, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 359, - "endColumn": 46 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 359, - "column": 26, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 359, - "endColumn": 45 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 382, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 382, - "endColumn": 35 - } - ], - "suppressedMessages": [], - "errorCount": 16, - "fatalErrorCount": 0, - "warningCount": 17, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { BasicTree, BasicTreeNode } from '@code-pushup/models';\nimport { formatBytes, pluralizeToken, truncateText } from '@code-pushup/utils';\nimport type { GroupingRule } from '../../types.js';\nimport type { UnifiedStats } from '../../unify/unified-stats.types';\nimport type { SelectionConfig } from '../selection.js';\nimport {\n type StatsTreeNode,\n applyGrouping as applyGroupingAndSort,\n} from './grouping.js';\nimport type { SharedViewConfig } from './table.js';\nimport type { StatsNodeValues } from './types.js';\n\n/**\n * Helper type that transforms picked properties by adding \"Display\" suffix and making them strings.\n */\nexport type AddDisplaySuffix = {\n [K in keyof T as `${string & K}Display`]: string;\n};\n\n/**\n * Display values for StatsTreeNode with formatted strings.\n */\nexport type StatsTreeNodeDisplayValues = AddDisplaySuffix<\n Pick\n>;\n\nexport type FormattedStatsTreeNode = {\n name: string;\n values?: Record;\n children: FormattedStatsTreeNode[];\n};\n\n/**\n * Display tree structure for bundle statistics output.\n */\nexport type FormattedStatsTree = {\n root: FormattedStatsTreeNode;\n};\n\nexport const DEFAULT_PATH_LENGTH = 40;\n\n// Simple performance optimization: single cache for formatted strings\nconst STRING_FORMAT_CACHE = new Map();\n\nexport type DependencyTreeConfig = {\n groups?: GroupingRule[] | false;\n pruning?: PruningConfig;\n} & SharedViewConfig;\n\nexport type PruningConfig = {\n enabled?: boolean;\n maxChildren?: number;\n maxDepth?: number;\n minSize?: number;\n pathLength?: number | false;\n};\n\nexport type PruneTreeNode = {\n children: StatsTreeNode[];\n};\n\n/**\n * Converts statistics to tree structure. Streamlined for speed.\n */\nexport function convertStatsToTree(stats: UnifiedStats): StatsTreeNode[] {\n const artifacts = Object.values(stats);\n const result: StatsTreeNode[] = [];\n\n for (const artefact of artifacts) {\n const isEntry = Boolean(artefact.entryPoint);\n let inputNodes: StatsTreeNode[] = [];\n\n if (artefact.inputs) {\n const validInputs: StatsTreeNode[] = [];\n\n for (const [path, input] of Object.entries(artefact.inputs)) {\n if (input.bytes > 0) {\n validInputs.push({\n name: path,\n values: {\n path,\n bytes: input.bytes,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n });\n }\n }\n\n if (validInputs.length > 1) {\n validInputs.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n inputNodes = validInputs;\n }\n\n result.push({\n name: artefact.path,\n values: {\n path: artefact.path,\n bytes: artefact.bytes,\n modules: inputNodes.length,\n type: isEntry ? 'entry-file' : 'static-import',\n },\n children: inputNodes,\n });\n }\n\n if (result.length > 1) {\n result.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n return result;\n}\n\n/**\n * Flattens single-child groups to reduce hierarchy and applies group icons to actual files.\n */\nfunction flattenSingleChildGroups(nodes: StatsTreeNode[]): StatsTreeNode[] {\n return nodes.map(node => {\n // If this is a group with exactly one child, flatten it\n if (node.values.type === 'group' && node.children.length === 1) {\n const child = node.children[0]!;\n\n // Use the group's icon for the child file if the group has an icon\n return {\n ...child,\n values: {\n ...child.values,\n icon: node.values.icon, // Use group icon only if it exists\n },\n children: flattenSingleChildGroups(child.children), // Recursively flatten children\n };\n }\n\n // For other nodes, just recursively process children\n return {\n ...node,\n children: flattenSingleChildGroups(node.children),\n };\n });\n}\n\n/**\n * Formats tree nodes with clean names and separate values for proper alignment.\n */\nexport function formatStatsTreeForDisplay(\n node: StatsTreeNode,\n pathLength: number | false = DEFAULT_PATH_LENGTH,\n): FormattedStatsTreeNode {\n const maxChars = pathLength === false ? DEFAULT_PATH_LENGTH : pathLength;\n\n // Clean name truncation (no icons or size info)\n const cleanName =\n maxChars < node.name.length\n ? truncateText(node.name, { maxChars, position: 'middle' })\n : node.name;\n\n // Use only explicitly configured icons\n const icon = node.values.icon;\n\n // Recurse through children (keep it simple - recursion is fast in JS)\n const children = node.children.map(child =>\n formatStatsTreeForDisplay(child, pathLength),\n );\n\n const values: Record = {};\n\n // Show size for all nodes except intermediate nodes in single-child chains\n // This means: entry files, groups with multiple children, and leaf files all show size\n if (node.children.length !== 1) {\n values['size'] = formatBytes(node.values.bytes);\n }\n\n // Only show source count if more than 1 source\n if (node.values.modules > 1) {\n // For \"...\" groups that represent multiple files, show \"files\" instead of \"sources\"\n const token = node.name === '...' ? 'file' : 'module';\n values['modules'] = pluralizeToken(token, node.values.modules);\n }\n\n return {\n name: icon ? `${icon} ${cleanName}` : cleanName,\n values,\n children,\n };\n}\n\n/**\n * Converts FormattedStatsTreeNode to BasicTreeNode for proper ASCII display.\n */\nfunction formattedStatsTreeNodeToBasicTreeNode(\n node: FormattedStatsTreeNode,\n): BasicTreeNode {\n return {\n name: node.name,\n ...(node.values && { values: node.values }),\n ...(node.children.length > 0 && {\n children: node.children.map(formattedStatsTreeNodeToBasicTreeNode),\n }),\n };\n}\n\n/**\n * Creates artifact tree with focused optimizations.\n */\nexport function createTree(\n statsSlice: UnifiedStats,\n options: {\n title: string;\n selection?: SelectionConfig;\n } & DependencyTreeConfig,\n): BasicTree {\n const { title, groups, pruning, mode, selection } = options;\n\n // Simple cache management\n if (STRING_FORMAT_CACHE.size > 25_000) {\n STRING_FORMAT_CACHE.clear();\n }\n\n let nodes = convertStatsToTree(statsSlice);\n\n // Apply grouping if needed\n if (Array.isArray(groups) && groups.length > 0 && nodes.length > 0) {\n // Apply grouping only to inputs (children) within each output file\n // Don't group the output files themselves\n for (const node of nodes) {\n if (node.children.length > 0) {\n node.children = applyGroupingAndSort(node.children, groups);\n }\n }\n\n // Flatten single-child groups after applying grouping\n nodes = flattenSingleChildGroups(nodes);\n }\n\n // Apply onlyMatching mode filtering - hide files with no matching inputs\n if (mode === 'onlyMatching') {\n nodes = nodes.filter(node => node.children.length > 0);\n }\n\n // Apply pruning only if explicitly configured and enabled\n let prunedNodes: StatsTreeNode[];\n if (pruning && pruning.enabled !== false) {\n const prunedRoot = pruneTree({ children: nodes }, pruning);\n prunedNodes = prunedRoot.children;\n } else {\n // No pruning - show all nodes\n prunedNodes = nodes;\n }\n\n // Calculate totals\n let totalBytes = 0;\n let totalModules = 0;\n for (const node of prunedNodes) {\n totalBytes += node.values.bytes;\n totalModules += node.values.modules;\n }\n\n // Format nodes\n const formattedChildren = prunedNodes.map(node =>\n formatStatsTreeForDisplay(node, pruning?.pathLength),\n );\n\n const formattedRoot: FormattedStatsTreeNode = {\n name: title,\n values: {\n 'total size': formatBytes(totalBytes),\n ...(totalModules > 1 && { 'total modules': totalModules }),\n files: prunedNodes.length,\n },\n children: formattedChildren,\n };\n\n // Convert to BasicTree for proper ASCII display\n const root = formattedStatsTreeNodeToBasicTreeNode(formattedRoot);\n\n return {\n type: 'basic',\n title,\n root,\n };\n}\n\nexport function pruneTree(\n rootNode: PruneTreeNode,\n options: PruningConfig,\n): PruneTreeNode {\n // Provide defaults for all required properties\n const completeOptions: Required = {\n maxDepth: options.maxDepth ?? 999,\n maxChildren: options.maxChildren ?? 999,\n minSize: options.minSize ?? 0,\n pathLength: options.pathLength ?? 999,\n enabled: options.enabled ?? true,\n };\n\n // Start from 1 so that maxDepth: 2 stops at package level, maxDepth: 3 shows individual files\n return pruneTreeRecursive(rootNode, completeOptions, 1);\n}\n\nfunction pruneTreeRecursive(\n node: PruneTreeNode,\n options: Required,\n currentDepth: number,\n): PruneTreeNode {\n const { maxChildren, maxDepth, minSize } = options;\n\n if (node.children.length === 0) {\n return node;\n }\n\n // Sort children by size (largest first)\n if (node.children.length > 1) {\n node.children.sort((a, b) => b.values.bytes - a.values.bytes);\n }\n\n // Apply maxChildren and minSize filtering at all levels within maxDepth\n const keptChildren: StatsTreeNode[] = [];\n const groupedChildren: StatsTreeNode[] = [];\n\n for (const child of node.children) {\n if (child.values.bytes >= minSize) {\n // Recursively prune child's subtree if within maxDepth\n const prunedChild =\n currentDepth < maxDepth\n ? pruneTreeRecursive(\n { children: child.children },\n options,\n currentDepth + 1,\n )\n : { children: [] };\n\n keptChildren.push({\n ...child,\n children: prunedChild.children,\n });\n } else {\n // Collect small files for grouping\n groupedChildren.push(child);\n }\n }\n\n // Apply maxChildren limit - move overflow to grouped items\n let finalChildren = keptChildren;\n if (keptChildren.length > maxChildren) {\n const kept = keptChildren.slice(0, maxChildren);\n const overflow = keptChildren.slice(maxChildren);\n\n // Add overflow files to the grouped items\n groupedChildren.push(...overflow);\n finalChildren = kept;\n }\n\n // Create \"...\" group if we have multiple items to represent, or show single item directly\n if (groupedChildren.length > 0) {\n if (groupedChildren.length === 1) {\n // If there's only one grouped item, show it directly instead of creating \"...\" group\n finalChildren.push(groupedChildren[0]!);\n } else {\n // Multiple items - create \"...\" group\n const totalBytes = groupedChildren.reduce(\n (sum, child) => sum + child.values.bytes,\n 0,\n );\n const totalModules = groupedChildren.reduce(\n (sum, child) => sum + child.values.modules,\n 0,\n );\n\n const moreNode = {\n name: '...',\n values: {\n path: '',\n bytes: totalBytes,\n modules: totalModules,\n type: 'group' as const,\n },\n children: [], // Empty - just represents the grouped items\n };\n\n finalChildren.push(moreNode);\n }\n }\n\n return { children: finalChildren };\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/tree.unit.test.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'GroupingRule' is defined but never used.", - "line": 2, - "column": 15, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 2, - "endColumn": 27 - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it } from 'vitest';\nimport type { GroupingRule } from '../../types.js';\nimport { type StatsTreeNode, applyGrouping } from './grouping.js';\n\ndescribe('applyGrouping', () => {\n it('should group inputs by single pattern', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['src/**'], title: 'Source Files' },\n ]),\n ).toStrictEqual([\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'Source Files',\n values: {\n path: '',\n bytes: 150,\n modules: 2,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs by multiple patterns', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n path: 'src/utils/helper.ts',\n bytes: 40,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'tests/unit.test.ts',\n values: {\n path: 'tests/unit.test.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['src/**', 'tests/**'], title: 'Project Files' },\n ]),\n ).toStrictEqual([\n {\n name: 'Project Files',\n values: {\n bytes: 180,\n modules: 3,\n type: 'group',\n path: '',\n icon: undefined,\n },\n children: [\n {\n name: 'src/components/Button.tsx',\n values: {\n bytes: 80,\n modules: 1,\n type: 'static-import',\n path: 'src/components/Button.tsx',\n },\n children: [],\n },\n {\n name: 'tests/unit.test.ts',\n values: {\n bytes: 60,\n modules: 1,\n type: 'static-import',\n path: 'tests/unit.test.ts',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n bytes: 40,\n modules: 1,\n type: 'static-import',\n path: 'src/utils/helper.ts',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs with include/exclude patterns', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/components/Button.test.tsx',\n values: {\n path: 'src/components/Button.test.tsx',\n bytes: 40,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n path: 'src/utils/helper.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n {\n title: 'Source Code',\n includeInputs: ['src/**'],\n excludeInputs: ['**/*.test.*'],\n },\n ]),\n ).toStrictEqual([\n {\n name: 'Source Code',\n values: {\n path: '',\n bytes: 140,\n modules: 2,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils/helper.ts',\n values: {\n path: 'src/utils/helper.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs with numSegments', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 120,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'node_modules/lodash/core.js',\n values: {\n path: 'node_modules/lodash/core.js',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['node_modules/**'], numSegments: 2 },\n ]),\n ).toStrictEqual([\n {\n name: 'react',\n values: {\n path: 'node_modules/react',\n bytes: 120,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 120,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'lodash',\n values: {\n path: 'node_modules/lodash',\n bytes: 80,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'node_modules/lodash/core.js',\n values: {\n path: 'node_modules/lodash/core.js',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should add icons to nodes', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [{ includeInputs: ['src/**'], icon: '📦' }]),\n ).toStrictEqual([\n {\n name: 'Group',\n values: {\n path: '',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: '📦',\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should add title to nodes', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['src/**'], title: 'Source Code' },\n ]),\n ).toStrictEqual([\n {\n name: 'Source Code',\n values: {\n path: '',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should autoderive title from patterns', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [{ includeInputs: ['node_modules/**'] }]),\n ).toStrictEqual([\n {\n name: 'react',\n values: {\n path: '',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should separate packages into different groups with numSegments', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'packages/design-system/ui/button/src/button.component.ts',\n values: {\n path: 'packages/design-system/ui/button/src/button.component.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'packages/vanilla/lib/core/services/service.ts',\n values: {\n path: 'packages/vanilla/lib/core/services/service.ts',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'packages/themepark/components/theme.ts',\n values: {\n path: 'packages/themepark/components/theme.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n { includeInputs: ['packages/**'], numSegments: 2 },\n ]),\n ).toStrictEqual([\n {\n name: 'design-system',\n values: {\n path: 'packages/design-system',\n bytes: 100,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'packages/design-system/ui/button/src/button.component.ts',\n values: {\n path: 'packages/design-system/ui/button/src/button.component.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'vanilla',\n values: {\n path: 'packages/vanilla',\n bytes: 80,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'packages/vanilla/lib/core/services/service.ts',\n values: {\n path: 'packages/vanilla/lib/core/services/service.ts',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'themepark',\n values: {\n path: 'packages/themepark',\n bytes: 60,\n modules: 1,\n type: 'group',\n icon: undefined,\n },\n children: [\n {\n name: 'packages/themepark/components/theme.ts',\n values: {\n path: 'packages/themepark/components/theme.ts',\n bytes: 60,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should handle complex include/exclude combinations', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/components/Button.test.tsx',\n values: {\n path: 'src/components/Button.test.tsx',\n bytes: 40,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/components/Modal.spec.tsx',\n values: {\n path: 'src/components/Modal.spec.tsx',\n bytes: 30,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n {\n title: 'Source Code',\n includeInputs: ['src/**'],\n excludeInputs: ['**/*.test.*', '**/*.spec.*'],\n icon: '📦',\n },\n {\n title: 'Dependencies',\n includeInputs: ['node_modules/**'],\n icon: '🔗',\n },\n ]),\n ).toStrictEqual([\n {\n name: 'Dependencies',\n values: {\n path: '',\n bytes: 200,\n modules: 1,\n type: 'group',\n icon: '🔗',\n },\n children: [\n {\n name: 'node_modules/react/index.js',\n values: {\n path: 'node_modules/react/index.js',\n bytes: 200,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n {\n name: 'Source Code',\n values: {\n path: '',\n bytes: 80,\n modules: 1,\n type: 'group',\n icon: '📦',\n },\n children: [\n {\n name: 'src/components/Button.tsx',\n values: {\n path: 'src/components/Button.tsx',\n bytes: 80,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n\n it('should group inputs by multiple patterns with icons', () => {\n const nodes: StatsTreeNode[] = [\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 300,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ];\n\n expect(\n applyGrouping(nodes, [\n {\n includeInputs: ['src/main.ts', 'src/utils.ts'],\n title: 'Source Files',\n icon: '📄',\n },\n ]),\n ).toStrictEqual([\n {\n name: 'dist/output.js',\n values: {\n path: 'dist/output.js',\n bytes: 300,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'Source Files',\n values: {\n path: '',\n bytes: 150,\n modules: 2,\n type: 'group',\n icon: '📄',\n },\n children: [\n {\n name: 'src/main.ts',\n values: {\n path: 'src/main.ts',\n bytes: 100,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n {\n name: 'src/utils.ts',\n values: {\n path: 'src/utils.ts',\n bytes: 50,\n modules: 1,\n type: 'static-import',\n },\n children: [],\n },\n ],\n },\n ]);\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/details/types.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/scoring.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.1.", - "line": 34, - "column": 18, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 34, - "endColumn": 21 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.2.", - "line": 35, - "column": 16, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 35, - "endColumn": 19 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.2.", - "line": 66, - "column": 47, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 66, - "endColumn": 50 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.1.", - "line": 67, - "column": 51, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 67, - "endColumn": 54 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 69, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 69, - "endColumn": 22 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 70, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 70, - "endColumn": 24 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 72, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 78, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 150, - "column": 5, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 150, - "endColumn": 27 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.2.", - "line": 178, - "column": 36, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 178, - "endColumn": 39 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.2.", - "line": 201, - "column": 46, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 201, - "endColumn": 49 - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 0.1.", - "line": 202, - "column": 50, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 202, - "endColumn": 53 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 11, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { Issue } from '@code-pushup/models';\nimport type { MinMax } from '../types.js';\n\nexport type BlacklistPatternList = readonly BlacklistEntry[];\nexport type BlacklistEntry =\n | string\n | {\n pattern: string;\n hint?: string;\n };\n\nexport type PenaltyConfig = {\n enabled?: boolean;\n artefactSize?: [number, number];\n warningWeight?: number;\n errorWeight?: number;\n /**\n * glob patterns when matching get penalised\n * e.g. packagenames outdates, should be lazy loaded, etc.\n * Can be simple strings or objects with pattern and optional hint\n */\n blacklist?: BlacklistPatternList;\n};\n\nexport type ScoringConfig = {\n mode: 'off' | 'matchingWithStaticImports' | 'onlyMatching';\n totalSize?: MinMax;\n penalty?: false | PenaltyConfig;\n};\n\nexport type ScoreCalculator = (value: number, issues: Issue[]) => number;\n\nexport const DEFAULT_PENALTY: PenaltyConfig = {\n warningWeight: 0.1,\n errorWeight: 0.2,\n};\n\n/**\n * Calculates normalized penalty score from issues using provided penalty options. Legacy function for backward compatibility.\n *\n * ## Penalty Parameters\n * - **E**: Count of issues of severity errors (🚨)\n * - **W**: Count of issues of severity warnings (⚠️)\n * - **we**: Weight per error issue (default 0.2)\n * - **ww**: Weight per warning issue (default 0.1)\n *\n * ## Default Penalty Options\n * When penalty options are not provided, these defaults are used:\n * - **errorWeight**: 0.2\n * - **warningWeight**: 0.1\n *\n * ## Issues Penalty Formula\n * ```\n * penalty = we × E + ww × W\n * normalizedPenalty = penalty / (we + ww)\n * ```\n *\n * @param issues - Array of diagnostic issues with severity levels\n * @param penalty - Penalty configuration with error and warning weights\n * @returns Normalized penalty score (0-1) based on issue counts and weights\n */\nexport function calculatePenalty(\n issues: Issue[],\n penalty?: PenaltyConfig,\n): number {\n const errorWeight = penalty?.errorWeight ?? 0.2;\n const warningWeight = penalty?.warningWeight ?? 0.1;\n\n let errorCount = 0;\n let warningCount = 0;\n\n for (const issue of issues) {\n if (issue.severity === 'error') {\n errorCount++;\n } else if (issue.severity === 'warning') {\n warningCount++;\n }\n }\n\n const penaltyValue = errorWeight * errorCount + warningWeight * warningCount;\n const totalWeight = errorWeight + warningWeight;\n\n return totalWeight > 0 ? penaltyValue / totalWeight : 0;\n}\n\n/**\n * Creates a score calculator function configured with bundle settings. Applies direct penalty subtraction for intuitive scoring behavior with a maximum penalty cap of 20%.\n *\n * ## Scoring\n * Assigns a score in the range [0 … 1] to each artefact (or artefact selection) based on:\n * - Size vs. configurable minimum and maximum thresholds (if totalSize provided, otherwise defaults to 100%)\n * - Direct penalty subtraction based on issue severity levels (when enabled)\n * - Penalty is capped at maximum 20% of the size score\n *\n * A perfect score (1) means \"within acceptable range\"; lower values indicate regressions.\n *\n * ## Size Parameters\n * - **S**: Actual bytes\n * - **Min**: Minimum threshold bytes (lower bound)\n * - **Max**: Maximum threshold bytes (upper bound)\n *\n * ## Size Score Formula\n * When totalSize is not provided:\n * ```\n * sizeScore = 1 (100%)\n * ```\n *\n * For single threshold (number):\n * ```\n * sizeScore = {\n * 1, if S ≤ threshold\n * 0, if S > threshold\n * }\n * ```\n *\n * For range thresholds [Min, Max]:\n * ```\n * sizeScore = {\n * max(0, S/Min), if S < Min (penalize under-sized bundles)\n * 1, if Min ≤ S ≤ Max (perfect score)\n * 0, if S > Max (too big = score 0)\n * }\n * ```\n *\n * ## Penalty Calculation\n * Direct subtraction approach with 20% maximum penalty cap:\n * ```\n * penaltyShift = errors × errorWeight + warnings × warningWeight\n * cappedPenalty = min(penaltyShift, sizeScore × 0.2)\n * ```\n * Default weights: errorWeight = 0.2, warningWeight = 0.1\n *\n * ## Final Score Calculation\n * ```\n * finalScore = max(0, sizeScore - cappedPenalty)\n * ```\n * This creates a penalty shift pattern where issues directly reduce the score by their weight values,\n * but the total penalty reduction is capped at 20% of the original size score.\n * Note: When `penalty` is `false` or undefined, only size score is used.\n *\n * @param options - Scoring configuration containing optional thresholds and penalty weights\n * @returns Score calculator function that takes (value, issues) and returns score [0-1]\n */\nexport function createBundleStatsScoring(\n options: ScoringConfig,\n): ScoreCalculator {\n const { totalSize, penalty } = options;\n\n return (value: number, issues: Issue[] = []): number => {\n let sizeScore: number;\n\n if (!totalSize) {\n // No size constraints - default to perfect score (100%)\n sizeScore = 1;\n } else if (Array.isArray(totalSize)) {\n // Range thresholds [min, max]\n const [minThreshold, maxThreshold] = totalSize;\n\n if (value < minThreshold) {\n sizeScore = Math.max(0, value / minThreshold);\n } else if (value <= maxThreshold) {\n sizeScore = 1;\n } else {\n sizeScore = 0;\n }\n } else {\n sizeScore = value <= totalSize ? 1 : 0;\n }\n\n if (penalty === false || penalty === undefined || issues.length === 0) {\n return sizeScore;\n }\n\n const penaltyOptions = penalty || DEFAULT_PENALTY;\n const penaltyShift = calculatePenaltyShift(issues, penaltyOptions);\n\n // Cap penalty at maximum 20% of the size score\n const maxPenalty = sizeScore * 0.2;\n const cappedPenalty = Math.min(penaltyShift, maxPenalty);\n\n return Math.max(0, sizeScore - cappedPenalty);\n };\n}\n\n/**\n * Calculates direct penalty shift based on issue counts and weights. Creates intuitive score reduction where each issue subtracts its weight from the final score.\n *\n * @param issues - Array of diagnostic issues with severity levels\n * @param options - Penalty configuration with error and warning weights\n * @returns Direct penalty shift value to subtract from size score\n */\nfunction calculatePenaltyShift(\n issues: Issue[],\n options: PenaltyConfig,\n): number {\n const errorCount = issues.filter(issue => issue.severity === 'error').length;\n const warningCount = issues.filter(\n issue => issue.severity === 'warning',\n ).length;\n\n const errorWeight = options.errorWeight ?? 0.2;\n const warningWeight = options.warningWeight ?? 0.1;\n\n // Direct penalty: each error/warning reduces score by its weight\n return errorCount * errorWeight + warningCount * warningWeight;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/selection.ts", - "messages": [ - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 42, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 46, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 54, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 56, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'getImportPaths' is defined but never used.", - "line": 59, - "column": 11, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 59, - "endColumn": 25 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 63, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 65, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 75, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 79, - "endColumn": 4 - }, - { - "ruleId": "sonarjs/no-identical-functions", - "severity": 2, - "message": "Update this function so that its implementation is not identical to the one on line 68.", - "line": 83, - "column": 10, - "nodeType": null, - "messageId": "identicalFunctions", - "endLine": 83, - "endColumn": 26 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 90, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 94, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'pathsMatchPatterns' is defined but never used.", - "line": 98, - "column": 10, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 98, - "endColumn": 28 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 108, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 110, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 109, - "column": 5, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 109, - "endColumn": 25 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 118, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 122, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 131, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 135, - "endColumn": 4 - }, - { - "ruleId": "sonarjs/prefer-single-boolean-return", - "severity": 1, - "message": "Replace this if-then-else flow by a single return statement.", - "line": 176, - "column": 5, - "nodeType": "IfStatement", - "messageId": "replaceIfThenElseByReturn", - "endLine": 178, - "endColumn": 6, - "suggestions": [ - { - "messageId": "suggest", - "fix": { - "range": [4033, 4132], - "text": "return !(hasExcludedInput(bundle, patterns.excludeInputs));" - }, - "desc": "Replace with single return statement" - } - ] - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 203, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 203, - "endColumn": 25 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 204, - "column": 3, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 204, - "endColumn": 26 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 206, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 212, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 208, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 208, - "endColumn": 44 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 232, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 236, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 234, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 234, - "endColumn": 29 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'selectBundles' has too many lines (88). Maximum allowed is 50.", - "line": 267, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 381, - "endColumn": 2 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 277, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 279, - "endColumn": 4 - }, - { - "ruleId": "sonarjs/no-unused-collection", - "severity": 2, - "message": "Either use this collection's contents or remove the collection.", - "line": 288, - "column": 9, - "nodeType": "Identifier", - "messageId": "unusedCollection", - "endLine": 288, - "endColumn": 21 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 307, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 326, - "endColumn": 4 - }, - { - "ruleId": "functional/no-let", - "severity": 1, - "message": "Unexpected let, use const instead.", - "line": 313, - "column": 5, - "nodeType": "VariableDeclaration", - "messageId": "generic", - "endLine": 313, - "endColumn": 34 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 337, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 341, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 338, - "column": 7, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 340, - "endColumn": 8 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 344, - "column": 5, - "nodeType": "WhileStatement", - "messageId": "generic", - "endLine": 377, - "endColumn": 6 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 345, - "column": 26, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 345, - "endColumn": 49 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 345, - "column": 26, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 345, - "endColumn": 48 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 368, - "column": 9, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 375, - "endColumn": 10 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", - "line": 369, - "column": 11, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 374, - "endColumn": 12 - }, - { - "ruleId": "max-lines", - "severity": 1, - "message": "File has too many lines (311). Maximum allowed is 300.", - "line": 370, - "column": 1, - "nodeType": null, - "messageId": "exceed", - "endLine": 382, - "endColumn": 1 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 373, - "column": 13, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 373, - "endColumn": 53 - } - ], - "suppressedMessages": [], - "errorCount": 11, - "fatalErrorCount": 0, - "warningCount": 22, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n} from '../unify/unified-stats.types.js';\nimport { type PatternMatcher, compilePattern } from './details/grouping.js';\n\nexport type SelectionOutputsConfig = {\n includeOutputs: string[];\n excludeOutputs: string[];\n};\n\nexport type SelectionInputsConfig = {\n includeInputs: string[];\n excludeInputs: string[];\n};\n\nexport type SelectionMode =\n | 'matchingOnly'\n | 'bundle'\n | 'withStartupDeps'\n | 'withAllDeps';\n\nexport type SelectionConfig = {\n mode: SelectionMode;\n} & SelectionOutputsConfig &\n SelectionInputsConfig;\n\nexport type CompiledPatterns = {\n includeOutputs: PatternMatcher[];\n excludeOutputs: PatternMatcher[];\n includeInputs: PatternMatcher[];\n excludeInputs: PatternMatcher[];\n};\n\nfunction compilePatterns(patterns: string[]): PatternMatcher[] {\n return patterns.map(pattern =>\n compilePattern(pattern, { normalizeRelativePaths: true }),\n );\n}\n\nfunction matchesAnyPattern(path: string, patterns: PatternMatcher[]): boolean {\n for (const pattern of patterns) {\n if (pattern(path)) {\n return true;\n } // Early exit on first match\n }\n return false;\n}\n\nfunction* getInputPaths(bundle: UnifiedStatsBundle): Generator {\n if (!bundle.inputs) {\n return;\n }\n for (const path of Object.keys(bundle.inputs)) {\n yield path;\n }\n}\n\nfunction* getImportPaths(bundle: UnifiedStatsBundle): Generator {\n if (!bundle.imports) {\n return;\n }\n for (const imp of bundle.imports) {\n yield imp.path;\n }\n}\n\nfunction hasMatchingInput(\n bundle: UnifiedStatsBundle,\n patterns: PatternMatcher[],\n): boolean {\n if (patterns.length === 0) {\n return false;\n }\n for (const path of getInputPaths(bundle)) {\n if (matchesAnyPattern(path, patterns)) {\n return true;\n } // Stop on first match\n }\n return false;\n}\n\nfunction hasExcludedInput(\n bundle: UnifiedStatsBundle,\n patterns: PatternMatcher[],\n): boolean {\n if (patterns.length === 0) {\n return false;\n }\n for (const path of getInputPaths(bundle)) {\n if (matchesAnyPattern(path, patterns)) {\n return true;\n } // Stop on first exclusion\n }\n return false;\n}\n\nfunction pathsMatchPatterns(\n paths: Generator,\n includePatterns: PatternMatcher[],\n excludePatterns: PatternMatcher[],\n): boolean {\n if (includePatterns.length === 0 && excludePatterns.length === 0) {\n return true;\n }\n\n const pathArray: string[] = [];\n for (const path of paths) {\n pathArray.push(path);\n }\n\n if (pathArray.length === 0) {\n return includePatterns.length === 0;\n }\n\n // Check excludes first (early exit)\n if (excludePatterns.length > 0) {\n for (const path of pathArray) {\n if (matchesAnyPattern(path, excludePatterns)) {\n return false;\n }\n }\n }\n\n // If no includes specified, and nothing excluded, include it\n if (includePatterns.length === 0) {\n return true;\n }\n\n // Check includes\n for (const path of pathArray) {\n if (matchesAnyPattern(path, includePatterns)) {\n return true;\n }\n }\n\n return false;\n}\n\n// Mode-specific processors for optimized selection\nconst bundleSelectors = {\n matchingOnly: (\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n ): boolean =>\n patterns.includeInputs.length > 0 &&\n hasMatchingInput(bundle, patterns.includeInputs),\n\n bundle: (bundle: UnifiedStatsBundle, patterns: CompiledPatterns): boolean => {\n const hasIncludePatterns =\n patterns.includeOutputs.length > 0 || patterns.includeInputs.length > 0;\n if (!hasIncludePatterns) {\n return false;\n }\n\n // Check output patterns\n if (\n patterns.includeOutputs.length > 0 &&\n !matchesAnyPattern(bundle.path, patterns.includeOutputs)\n ) {\n return false;\n }\n\n // Check input patterns\n if (\n patterns.includeInputs.length > 0 &&\n !hasMatchingInput(bundle, patterns.includeInputs)\n ) {\n return false;\n }\n\n // Check exclusions\n if (matchesAnyPattern(bundle.path, patterns.excludeOutputs)) {\n return false;\n }\n if (hasExcludedInput(bundle, patterns.excludeInputs)) {\n return false;\n }\n\n return true;\n },\n\n withStartupDeps: (\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n ): boolean => bundleSelectors.bundle(bundle, patterns),\n\n withAllDeps: (\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n ): boolean => bundleSelectors.bundle(bundle, patterns),\n};\n\nfunction processMatchingOnlyBundle(\n bundle: UnifiedStatsBundle,\n patterns: CompiledPatterns,\n): UnifiedStatsBundle | null {\n if (!bundle.inputs) {\n return null;\n }\n\n const filteredInputs: typeof bundle.inputs = {};\n let filteredBytes = 0;\n let hasMatches = false;\n\n for (const [inputPath, inputData] of Object.entries(bundle.inputs)) {\n if (matchesAnyPattern(inputPath, patterns.includeInputs)) {\n filteredInputs[inputPath] = inputData;\n filteredBytes += inputData.bytes;\n hasMatches = true;\n }\n }\n\n return hasMatches\n ? {\n path: bundle.path,\n bytes: filteredBytes,\n inputs: filteredInputs,\n }\n : null;\n}\n\nfunction collectImportsForMode(\n bundle: UnifiedStatsBundle,\n mode: SelectionMode,\n): string[] {\n if (!bundle.imports) {\n return [];\n }\n\n const imports: string[] = [];\n for (const imp of bundle.imports) {\n if (mode === 'withAllDeps' || imp.kind === 'import-statement') {\n imports.push(imp.path);\n }\n }\n return imports;\n}\n\nfunction validatePatterns(patterns: CompiledPatterns): void {\n const hasAnyPatterns = [\n patterns.includeOutputs,\n patterns.excludeOutputs,\n patterns.includeInputs,\n patterns.excludeInputs,\n ].some(arr => arr.length > 0);\n\n if (!hasAnyPatterns) {\n throw new Error(\n 'Selection requires at least one include/exclude pattern for outputs or inputs. ' +\n 'Provide patterns like: { includeOutputs: [\"*.js\"] } or { includeInputs: [\"src/**\"] }',\n );\n }\n}\n\nexport function compileSelectionPatterns(\n config: SelectionConfig,\n): CompiledPatterns {\n return {\n includeOutputs: compilePatterns(config.includeOutputs),\n excludeOutputs: compilePatterns(config.excludeOutputs),\n includeInputs: compilePatterns(config.includeInputs),\n excludeInputs: compilePatterns(config.excludeInputs),\n };\n}\n\nexport function selectBundles(\n unifiedStats: UnifiedStats,\n selectionConfig: SelectionConfig,\n): UnifiedStats {\n // 🚀 Smart Optimization 1: Single-pass pattern compilation\n const patterns = compileSelectionPatterns(selectionConfig);\n validatePatterns(patterns);\n\n // 🚀 Smart Optimization 2: O(1) bundle lookups with simple map\n const pathToKey = new Map();\n for (const [key, bundle] of Object.entries(unifiedStats)) {\n pathToKey.set(bundle.path, key);\n }\n\n const findBundleByPath = (path: string) => {\n const key = pathToKey.get(path);\n return key && unifiedStats[key] ? { key, bundle: unifiedStats[key] } : null;\n };\n\n // 🚀 Smart Optimization 3: Early exit & set-based processing\n const selectedBundles = new Map();\n const excludedKeys = new Set();\n\n // Get mode-specific selector for optimized processing\n const isSelected = (bundle: UnifiedStatsBundle): boolean => {\n switch (selectionConfig.mode) {\n case 'matchingOnly':\n return bundleSelectors.matchingOnly(bundle, patterns);\n case 'bundle':\n return bundleSelectors.bundle(bundle, patterns);\n case 'withStartupDeps':\n return bundleSelectors.withStartupDeps(bundle, patterns);\n case 'withAllDeps':\n return bundleSelectors.withAllDeps(bundle, patterns);\n default:\n return false;\n }\n };\n\n // Process all bundles with early exits\n for (const [key, bundle] of Object.entries(unifiedStats)) {\n if (!isSelected(bundle)) {\n excludedKeys.add(key);\n continue; // Early exit\n }\n\n let processedBundle = bundle;\n\n // Special processing for matchingOnly mode\n if (selectionConfig.mode === 'matchingOnly') {\n const filtered = processMatchingOnlyBundle(bundle, patterns);\n if (!filtered) {\n excludedKeys.add(key);\n continue; // Early exit\n }\n processedBundle = filtered;\n }\n\n selectedBundles.set(key, processedBundle);\n }\n\n // 🚀 Smart Optimization 4: Optimized dependency processing\n if (\n selectionConfig.mode === 'withStartupDeps' ||\n selectionConfig.mode === 'withAllDeps'\n ) {\n const processed = new Set();\n const importsToProcess: string[] = [];\n\n // Collect all imports from selected bundles\n for (const bundle of selectedBundles.values()) {\n importsToProcess.push(\n ...collectImportsForMode(bundle, selectionConfig.mode),\n );\n }\n\n // Process imports with optimized lookups and early exits\n while (importsToProcess.length > 0) {\n const importPath = importsToProcess.pop()!;\n if (processed.has(importPath)) {\n continue;\n } // Early exit\n processed.add(importPath);\n\n const found = findBundleByPath(importPath);\n if (!found || selectedBundles.has(found.key)) {\n continue;\n } // Early exit\n\n // Check if import should be excluded\n if (matchesAnyPattern(found.bundle.path, patterns.excludeOutputs)) {\n continue;\n }\n if (hasExcludedInput(found.bundle, patterns.excludeInputs)) {\n continue;\n }\n\n selectedBundles.set(found.key, found.bundle);\n\n // Add nested static imports for further processing\n if (found.bundle.imports) {\n for (const nestedImport of found.bundle.imports) {\n if (\n nestedImport.kind === 'import-statement' &&\n !processed.has(nestedImport.path)\n ) {\n importsToProcess.push(nestedImport.path);\n }\n }\n }\n }\n }\n\n return Object.fromEntries(selectedBundles);\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/audits/selection.unit.test.ts", - "messages": [ - { - "ruleId": "vitest/no-conditional-expect", - "severity": 1, - "message": "Avoid calling `expect` inside conditional statements", - "line": 264, - "column": 9, - "nodeType": "CallExpression", - "messageId": "noConditionalExpect", - "endLine": 266, - "endColumn": 21 - }, - { - "ruleId": "vitest/no-conditional-expect", - "severity": 1, - "message": "Avoid calling `expect` inside conditional statements", - "line": 305, - "column": 9, - "nodeType": "CallExpression", - "messageId": "noConditionalExpect", - "endLine": 307, - "endColumn": 21 - }, - { - "ruleId": "vitest/no-conditional-expect", - "severity": 1, - "message": "Avoid calling `expect` inside conditional statements", - "line": 323, - "column": 9, - "nodeType": "CallExpression", - "messageId": "noConditionalExpect", - "endLine": 323, - "endColumn": 61 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 3, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it } from 'vitest';\nimport { normalizeSelectionOptions } from '../../normalize.js';\nimport type { UnifiedStats } from '../unify/unified-stats.types.js';\nimport { compileSelectionPatterns, selectBundles } from './selection.js';\n\ndescribe('compileSelectionPatterns', () => {\n it('should return object with correct structure for all pattern types', () => {\n const result = compileSelectionPatterns({\n mode: 'bundle',\n includeOutputs: ['dist/**/*.js'],\n excludeOutputs: ['dist/**/*.map'],\n includeInputs: ['src/**/*.ts'],\n excludeInputs: ['**/*.test.ts'],\n });\n\n expect(result).toStrictEqual({\n includeOutputs: [expect.any(Function)],\n excludeOutputs: [expect.any(Function)],\n includeInputs: [expect.any(Function)],\n excludeInputs: [expect.any(Function)],\n });\n expect([\n result.includeOutputs[0]!('dist/main.js'),\n result.includeOutputs[0]!('dist/main.map'),\n ]).toEqual([true, false]);\n });\n\n it('should handle empty selection options', () => {\n expect(\n compileSelectionPatterns({\n mode: 'bundle',\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n }),\n ).toStrictEqual({\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n });\n });\n\n it('should merge global include/exclude patterns', () => {\n const result = compileSelectionPatterns(\n normalizeSelectionOptions({\n include: ['src/**'],\n exclude: ['*.test.*'],\n includeOutputs: ['main.js'],\n excludeOutputs: ['dev.js'],\n includeInputs: ['components/**'],\n excludeInputs: ['temp.js'],\n }),\n );\n\n expect(\n [\n result.includeOutputs,\n result.excludeOutputs,\n result.includeInputs,\n result.excludeInputs,\n ].map(arr => arr.length),\n ).toEqual([2, 2, 2, 2]);\n });\n\n it('should work with type configurations', () => {\n const result = compileSelectionPatterns({\n mode: 'bundle' as const,\n includeOutputs: ['*.js'],\n excludeOutputs: ['*.test.js'],\n includeInputs: [],\n excludeInputs: [],\n });\n\n expect([\n result.includeOutputs[0]!('main.js'),\n result.excludeOutputs[0]!('main.test.js'),\n ]).toEqual([true, true]);\n });\n});\n\ndescribe('selectBundles', () => {\n const empty = {\n mode: 'bundle' as const,\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n\n const stats: UnifiedStats = {\n 'dist/index.js': {\n path: 'dist/index.js',\n bytes: 5000,\n inputs: {\n 'src/index.ts': { bytes: 1000 },\n 'src/lib/feature-1.ts': { bytes: 1000 },\n 'src/lib/utils/format.ts': { bytes: 1000 },\n 'src/lib/utils/math.ts': { bytes: 1000 },\n 'src/lib/feature-2.ts': { bytes: 1000 },\n },\n imports: [\n { path: 'dist/chunks/chunk-U6O5K65G.js', kind: 'import-statement' },\n { path: 'dist/chunks/feature-2-X2YVDBQK.js', kind: 'dynamic-import' },\n ],\n },\n 'dist/bin.js': {\n path: 'dist/bin.js',\n bytes: 3000,\n inputs: {\n 'src/bin.ts': { bytes: 500 },\n 'src/lib/feature-1.ts': { bytes: 1000 },\n 'src/lib/utils/format.ts': { bytes: 1000 },\n 'src/lib/utils/math.ts': { bytes: 500 },\n },\n imports: [\n { path: 'dist/chunks/chunk-U6O5K65G.js', kind: 'import-statement' },\n ],\n },\n 'dist/chunks/chunk-U6O5K65G.js': {\n path: 'dist/chunks/chunk-U6O5K65G.js',\n bytes: 2000,\n inputs: {\n 'src/lib/utils/format.ts': { bytes: 1000 },\n 'src/lib/feature-1.ts': { bytes: 500 },\n 'src/lib/utils/math.ts': { bytes: 500 },\n },\n },\n 'dist/chunks/feature-2-X2YVDBQK.js': {\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n bytes: 1000,\n inputs: {\n 'src/lib/feature-2.ts': { bytes: 1000 },\n },\n },\n };\n\n it('should return empty result for empty stats', () => {\n expect(\n selectBundles({}, { ...empty, includeOutputs: ['*.js'] }),\n ).toStrictEqual({});\n });\n\n it('should throw error for empty selection options', () => {\n expect(() => selectBundles({}, empty)).toThrow(\n 'Selection requires at least one include/exclude pattern',\n );\n expect(() =>\n selectBundles(\n { 'main.js': { path: 'dist/main.js', bytes: 0, inputs: {} } },\n empty,\n ),\n ).toThrow('Provide patterns like');\n });\n\n // Byte Inclusion Tests\n it('should select output and dependencies (Include Output)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n }),\n ),\n ).toEqual(['dist/index.js', 'dist/chunks/chunk-U6O5K65G.js']);\n });\n\n it('should include static imports only (Include Output)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n !!result['dist/chunks/chunk-U6O5K65G.js'],\n !!result['dist/chunks/feature-2-X2YVDBQK.js'],\n ]).toEqual([true, false]);\n });\n\n it('should select only bundle file in bundle mode', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n mode: 'bundle',\n includeOutputs: ['**/dist/index.js'],\n }),\n ),\n ).toEqual(['dist/index.js']);\n });\n\n it('should exclude files by pattern (Include/Exclude Output)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/*'],\n excludeOutputs: ['**/bin.js'],\n }),\n ),\n ).toEqual([\n 'dist/index.js',\n 'dist/chunks/chunk-U6O5K65G.js',\n 'dist/chunks/feature-2-X2YVDBQK.js',\n ]);\n });\n\n it('should prioritize exclude over include', () => {\n expect(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/dist/index.js'],\n excludeOutputs: ['**/dist/index.js'],\n }),\n ).toStrictEqual({});\n });\n\n it('should select by input files (Include Input)', () => {\n expect(\n Object.keys(\n selectBundles(stats, { ...empty, includeInputs: ['**/feature-2.ts'] }),\n ),\n ).toEqual(['dist/index.js', 'dist/chunks/feature-2-X2YVDBQK.js']);\n });\n\n it('should select by utility files (Include Input)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeInputs: ['**/utils/format.ts'],\n }),\n ),\n ).toEqual([\n 'dist/index.js',\n 'dist/bin.js',\n 'dist/chunks/chunk-U6O5K65G.js',\n ]);\n });\n\n it('should exclude by input files (Include/Exclude Input)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/*'],\n excludeInputs: ['**/feature-2.ts'],\n }),\n ),\n ).toEqual(['dist/bin.js', 'dist/chunks/chunk-U6O5K65G.js']);\n });\n\n it('should exclude utility files', () => {\n const result = selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/*'],\n excludeInputs: ['**/utils/**'],\n });\n Object.values(result).forEach(\n output =>\n output?.inputs &&\n expect(\n Object.keys(output.inputs).every(path => !path.includes('utils')),\n ).toBe(true),\n );\n });\n\n it('should handle complex filtering (Include/Exclude Mixed)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/index.js', '**/chunks/**'],\n excludeOutputs: ['**/bin.js'],\n excludeInputs: ['**/utils/**'],\n }),\n ),\n ).not.toContain('dist/bin.js');\n });\n\n it('should combine include patterns with OR logic', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n includeOutputs: ['**/index.js', '**/bin.js'],\n excludeInputs: ['**/feature-2.ts'],\n }),\n ),\n ).toEqual(['dist/bin.js']);\n });\n\n // Dependency Inclusion Tests\n it('should filter inputs in matchingOnly mode', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'matchingOnly',\n includeInputs: ['**/utils/format.ts'],\n });\n Object.values(result).forEach(\n output =>\n output?.inputs &&\n expect(\n Object.keys(output.inputs).every(path => path.includes('format.ts')),\n ).toBe(true),\n );\n });\n\n it('should exclude bundler overhead in matchingOnly mode', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'matchingOnly',\n includeInputs: ['**/feature-1.ts'],\n });\n Object.values(result).forEach(output => {\n if (output?.inputs) {\n const inputBytes = Object.values(output.inputs).reduce(\n (sum, input) => sum + (input?.bytes || 0),\n 0,\n );\n expect(output.bytes).toBeLessThanOrEqual(inputBytes);\n }\n });\n });\n\n it('should include full bundle with overhead (Mode: bundle)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'bundle',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n result['dist/index.js']?.bytes,\n Object.keys(result).length,\n ]).toEqual([5000, 1]);\n });\n\n it('should preserve bundled inputs (Mode: bundle)', () => {\n expect(\n Object.keys(\n selectBundles(stats, {\n ...empty,\n mode: 'bundle',\n includeOutputs: ['**/dist/bin.js'],\n })['dist/bin.js']?.inputs || {},\n ),\n ).toHaveLength(4);\n });\n\n it('should include static imports (Mode: withStartupDeps)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n !!result['dist/chunks/chunk-U6O5K65G.js'],\n !!result['dist/chunks/feature-2-X2YVDBQK.js'],\n ]).toEqual([true, false]);\n });\n\n it('should exclude static imports by pattern (Mode: withStartupDeps)', () => {\n expect(\n selectBundles(stats, {\n ...empty,\n mode: 'withStartupDeps',\n includeOutputs: ['**/dist/index.js'],\n excludeOutputs: ['**/chunks/**'],\n })['dist/chunks/chunk-U6O5K65G.js'],\n ).toBeUndefined();\n });\n\n it('should include all imports (Mode: withAllDeps)', () => {\n const result = selectBundles(stats, {\n ...empty,\n mode: 'withAllDeps',\n includeOutputs: ['**/dist/index.js'],\n });\n expect([\n !!result['dist/chunks/chunk-U6O5K65G.js'],\n !!result['dist/chunks/feature-2-X2YVDBQK.js'],\n ]).toEqual([true, true]);\n });\n\n it('should exclude dependencies that match exclude patterns (Mode: withAllDeps)', () => {\n expect(\n selectBundles(stats, {\n ...empty,\n mode: 'withAllDeps',\n includeOutputs: ['**/dist/index.js'],\n excludeOutputs: ['**/chunks/**'],\n }),\n ).toStrictEqual({ 'dist/index.js': stats['dist/index.js'] });\n });\n\n it('should handle nested dependency chains (Mode: withAllDeps)', () => {\n const nestedStats = {\n 'dist/nested.js': {\n path: 'dist/nested.js',\n bytes: 1000,\n inputs: {},\n imports: [{ path: 'dist/level1.js', kind: 'import-statement' }],\n },\n 'dist/level1.js': {\n path: 'dist/level1.js',\n bytes: 500,\n inputs: {},\n imports: [{ path: 'dist/level2.js', kind: 'dynamic-import' }],\n },\n 'dist/level2.js': { path: 'dist/level2.js', bytes: 200, inputs: {} },\n } as unknown as UnifiedStats;\n\n expect(\n Object.keys(\n selectBundles(nestedStats, {\n ...empty,\n mode: 'withAllDeps',\n includeOutputs: ['**/nested.js'],\n }),\n ),\n ).toEqual(['dist/nested.js', 'dist/level1.js']);\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.int.test.ts", - "messages": [ - { - "ruleId": "unicorn/no-empty-file", - "severity": 1, - "message": "Empty files are not allowed.", - "line": 1, - "column": 1, - "nodeType": "Program", - "messageId": "no-empty-file", - "endLine": 1, - "endColumn": 1 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 1, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.ts", - "messages": [ - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'validateBundleStats' has too many lines (66). Maximum allowed is 50.", - "line": 35, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 102, - "endColumn": 2 - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 109, - "column": 12, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 109, - "endColumn": 15, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3597, 3600], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3597, 3600], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 109, - "column": 27, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 109, - "endColumn": 30, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3612, 3615], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3612, 3615], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 112, - "column": 22, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 112, - "endColumn": 25, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3697, 3700], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3697, 3700], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 112, - "column": 36, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 112, - "endColumn": 39, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3711, 3714], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3711, 3714], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "functional/prefer-tacit", - "severity": 1, - "message": "Potentially unnecessary function wrapper.", - "line": 115, - "column": 14, - "nodeType": "ArrowFunctionExpression", - "messageId": "generic", - "endLine": 115, - "endColumn": 54, - "suggestions": [ - { - "messageId": "generic", - "fix": { - "range": [3800, 3840], - "text": "unifyWebpackStats" - }, - "desc": "Potentially unnecessary function wrapper." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 115, - "column": 22, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 115, - "endColumn": 25, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3808, 3811], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3808, 3811], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "functional/prefer-tacit", - "severity": 1, - "message": "Potentially unnecessary function wrapper.", - "line": 117, - "column": 14, - "nodeType": "ArrowFunctionExpression", - "messageId": "generic", - "endLine": 117, - "endColumn": 54, - "suggestions": [ - { - "messageId": "generic", - "fix": { - "range": [3875, 3915], - "text": "unifyRsbuildStats" - }, - "desc": "Potentially unnecessary function wrapper." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 117, - "column": 22, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 117, - "endColumn": 25, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3883, 3886], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3883, 3886], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "functional/prefer-tacit", - "severity": 1, - "message": "Potentially unnecessary function wrapper.", - "line": 119, - "column": 14, - "nodeType": "ArrowFunctionExpression", - "messageId": "generic", - "endLine": 119, - "endColumn": 51, - "suggestions": [ - { - "messageId": "generic", - "fix": { - "range": [3947, 3984], - "text": "unifyViteStats" - }, - "desc": "Potentially unnecessary function wrapper." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 119, - "column": 22, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 119, - "endColumn": 25, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [3955, 3958], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [3955, 3958], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 121, - "column": 22, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 121, - "endColumn": 25, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [4025, 4028], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [4025, 4028], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-explicit-any", - "severity": 2, - "message": "Unexpected any. Specify a different type.", - "line": 121, - "column": 36, - "nodeType": "TSAnyKeyword", - "messageId": "unexpectedAny", - "endLine": 121, - "endColumn": 39, - "suggestions": [ - { - "messageId": "suggestUnknown", - "fix": { - "range": [4039, 4042], - "text": "unknown" - }, - "desc": "Use `unknown` instead, this will force you to explicitly, and safely assert the type is correct." - }, - { - "messageId": "suggestNever", - "fix": { - "range": [4039, 4042], - "text": "never" - }, - "desc": "Use `never` instead, this is useful when instantiating generic type parameters that you don't need to know the type of." - } - ] - }, - { - "ruleId": "@typescript-eslint/no-magic-numbers", - "severity": 1, - "message": "No magic number: 20.", - "line": 159, - "column": 22, - "nodeType": "Literal", - "messageId": "noMagic", - "endLine": 159, - "endColumn": 24 - } - ], - "suppressedMessages": [], - "errorCount": 9, - "fatalErrorCount": 0, - "warningCount": 5, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { AuditOutput, PluginArtifactOptions } from '@code-pushup/models';\nimport { executeProcess, readJsonFile } from '@code-pushup/utils';\nimport { normalizeRange } from '../normalize.js';\nimport type {\n PluginDependencyTreeOptions,\n PluginInsightsTableOptions,\n PluginScoringOptions,\n PluginSelectionOptions,\n} from '../types.js';\nimport { generateAuditOutputs } from './audits/audit-outputs.js';\nimport type { InsightsTableConfig } from './audits/details/table.js';\nimport type { DependencyTreeConfig } from './audits/details/tree.js';\nimport { DEFAULT_PENALTY } from './audits/scoring.js';\nimport type { SelectionConfig } from './audits/selection.js';\nimport type {\n BundleStatsConfig,\n GroupingRule,\n SupportedBundlers,\n} from './types.js';\nimport type { UnifiedStats } from './unify/unified-stats.types.js';\nimport { unifyBundlerStats as unifyEsbuildStats } from './unify/unify.esbuild.js';\nimport { unifyBundlerStats as unifyRsbuildStats } from './unify/unify.rsbuild.js';\nimport { unifyBundlerStats as unifySondaStats } from './unify/unify.sonda.js';\nimport { unifyBundlerStats as unifyViteStats } from './unify/unify.vite.js';\nimport { unifyBundlerStats as unifyWebpackStats } from './unify/unify.webpack.js';\n\nexport type BundleStatsRunnerConfig = {\n bundler: SupportedBundlers;\n bundleStatsConfigs: BundleStatsConfig[];\n} & PluginArtifactOptions;\n\n/**\n * Validates bundle stats data structure based on bundler type. Ensures stats and required properties are properly defined.\n */\nexport function validateBundleStats(\n stats: unknown,\n artefactsPath: string,\n bundler: SupportedBundlers,\n): void {\n if (!stats) {\n throw new Error(`Bundle stats file is null or undefined: ${artefactsPath}`);\n }\n\n if (typeof stats !== 'object') {\n throw new TypeError(\n `Bundle stats file has invalid structure: ${artefactsPath}`,\n );\n }\n\n switch (bundler) {\n case 'esbuild':\n if (!('outputs' in stats)) {\n throw new Error(\n `Bundle stats file missing 'outputs' property for esbuild: ${artefactsPath}`,\n );\n }\n if (!stats.outputs) {\n throw new Error(\n `Bundle stats outputs is null or undefined in file: ${artefactsPath}`,\n );\n }\n break;\n case 'webpack':\n if (\n !('assets' in stats) ||\n !('chunks' in stats) ||\n !('modules' in stats)\n ) {\n throw new Error(\n `Bundle stats file missing required webpack properties (assets, chunks, modules): ${artefactsPath}`,\n );\n }\n break;\n case 'rsbuild':\n if (\n !('assets' in stats) ||\n !('chunks' in stats) ||\n !('modules' in stats)\n ) {\n throw new Error(\n `Bundle stats file missing required rsbuild properties (assets, chunks, modules): ${artefactsPath}`,\n );\n }\n break;\n case 'vite':\n if (!('assets' in stats) || !('chunks' in stats)) {\n throw new Error(\n `Bundle stats file missing required vite properties (assets, chunks): ${artefactsPath}`,\n );\n }\n break;\n case 'sonda':\n if (!('resources' in stats) || !('connections' in stats)) {\n throw new Error(\n `Bundle stats file missing required sonda properties (resources, connections): ${artefactsPath}`,\n );\n }\n break;\n default:\n throw new Error(`Unsupported bundler: ${bundler}`);\n }\n}\n\n/**\n * Returns the appropriate unify function based on bundler type. Provides bundler-specific stats processing.\n */\nexport function getUnifyFunction(\n bundler: SupportedBundlers,\n): (stats: any, options?: any) => UnifiedStats {\n switch (bundler) {\n case 'esbuild':\n return (stats: any, options: any = {}) =>\n unifyEsbuildStats(stats, options);\n case 'webpack':\n return (stats: any) => unifyWebpackStats(stats);\n case 'rsbuild':\n return (stats: any) => unifyRsbuildStats(stats);\n case 'vite':\n return (stats: any) => unifyViteStats(stats);\n case 'sonda':\n return (stats: any, options: any = {}) => unifySondaStats(stats, options);\n default:\n throw new Error(`Unsupported bundler: ${bundler}`);\n }\n}\n\n/**\n * Merges dependency tree configurations from audit and plugin levels.\n * Groups merge (global + local), pruning overwrites (local takes precedence).\n */\nexport function mergeDependencyTreeConfig(\n auditConfig: DependencyTreeConfig | undefined,\n pluginOptions: PluginDependencyTreeOptions | undefined,\n): DependencyTreeConfig | undefined {\n // Only hide if audit config explicitly disables\n if (auditConfig?.enabled === false) {\n return undefined;\n }\n\n // If global options exist, always show them (unless disabled above)\n if (pluginOptions) {\n return {\n // Groups logic: false = hide, array = overwrite global, undefined = use global\n groups: (() => {\n // Only hide if explicitly set to false\n if (auditConfig?.groups === false) {\n return [];\n }\n // If audit defines groups, use them (overwrite global)\n if (auditConfig?.groups !== undefined) {\n return auditConfig.groups as GroupingRule[];\n }\n // Otherwise, use global groups\n return pluginOptions?.groups ?? [];\n })(),\n // Pruning overwrites - local takes precedence over global\n pruning: {\n maxDepth: 2,\n maxChildren: 20,\n pathLength: 60,\n ...pluginOptions?.pruning,\n ...auditConfig?.pruning,\n },\n mode: auditConfig?.mode ?? 'onlyMatching',\n };\n }\n\n // If no global options but config exists, use config\n if (auditConfig) {\n return {\n // Groups fallback - use audit groups or empty array if false\n groups: auditConfig.groups === false ? [] : (auditConfig.groups ?? []),\n // Pruning fallback - use audit pruning with defaults\n pruning: {\n maxDepth: 2,\n maxChildren: 10,\n pathLength: 60,\n ...auditConfig?.pruning,\n },\n mode: auditConfig.mode ?? 'onlyMatching',\n };\n }\n\n return undefined;\n}\n\n/**\n * Merges selection configurations with hybrid strategy. Excludes merge for safety, includes overwrite for scope clarity.\n */\nexport function mergeSelectionConfig(\n auditConfig: SelectionConfig | undefined,\n pluginOptions?: PluginSelectionOptions,\n): SelectionConfig {\n return {\n // mode from audit config takes precedence\n mode: auditConfig?.mode == null ? 'bundle' : auditConfig.mode,\n\n // Include arrays overwrite - config takes precedence for scope clarity\n includeOutputs: auditConfig?.includeOutputs ?? [],\n includeInputs: auditConfig?.includeInputs ?? [],\n\n // Exclude arrays merge - merging exclusions is safe and expected\n excludeOutputs: [\n ...(pluginOptions?.excludeOutputs ?? []),\n ...(auditConfig?.excludeOutputs ?? []),\n ],\n excludeInputs: [\n ...(pluginOptions?.excludeInputs ?? []),\n ...(auditConfig?.excludeInputs ?? []),\n ],\n };\n}\n\n/**\n * Merges scoring configurations with hybrid strategy. Penalty blacklist merges to combine blocked patterns.\n */\nexport function mergeScoringConfig(\n auditConfig: BundleStatsConfig['scoring'] | undefined,\n pluginOptions: PluginScoringOptions | undefined,\n): BundleStatsConfig['scoring'] {\n if (auditConfig?.penalty === false) {\n return auditConfig;\n }\n\n if (!auditConfig) {\n return pluginOptions as BundleStatsConfig['scoring'];\n }\n\n const pluginPenalty = pluginOptions?.penalty;\n const normalizedPluginPenalty = pluginPenalty\n ? {\n ...pluginPenalty,\n artefactSize: pluginPenalty.artefactSize\n ? normalizeRange(pluginPenalty.artefactSize)\n : undefined,\n }\n : undefined;\n\n return {\n ...auditConfig,\n penalty: {\n ...DEFAULT_PENALTY,\n ...normalizedPluginPenalty,\n ...auditConfig?.penalty,\n // Blacklist merges - combine blocked patterns from both sources\n blacklist: [\n ...(normalizedPluginPenalty?.blacklist ?? []),\n ...(auditConfig?.penalty?.blacklist ?? []),\n ],\n },\n };\n}\n\n/**\n * Merges insights configurations with fallback strategy. Uses audit-level when defined, falls back to global when undefined, hides when false.\n */\nexport function mergeInsightsConfig(\n auditConfig: InsightsTableConfig | false | undefined,\n pluginOptions: InsightsTableConfig | false | undefined,\n): InsightsTableConfig | false | undefined {\n if (auditConfig === false) {\n return undefined;\n }\n\n // Insights override - audit-level completely replaces plugin-level when defined\n if (auditConfig !== undefined) {\n return auditConfig;\n }\n\n // Handle false plugin options\n if (pluginOptions === false) {\n return undefined;\n }\n\n return pluginOptions;\n}\n\n/**\n * Creates a bundle stats audit runner that processes bundler output and generates audit results.\n * Supports multiple bundlers (esbuild, webpack, rsbuild) with dynamic module loading.\n */\nexport async function bundleStatsRunner(\n opts: BundleStatsRunnerConfig,\n): Promise<() => Promise> {\n const {\n artifactsPaths,\n generateArtifactsCommand,\n bundleStatsConfigs,\n bundler,\n } = opts;\n\n return async () => {\n if (artifactsPaths && generateArtifactsCommand) {\n const { command, args } =\n typeof generateArtifactsCommand === 'string'\n ? { command: generateArtifactsCommand, args: undefined }\n : generateArtifactsCommand;\n try {\n await executeProcess({\n command,\n args,\n });\n } catch (error) {\n throw new Error(\n `Failed to generate artefacts for plugin bundle-stats. command: ${command} args: ${args} error: ${error}`,\n );\n }\n }\n\n if (Array.isArray(artifactsPaths)) {\n throw new TypeError(\n 'The bundle stats plugin does not support multiple artifact paths. Request feature on GitHub.',\n );\n }\n\n const stats = await readJsonFile(artifactsPaths);\n // @TODO implement zod schema\n validateBundleStats(stats, artifactsPaths, bundler);\n\n const unifyBundlerStats = getUnifyFunction(bundler);\n const unifiedBundleStats = unifyBundlerStats(stats, {});\n\n return generateAuditOutputs(unifiedBundleStats, bundleStatsConfigs);\n };\n}\n\nexport function mergeAuditConfigs(\n configs: BundleStatsConfig[],\n options: {\n dependencyTree?: PluginDependencyTreeOptions;\n selection?: PluginSelectionOptions;\n scoring?: PluginScoringOptions;\n insightsTable?: PluginInsightsTableOptions;\n },\n): BundleStatsConfig[] {\n return configs.map(config => {\n const { insightsTable: configInsights, ...configWithoutInsights } = config;\n\n return {\n ...configWithoutInsights,\n dependencyTree: mergeDependencyTreeConfig(\n config.dependencyTree,\n options.dependencyTree,\n ),\n selection: mergeSelectionConfig(config.selection, options.selection),\n scoring: mergeScoringConfig(config.scoring, options.scoring),\n ...(configInsights === false\n ? {}\n : {\n insightsTable: mergeInsightsConfig(\n configInsights,\n options.insightsTable,\n ),\n }),\n };\n });\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/bundle-stats-runner.unit.test.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'vi' is defined but never used.", - "line": 1, - "column": 32, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 1, - "endColumn": 34 - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it, vi } from 'vitest';\nimport type { PluginSelectionOptions } from '../types.js';\nimport type { PenaltyConfig } from './audits/scoring.js';\nimport type { SelectionConfig } from './audits/selection.js';\nimport {\n mergeAuditConfigs,\n mergeDependencyTreeConfig,\n mergeInsightsConfig,\n mergeScoringConfig,\n mergeSelectionConfig,\n} from './bundle-stats-runner.js';\nimport type { GroupingRule } from './types.js';\n\nconst testScoring = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: { warningWeight: 0.1, errorWeight: 0.2 } as PenaltyConfig,\n};\nconst emptySelection: SelectionConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n};\n\ndescribe('mergeDependencyTreeConfig', () => {\n it('should return undefined when both global and config are undefined', () => {\n expect(mergeDependencyTreeConfig(undefined, undefined)).toBeUndefined();\n });\n\n it('should use config when global is undefined', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n const result = mergeDependencyTreeConfig(auditConfig, undefined);\n\n expect(result?.groups).toHaveLength(1);\n expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject(\n { includeInputs: ['**/*.ts'] },\n );\n });\n\n it('should return undefined when config.enabled is false', () => {\n const auditConfig = { enabled: false, groups: [] };\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n expect(\n mergeDependencyTreeConfig(auditConfig, pluginOptions),\n ).toBeUndefined();\n });\n\n it('should merge when global options provided and config undefined', () => {\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n const result = mergeDependencyTreeConfig(undefined, pluginOptions);\n\n expect(result?.groups).toHaveLength(1);\n expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject(\n { includeInputs: ['**/*.js'] },\n );\n });\n\n it('should merge when both global and config options provided', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n const result = mergeDependencyTreeConfig(auditConfig, pluginOptions);\n\n expect(result?.groups).toHaveLength(1);\n expect(Array.isArray(result?.groups) ? result.groups[0] : {}).toMatchObject(\n { includeInputs: ['**/*.ts'] },\n );\n });\n\n it('should overwrite pruning options (config takes precedence)', () => {\n const auditConfig = { pruning: { maxDepth: 5 } };\n const pluginOptions = { pruning: { maxDepth: 3 } };\n const result = mergeDependencyTreeConfig(auditConfig, pluginOptions);\n\n expect(result?.pruning?.maxDepth).toBe(5);\n });\n\n it('should provide DEFAULT pruning options when no options provided', () => {\n const auditConfig = { groups: [] };\n const result = mergeDependencyTreeConfig(auditConfig, undefined);\n\n expect(result?.pruning).toBeDefined();\n });\n});\n\ndescribe('mergeSelectionConfig', () => {\n it('should merge plugin and audit selection patterns', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: ['main.js'],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: [],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result).toMatchObject({\n includeOutputs: ['main.js'],\n excludeOutputs: ['*.map'],\n });\n });\n\n it('should handle empty plugin options', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: [],\n excludeOutputs: ['dev.js'],\n includeInputs: [],\n excludeInputs: [],\n };\n const result = mergeSelectionConfig(auditConfig);\n\n expect(result).toMatchObject({\n excludeOutputs: ['dev.js'],\n });\n });\n\n it('should merge multiple arrays correctly', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: ['main.js'],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: ['temp.js'],\n };\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: ['test/**'],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result).toMatchObject({\n includeOutputs: ['main.js'],\n excludeOutputs: ['*.map'],\n excludeInputs: ['test/**', 'temp.js'],\n });\n });\n\n it('should handle undefined config selection', () => {\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: [],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(undefined, pluginOptions);\n\n expect(result).toMatchObject({\n includeOutputs: [],\n excludeOutputs: ['*.map'],\n });\n });\n\n it('should handle empty exclude arrays', () => {\n const auditConfig = {\n mode: 'matchingOnly' as const,\n includeOutputs: [],\n excludeOutputs: [],\n includeInputs: [],\n excludeInputs: [],\n };\n const pluginOptions = {\n excludeOutputs: [],\n excludeInputs: [],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result).toMatchObject(emptySelection);\n });\n\n it('should merge exclude patterns correctly', () => {\n const auditConfig = emptySelection;\n const pluginOptions = {\n excludeOutputs: ['*.map'],\n excludeInputs: ['*.test.js'],\n } as PluginSelectionOptions;\n const result = mergeSelectionConfig(auditConfig, pluginOptions);\n\n expect(result.excludeOutputs).toStrictEqual(['*.map']);\n expect(result.excludeInputs).toStrictEqual(['*.test.js']);\n });\n});\n\ndescribe('mergeScoringConfig', () => {\n it('should return config when config.penalty is false', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: false as const,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n } as PenaltyConfig,\n };\n\n expect(mergeScoringConfig(auditConfig, pluginOptions)).toStrictEqual({\n mode: 'onlyMatching',\n totalSize: [0, 1000],\n penalty: false,\n });\n });\n\n it('should return options when config is undefined', () => {\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n } as PenaltyConfig,\n };\n\n expect(mergeScoringConfig(undefined, pluginOptions)).toStrictEqual(\n pluginOptions,\n );\n });\n\n it('should merge when both config and options provided', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 3,\n } as PenaltyConfig,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n threshold: 100,\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, pluginOptions);\n\n expect(result?.penalty).toMatchObject({ factor: 3, threshold: 100 });\n });\n\n it('should merge penalty blacklists from both sources', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n blacklist: ['config-pattern'],\n } as PenaltyConfig,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n blacklist: ['global-pattern'],\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, pluginOptions);\n\n expect((result?.penalty as any)?.blacklist).toStrictEqual([\n 'global-pattern',\n 'config-pattern',\n ]);\n });\n\n it('should overwrite other penalty properties (config takes precedence)', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 3,\n threshold: 500,\n } as PenaltyConfig,\n };\n const pluginOptions = {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n threshold: 100,\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, pluginOptions);\n\n expect((result?.penalty as any)?.factor).toBe(3);\n expect((result?.penalty as any)?.threshold).toBe(500);\n });\n\n it('should handle undefined global scoring', () => {\n const auditConfig = {\n mode: 'onlyMatching' as const,\n totalSize: [0, 1000] as [number, number],\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 2,\n } as PenaltyConfig,\n };\n const result = mergeScoringConfig(auditConfig, undefined);\n\n expect((result?.penalty as any)?.factor).toBe(2);\n });\n});\n\ndescribe('mergeInsightsConfig', () => {\n it('should return undefined when config is false', () => {\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n expect(mergeInsightsConfig(false, pluginOptions)).toBeUndefined();\n });\n\n it('should merge arrays when both global and config provided', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n // Function overrides (doesn't merge) - auditConfig takes precedence\n const result = mergeInsightsConfig(auditConfig, pluginOptions);\n expect(\n result && typeof result === 'object' && 'groups' in result\n ? result.groups\n : [],\n ).toHaveLength(1);\n expect(\n result && typeof result === 'object' && 'groups' in result\n ? result.groups?.[0]\n : {},\n ).toMatchObject({ includeInputs: ['**/*.ts'] });\n });\n\n it('should use global when config is undefined', () => {\n const pluginOptions = {\n groups: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n };\n\n expect(mergeInsightsConfig(undefined, pluginOptions)).toStrictEqual({\n groups: [{ includeInputs: ['**/*.js'], title: 'JavaScript' }],\n });\n });\n\n it('should use config when global is undefined', () => {\n const auditConfig = {\n groups: [\n { includeInputs: ['**/*.ts'], title: 'TypeScript' } as GroupingRule,\n ],\n };\n\n expect(mergeInsightsConfig(auditConfig, undefined)).toStrictEqual({\n groups: [{ includeInputs: ['**/*.ts'], title: 'TypeScript' }],\n });\n });\n\n it('should return undefined when both are undefined', () => {\n expect(mergeInsightsConfig(undefined, undefined)).toBeUndefined();\n });\n\n it('should handle false in both global and config', () => {\n expect(mergeInsightsConfig(false, false)).toBeUndefined();\n });\n});\n\ndescribe('mergeAuditConfigs', () => {\n it('should return empty array when given empty configs', () => {\n expect(mergeAuditConfigs([], {})).toStrictEqual([]);\n });\n\n it('should map over multiple configs correctly', () => {\n const configs = [\n {\n slug: 'audit-1',\n title: 'First',\n selection: emptySelection,\n scoring: testScoring,\n },\n {\n slug: 'audit-2',\n title: 'Second',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result).toHaveLength(2);\n expect(result[0]?.slug).toBe('audit-1');\n expect(result[1]?.slug).toBe('audit-2');\n });\n\n it('should set selection property correctly', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const options = {\n selection: { excludeOutputs: ['*.test.js'] } as PluginSelectionOptions,\n };\n const result = mergeAuditConfigs(configs, options);\n\n expect(result[0]?.selection).toBeDefined();\n expect(result[0]?.selection.excludeOutputs).toStrictEqual(['*.test.js']);\n });\n\n it('should set scoring property correctly', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const options = {\n scoring: {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n } satisfies PenaltyConfig,\n },\n };\n const result = mergeAuditConfigs(configs, options);\n\n expect(result[0]?.scoring).toBeDefined();\n });\n\n it('should include insightsTable when config.insightsTable is not false', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n insightsTable: [\n { includeInputs: ['**/*.js'], title: 'JavaScript' } as GroupingRule,\n ],\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result[0]).toHaveProperty('insightsTable');\n expect(result[0]?.insightsTable).toHaveLength(1);\n });\n\n it('should exclude insightsTable when config.insightsTable is false', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n insightsTable: false,\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result[0]).not.toHaveProperty('insightsTable');\n });\n\n it('should handle empty options object', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const result = mergeAuditConfigs(configs, {});\n\n expect(result[0]).toMatchObject({\n slug: 'test',\n selection: {\n mode: 'matchingOnly',\n includeOutputs: [],\n includeInputs: [],\n excludeOutputs: [],\n excludeInputs: [],\n },\n });\n expect((result[0] as any).artefactTree).toBeUndefined();\n });\n\n it('should handle partial options object', () => {\n const configs = [\n {\n slug: 'test',\n title: 'Test',\n selection: emptySelection,\n scoring: testScoring,\n },\n ] as any;\n const options = {\n scoring: {\n penalty: {\n warningWeight: 0.1,\n errorWeight: 0.2,\n factor: 1.5,\n } as PenaltyConfig,\n },\n };\n const result = mergeAuditConfigs(configs, options);\n\n expect(result[0]).toMatchObject({\n slug: 'test',\n scoring: expect.any(Object),\n });\n expect((result[0] as any).artefactTree).toBeUndefined();\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/constants.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/types.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unified-stats.types.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.ts", - "messages": [ - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'unifyBundlerStats' has too many lines (68). Maximum allowed is 50.", - "line": 56, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 140, - "endColumn": 2 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 65, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 137, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 66, - "column": 24, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 66, - "endColumn": 34 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 92, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 92, - "endColumn": 44 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 95, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 108, - "endColumn": 11 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 103, - "column": 13, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 103, - "endColumn": 50 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying properties of existing object not allowed.", - "line": 110, - "column": 5, - "nodeType": "CallExpression", - "messageId": "object", - "endLine": 110, - "endColumn": 50 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 117, - "column": 9, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 126, - "endColumn": 10 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 118, - "column": 29, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 118, - "endColumn": 38 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", - "line": 121, - "column": 11, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 125, - "endColumn": 12 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 122, - "column": 13, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 124, - "endColumn": 14 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 128, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 128, - "endColumn": 38 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 130, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 130, - "endColumn": 34 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 133, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 133, - "endColumn": 32 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 136, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 136, - "endColumn": 39 - } - ], - "suppressedMessages": [], - "errorCount": 11, - "fatalErrorCount": 0, - "warningCount": 4, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { minimatch } from 'minimatch';\nimport type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type EsBuildImportKind = 'import-statement' | 'dynamic-import';\n\nexport type EsBuildInputImport = {\n path: string;\n kind: EsBuildImportKind;\n original: string;\n};\n\nexport type EsBuildOutputImport = {\n path: string;\n kind: EsBuildImportKind;\n external?: boolean;\n original?: string;\n};\n\nexport type EsBuildInput = {\n bytes: number;\n imports: EsBuildInputImport[];\n format?: string;\n};\n\nexport type EsBuildOutput = {\n bytes: number;\n inputs?: Record;\n entryPoint?: string;\n imports?: EsBuildOutputImport[];\n exports?: string[];\n};\n\nexport type EsBuildCoreStats = {\n outputs: Record;\n inputs: Record;\n};\n\nexport type EsBuildUnifyOptions = {\n excludeOutputs?: string[];\n};\n\n/**\n * Checks if path matches any exclude pattern. Filters unwanted files from bundle stats.\n */\nfunction shouldExcludeOutput(\n outputPath: string,\n excludePatterns: string[],\n): boolean {\n return excludePatterns.some(pattern => minimatch(outputPath, pattern));\n}\n\nexport function unifyBundlerStats(\n stats: EsBuildCoreStats,\n options: EsBuildUnifyOptions,\n): UnifiedStats {\n const { excludeOutputs = ['**/*.map', '**/*.d.ts'] } = options;\n\n const outputKeys = Object.keys(stats.outputs);\n const result: UnifiedStats = {};\n\n for (const outputKey of outputKeys) {\n const outputName = outputKey!;\n const outputInfo = stats.outputs[outputName];\n if (!outputInfo) {\n continue;\n }\n\n // Skip outputs that match exclude patterns\n if (shouldExcludeOutput(outputName, excludeOutputs)) {\n continue;\n }\n\n const {\n bytes,\n entryPoint,\n imports,\n exports,\n inputs: outputInputs,\n ...additionalProps\n } = outputInfo;\n\n const unifiedOutput: UnifiedStatsBundle = {\n path: outputName,\n bytes,\n };\n\n if (entryPoint !== undefined) {\n unifiedOutput.entryPoint = entryPoint;\n }\n\n unifiedOutput.imports = imports\n ? imports.map(imp => {\n const unifiedImport: UnifiedStatsImport = {\n path: imp.path,\n kind: imp.kind,\n };\n\n if ('original' in imp && typeof imp.original === 'string') {\n unifiedImport.original = imp.original;\n }\n\n return unifiedImport;\n })\n : [];\n\n Object.assign(unifiedOutput, additionalProps);\n\n if (outputInputs) {\n const inputKeys = Object.keys(outputInputs);\n if (inputKeys.length > 0) {\n const inputs: Record = {};\n\n for (const inputKey of inputKeys) {\n const inputPath = inputKey!;\n const outputInputInfo = outputInputs[inputPath];\n\n if (outputInputInfo?.bytesInOutput !== undefined) {\n inputs[inputPath] = {\n bytes: outputInputInfo.bytesInOutput,\n };\n }\n }\n\n unifiedOutput.inputs = inputs;\n } else {\n unifiedOutput.inputs = {};\n }\n } else {\n unifiedOutput.inputs = {};\n }\n\n result[outputName] = unifiedOutput;\n }\n\n return result;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.esbuild.unit.test.ts", - "messages": [ - { - "ruleId": "no-duplicate-imports", - "severity": 1, - "message": "'./unify.esbuild.js' import is duplicated.", - "line": 3, - "column": 1, - "nodeType": "ImportDeclaration", - "messageId": "import", - "endLine": 3, - "endColumn": 60 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 1, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it } from 'vitest';\nimport { unifyBundlerStats } from './unify.esbuild.js';\nimport type { EsBuildCoreStats } from './unify.esbuild.js';\n\ndescribe('unifyBundlerStats', () => {\n it('should only consider outputs and provide default values', () => {\n const esbuildStats: EsBuildCoreStats = {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n },\n },\n };\n expect(unifyBundlerStats(esbuildStats, {})).toStrictEqual({\n 'dist/index.js': {\n path: 'dist/index.js',\n bytes: 100,\n imports: [],\n inputs: {},\n },\n });\n });\n\n it('should parse inputs correctly', () => {\n expect(\n unifyBundlerStats(\n {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n inputs: {\n 'src/index.ts': {\n bytesInOutput: 100,\n },\n },\n },\n },\n },\n {},\n ),\n ).toStrictEqual({\n 'dist/index.js': expect.objectContaining({\n inputs: {\n 'src/index.ts': {\n bytes: 100,\n },\n },\n }),\n });\n });\n\n it('should parse imports correctly', () => {\n expect(\n unifyBundlerStats(\n {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n },\n },\n },\n {},\n ),\n ).toStrictEqual({\n 'dist/index.js': expect.objectContaining({\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n }),\n });\n });\n\n it('should preserve original import paths when present', () => {\n expect(\n unifyBundlerStats(\n {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n bytes: 100,\n imports: [\n {\n path: 'node_modules/rxjs/dist/esm/internal/util/isFunction.js',\n kind: 'import-statement',\n original: './util/isFunction',\n },\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n },\n },\n },\n {},\n ),\n ).toStrictEqual({\n 'dist/index.js': expect.objectContaining({\n imports: [\n {\n path: 'node_modules/rxjs/dist/esm/internal/util/isFunction.js',\n kind: 'import-statement',\n original: './util/isFunction',\n },\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n }),\n });\n });\n\n it('should unify esbuild stats into unified stats structure', () => {\n const esbuildStats: EsBuildCoreStats = {\n inputs: {},\n outputs: {\n 'dist/index.js': {\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n {\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n kind: 'dynamic-import',\n },\n ],\n exports: ['default', 'indexOnlyFunction'],\n entryPoint: 'src/index.ts',\n inputs: {\n 'src/index.ts': {\n bytesInOutput: 350,\n },\n },\n bytes: 496,\n },\n 'dist/bin.js': {\n imports: [\n {\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n kind: 'import-statement',\n },\n ],\n exports: [],\n entryPoint: 'src/bin.ts',\n inputs: {\n 'src/bin.ts': {\n bytesInOutput: 366,\n },\n },\n bytes: 479,\n },\n 'dist/chunks/chunk-WIJM4GGD.js': {\n imports: [],\n exports: ['calculate', 'externalFunction'],\n inputs: {\n 'src/lib/utils/format.ts': {\n bytesInOutput: 269,\n },\n 'src/lib/feature-1.ts': {\n bytesInOutput: 269,\n },\n 'src/lib/utils/math.ts': {\n bytesInOutput: 145,\n },\n },\n bytes: 806,\n },\n 'dist/chunks/feature-2-X2YVDBQK.js': {\n imports: [],\n exports: ['chart'],\n entryPoint: 'src/lib/feature-2.ts',\n inputs: {\n 'src/lib/feature-2.ts': {\n bytesInOutput: 38,\n },\n },\n bytes: 82,\n },\n },\n };\n\n expect(unifyBundlerStats(esbuildStats, {})).toStrictEqual({\n 'dist/bin.js': {\n bytes: 479,\n entryPoint: 'src/bin.ts',\n imports: [\n {\n kind: 'import-statement',\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n },\n ],\n inputs: {\n 'src/bin.ts': {\n bytes: 366,\n },\n },\n path: 'dist/bin.js',\n },\n 'dist/chunks/chunk-WIJM4GGD.js': {\n bytes: 806,\n imports: [],\n inputs: {\n 'src/lib/feature-1.ts': {\n bytes: 269,\n },\n 'src/lib/utils/format.ts': {\n bytes: 269,\n },\n 'src/lib/utils/math.ts': {\n bytes: 145,\n },\n },\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n },\n 'dist/chunks/feature-2-X2YVDBQK.js': {\n bytes: 82,\n entryPoint: 'src/lib/feature-2.ts',\n imports: [],\n inputs: {\n 'src/lib/feature-2.ts': {\n bytes: 38,\n },\n },\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n },\n 'dist/index.js': {\n bytes: 496,\n entryPoint: 'src/index.ts',\n imports: [\n {\n kind: 'import-statement',\n path: 'dist/chunks/chunk-WIJM4GGD.js',\n },\n {\n kind: 'dynamic-import',\n path: 'dist/chunks/feature-2-X2YVDBQK.js',\n },\n ],\n inputs: {\n 'src/index.ts': {\n bytes: 350,\n },\n },\n path: 'dist/index.js',\n },\n });\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'UnifiedStatsImport' is defined but never used.", - "line": 4, - "column": 3, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 4, - "endColumn": 21 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'unifyBundlerStats' has too many lines (92). Maximum allowed is 50.", - "line": 139, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 242, - "endColumn": 2 - }, - { - "ruleId": "complexity", - "severity": 1, - "message": "Function 'unifyBundlerStats' has a complexity of 23. Maximum allowed is 20.", - "line": 139, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "complex", - "endLine": 242, - "endColumn": 2 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 143, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 145, - "endColumn": 4 - }, - { - "ruleId": "sonarjs/no-unused-collection", - "severity": 2, - "message": "Either use this collection's contents or remove the collection.", - "line": 147, - "column": 9, - "nodeType": "Identifier", - "messageId": "unusedCollection", - "endLine": 147, - "endColumn": 19 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 148, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 150, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 152, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 239, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 164, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 183, - "endColumn": 6 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'entryName' is assigned a value but never used. Allowed unused elements of array destructuring must match /^_/u.", - "line": 164, - "column": 17, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 164, - "endColumn": 26 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 169, - "column": 9, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 180, - "endColumn": 10 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", - "line": 171, - "column": 11, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 179, - "endColumn": 12 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", - "line": 175, - "column": 13, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 178, - "endColumn": 14 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 176, - "column": 15, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 176, - "endColumn": 58 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 185, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 224, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 191, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 223, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 197, - "column": 11, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 199, - "endColumn": 12 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 202, - "column": 9, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 222, - "endColumn": 10 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", - "line": 203, - "column": 11, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 221, - "endColumn": 12 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", - "line": 204, - "column": 13, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 210, - "endColumn": 14 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 205, - "column": 15, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 209, - "endColumn": 17 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 216, - "column": 13, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 220, - "endColumn": 15 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 235, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 235, - "endColumn": 44 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 238, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 238, - "endColumn": 39 - } - ], - "suppressedMessages": [], - "errorCount": 9, - "fatalErrorCount": 0, - "warningCount": 14, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type RsbuildImportKind = 'import-statement' | 'dynamic-import';\n\nexport type RsbuildReason = {\n moduleIdentifier: string | null;\n module: string | null;\n moduleName: string | null;\n type: string;\n userRequest: string;\n loc: string;\n active: boolean;\n moduleId: string | null;\n resolvedModuleId: string | null;\n};\n\nexport type RsbuildAsset = {\n type: string;\n name: string;\n size: number;\n emitted: boolean;\n cached: boolean;\n chunkNames: string[];\n chunkIdHints: string[];\n chunks: string[];\n auxiliaryChunks: string[];\n};\n\nexport type RsbuildModule = {\n type: string;\n moduleType: string;\n size: number;\n sizes: Record;\n built: boolean;\n codeGenerated: boolean;\n buildTimeExecuted: boolean;\n cached: boolean;\n identifier: string;\n name: string;\n nameForCondition?: string;\n index: number;\n preOrderIndex: number;\n index2: number;\n postOrderIndex: number;\n cacheable: boolean;\n optional: boolean;\n orphan: boolean;\n dependent?: boolean;\n issuer?: string | null;\n issuerName?: string | null;\n issuerPath?: {\n identifier: string;\n name: string;\n id: string;\n }[];\n failed: boolean;\n errors: number;\n warnings: number;\n id: string;\n issuerId?: string;\n chunks: string[];\n assets: string[];\n reasons: RsbuildReason[];\n usedExports: string[] | null;\n providedExports?: string[];\n optimizationBailout: string[];\n depth: number;\n};\n\nexport type RsbuildChunk = {\n type: string;\n rendered: boolean;\n initial: boolean;\n entry: boolean;\n reason?: string;\n size: number;\n sizes: Record;\n names: string[];\n idHints: string[];\n runtime: string[];\n files: string[];\n auxiliaryFiles: string[];\n hash: string;\n childrenByOrder: Record;\n id: string;\n siblings: string[];\n parents: string[];\n children: string[];\n modules: RsbuildModule[];\n origins: {\n module: string;\n moduleIdentifier: string;\n moduleName: string;\n loc: string;\n request: string;\n moduleId: string;\n }[];\n};\n\nexport type RsbuildEntrypoint = {\n name: string;\n chunks: string[];\n assets: { name: string; size: number }[];\n filteredAssets: number;\n assetsSize: number;\n auxiliaryAssets: { name: string; size: number }[];\n auxiliaryAssetsSize: number;\n children: Record;\n childAssets: Record;\n isOverSizeLimit: boolean;\n};\n\nexport type RsbuildCoreStats = {\n name: string;\n hash: string;\n version: string;\n rspackVersion: string;\n time: number;\n builtAt: number;\n publicPath: string;\n outputPath: string;\n assetsByChunkName: Record;\n assets: RsbuildAsset[];\n chunks: RsbuildChunk[];\n modules: RsbuildModule[];\n entrypoints: Record;\n namedChunkGroups: Record;\n errors: unknown[];\n errorsCount: number;\n warnings: unknown[];\n warningsCount: number;\n children: unknown[];\n};\n\nexport function unifyBundlerStats(stats: RsbuildCoreStats): UnifiedStats {\n const result: UnifiedStats = {};\n\n const chunksMap = new Map();\n for (const chunk of stats.chunks) {\n chunksMap.set(chunk.id, chunk);\n }\n\n const modulesMap = new Map();\n for (const module of stats.modules) {\n modulesMap.set(module.identifier, module);\n }\n\n for (const asset of stats.assets) {\n if (!asset.name.endsWith('.js')) {\n continue;\n }\n\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.size,\n imports: [],\n inputs: {},\n };\n\n for (const [entryName, entrypoint] of Object.entries(stats.entrypoints)) {\n if (\n entrypoint.assets.some(entryAsset => entryAsset.name === asset.name)\n ) {\n const entryChunks = entrypoint.chunks;\n for (const chunkId of entryChunks) {\n const chunk = chunksMap.get(chunkId);\n if (chunk?.entry) {\n const entryModule = chunk.modules.find(module =>\n module.reasons.some(reason => reason.type === 'entry'),\n );\n if (entryModule) {\n unifiedOutput.entryPoint = entryModule.name;\n break;\n }\n }\n }\n break;\n }\n }\n\n for (const chunkId of asset.chunks) {\n const chunk = chunksMap.get(chunkId);\n if (!chunk) {\n continue;\n }\n\n for (const module of chunk.modules) {\n if (module.moduleType === 'runtime') {\n continue;\n }\n\n if (unifiedOutput.inputs) {\n unifiedOutput.inputs[module.name] = {\n bytes: module.size,\n };\n }\n\n for (const reason of module.reasons) {\n if (reason.type === 'import()') {\n if (unifiedOutput.imports) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'dynamic-import',\n original: reason.userRequest,\n });\n }\n } else if (\n (reason.type === 'esm import' ||\n reason.type === 'esm import specifier') &&\n unifiedOutput.imports\n ) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'import-statement',\n original: reason.userRequest,\n });\n }\n }\n }\n }\n\n if (unifiedOutput.imports) {\n const uniqueImports = unifiedOutput.imports.filter(\n (importItem, index, self) =>\n index ===\n self.findIndex(\n item =>\n item.path === importItem.path && item.kind === importItem.kind,\n ),\n );\n unifiedOutput.imports = uniqueImports;\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.rsbuild.unit.test.ts", - "messages": [ - { - "ruleId": "no-duplicate-imports", - "severity": 1, - "message": "'./unify.rsbuild.js' import is duplicated.", - "line": 3, - "column": 1, - "nodeType": "ImportDeclaration", - "messageId": "import", - "endLine": 3, - "endColumn": 60 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 1, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it } from 'vitest';\nimport { unifyBundlerStats } from './unify.rsbuild.js';\nimport type { RsbuildCoreStats } from './unify.rsbuild.js';\n\ndescribe('unifyBundlerStats', () => {\n it('should transform realistic rsbuild stats with multiple assets, chunks, and complex module dependencies', () => {\n const rsbuildStats: RsbuildCoreStats = {\n name: 'web',\n hash: 'f7f35d6bcb429212',\n version: '5.75.0',\n rspackVersion: '1.4.6',\n time: 18,\n builtAt: 1_752_462_348_764,\n publicPath: '/',\n outputPath: '/dist/rsbuild',\n assetsByChunkName: {\n index: ['static/js/index.js'],\n },\n assets: [\n {\n type: 'asset',\n name: 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js',\n size: 79_545,\n emitted: true,\n cached: false,\n chunkNames: [],\n chunkIdHints: ['vendors'],\n chunks: ['vendors-node_modules_minimatch_dist_esm_index_js'],\n auxiliaryChunks: [],\n },\n {\n type: 'asset',\n name: 'static/js/index.js',\n size: 38_142,\n emitted: true,\n cached: false,\n chunkNames: ['index'],\n chunkIdHints: [],\n chunks: ['index'],\n auxiliaryChunks: [],\n },\n {\n type: 'asset',\n name: 'static/js/async/src_lib_feature-2_ts.js',\n size: 708,\n emitted: true,\n cached: false,\n chunkNames: [],\n chunkIdHints: [],\n chunks: ['src_lib_feature-2_ts'],\n auxiliaryChunks: [],\n },\n {\n type: 'asset',\n name: 'index.html',\n size: 242,\n emitted: true,\n cached: false,\n chunkNames: [],\n chunkIdHints: [],\n chunks: [],\n auxiliaryChunks: [],\n },\n ],\n chunks: [\n {\n type: 'chunk',\n rendered: true,\n initial: true,\n entry: true,\n size: 1384,\n sizes: {\n javascript: 1384,\n runtime: 32_421,\n },\n names: ['index'],\n idHints: [],\n runtime: ['index'],\n files: ['static/js/index.js'],\n auxiliaryFiles: ['static/js/index.js.map'],\n hash: '9529fef35c1c4eed',\n childrenByOrder: {},\n id: 'index',\n siblings: [],\n parents: [],\n children: [\n 'src_lib_feature-2_ts',\n 'vendors-node_modules_minimatch_dist_esm_index_js',\n ],\n modules: [\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 461,\n sizes: {\n javascript: 461,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n name: './src/index.ts',\n nameForCondition: '/src/index.ts',\n index: 0,\n preOrderIndex: 0,\n index2: 3,\n postOrderIndex: 3,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: false,\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/index.ts',\n chunks: ['index'],\n assets: [],\n reasons: [\n {\n moduleIdentifier: null,\n module: null,\n moduleName: null,\n type: 'entry',\n userRequest: './src/index.ts',\n loc: 'index',\n active: true,\n moduleId: null,\n resolvedModuleId: null,\n },\n ],\n usedExports: null,\n providedExports: ['default', 'indexOnlyFunction'],\n optimizationBailout: [],\n depth: 0,\n },\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 376,\n sizes: {\n javascript: 376,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-1.ts',\n name: './src/lib/feature-1.ts',\n nameForCondition: '/src/lib/feature-1.ts',\n index: 1,\n preOrderIndex: 1,\n index2: 1,\n postOrderIndex: 1,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: true,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n issuerName: './src/index.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/lib/feature-1.ts',\n issuerId: './src/index.ts',\n chunks: ['index'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import',\n userRequest: './lib/feature-1',\n loc: '1:0-51',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import specifier',\n userRequest: './lib/feature-1',\n loc: '6:79-95',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n ],\n usedExports: null,\n providedExports: ['default', 'externalFunction'],\n optimizationBailout: [],\n depth: 1,\n },\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 172,\n sizes: {\n javascript: 172,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/utils/math.ts',\n name: './src/lib/utils/math.ts',\n nameForCondition: '/src/lib/utils/math.ts',\n index: 3,\n preOrderIndex: 3,\n index2: 2,\n postOrderIndex: 2,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: true,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n issuerName: './src/index.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/lib/utils/math.ts',\n issuerId: './src/index.ts',\n chunks: ['index'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import',\n userRequest: './lib/utils/math',\n loc: '2:0-45',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'esm import specifier',\n userRequest: './lib/utils/math',\n loc: '6:30-39',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n ],\n usedExports: null,\n providedExports: ['add', 'calculate', 'multiply'],\n optimizationBailout: [],\n depth: 1,\n },\n ],\n origins: [\n {\n module: '',\n moduleIdentifier: '',\n moduleName: '',\n loc: 'index',\n request: './src/index.ts',\n moduleId: 'index',\n },\n ],\n },\n {\n type: 'chunk',\n rendered: true,\n initial: false,\n entry: false,\n size: 147,\n sizes: {\n javascript: 147,\n },\n names: [],\n idHints: [],\n runtime: ['index'],\n files: ['static/js/async/src_lib_feature-2_ts.js'],\n auxiliaryFiles: ['static/js/async/src_lib_feature-2_ts.js.map'],\n hash: '30813a925289ba1f',\n childrenByOrder: {},\n id: 'src_lib_feature-2_ts',\n siblings: ['vendors-node_modules_minimatch_dist_esm_index_js'],\n parents: ['index'],\n children: [],\n modules: [\n {\n type: 'module',\n moduleType: 'javascript/auto',\n size: 147,\n sizes: {\n javascript: 147,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n name: './src/lib/feature-2.ts',\n nameForCondition: '/src/lib/feature-2.ts',\n index: 4,\n preOrderIndex: 4,\n index2: 12,\n postOrderIndex: 12,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: false,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n issuerName: './src/index.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: './src/lib/feature-2.ts',\n issuerId: './src/index.ts',\n chunks: ['src_lib_feature-2_ts'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n module: './src/index.ts',\n moduleName: './src/index.ts',\n type: 'import()',\n userRequest: './lib/feature-2',\n loc: '4:28-53',\n active: true,\n moduleId: './src/index.ts',\n resolvedModuleId: './src/index.ts',\n },\n ],\n usedExports: null,\n providedExports: ['chart'],\n optimizationBailout: [],\n depth: 1,\n },\n ],\n origins: [\n {\n module:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleName: './src/index.ts',\n loc: '4:28-53',\n request: './lib/feature-2',\n moduleId: './src/index.ts',\n },\n ],\n },\n {\n type: 'chunk',\n rendered: true,\n initial: false,\n entry: false,\n reason: 'split chunk (cache group: defaultVendors)',\n size: 75_559,\n sizes: {\n javascript: 75_559,\n },\n names: [],\n idHints: ['vendors'],\n runtime: ['index'],\n files: [\n 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js',\n ],\n auxiliaryFiles: [\n 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js.map',\n ],\n hash: '204484fe4072555f',\n childrenByOrder: {},\n id: 'vendors-node_modules_minimatch_dist_esm_index_js',\n siblings: ['src_lib_feature-2_ts'],\n parents: ['index'],\n children: [],\n modules: [\n {\n type: 'module',\n moduleType: 'javascript/esm',\n size: 39_098,\n sizes: {\n javascript: 39_098,\n },\n built: true,\n codeGenerated: true,\n buildTimeExecuted: false,\n cached: false,\n identifier:\n 'javascript/esm|/node_modules/minimatch/dist/esm/index.js',\n name: '../../../../../node_modules/minimatch/dist/esm/index.js',\n nameForCondition: '/node_modules/minimatch/dist/esm/index.js',\n index: 5,\n preOrderIndex: 5,\n index2: 11,\n postOrderIndex: 11,\n cacheable: true,\n optional: false,\n orphan: false,\n dependent: false,\n issuer:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n issuerName: './src/lib/feature-2.ts',\n failed: false,\n errors: 0,\n warnings: 0,\n id: '../../../../../node_modules/minimatch/dist/esm/index.js',\n issuerId: './src/lib/feature-2.ts',\n chunks: ['vendors-node_modules_minimatch_dist_esm_index_js'],\n assets: [],\n reasons: [\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n module: './src/lib/feature-2.ts',\n moduleName: './src/lib/feature-2.ts',\n type: 'esm import',\n userRequest: 'minimatch',\n loc: '1:0-38',\n active: true,\n moduleId: './src/lib/feature-2.ts',\n resolvedModuleId: './src/lib/feature-2.ts',\n },\n {\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/lib/feature-2.ts',\n module: './src/lib/feature-2.ts',\n moduleName: './src/lib/feature-2.ts',\n type: 'esm import specifier',\n userRequest: 'minimatch',\n loc: '3:11-20',\n active: true,\n moduleId: './src/lib/feature-2.ts',\n resolvedModuleId: './src/lib/feature-2.ts',\n },\n ],\n usedExports: null,\n providedExports: [\n 'AST',\n 'GLOBSTAR',\n 'Minimatch',\n 'braceExpand',\n 'defaults',\n 'escape',\n 'filter',\n 'makeRe',\n 'match',\n 'minimatch',\n 'sep',\n 'unescape',\n ],\n optimizationBailout: [],\n depth: 2,\n },\n ],\n origins: [\n {\n module:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleIdentifier:\n 'builtin:swc-loader??ruleSet[1].rules[4].use[0]!/src/index.ts',\n moduleName: './src/index.ts',\n loc: '4:28-53',\n request: './lib/feature-2',\n moduleId: './src/index.ts',\n },\n ],\n },\n ],\n modules: [],\n entrypoints: {\n index: {\n name: 'index',\n chunks: ['index'],\n assets: [{ name: 'static/js/index.js', size: 38_142 }],\n filteredAssets: 0,\n assetsSize: 38_142,\n auxiliaryAssets: [{ name: 'static/js/index.js.map', size: 45_982 }],\n auxiliaryAssetsSize: 45_982,\n children: {},\n childAssets: {},\n isOverSizeLimit: false,\n },\n },\n namedChunkGroups: {\n index: {\n name: 'index',\n chunks: ['index'],\n assets: [{ name: 'static/js/index.js', size: 38_142 }],\n filteredAssets: 0,\n assetsSize: 38_142,\n auxiliaryAssets: [{ name: 'static/js/index.js.map', size: 45_982 }],\n auxiliaryAssetsSize: 45_982,\n children: {},\n childAssets: {},\n isOverSizeLimit: false,\n },\n },\n errors: [],\n errorsCount: 0,\n warnings: [],\n warningsCount: 0,\n children: [],\n };\n\n const result = unifyBundlerStats(rsbuildStats);\n\n expect(result).toEqual({\n 'static/js/index.js': {\n path: 'static/js/index.js',\n bytes: 38_142,\n imports: [\n {\n path: './lib/feature-1',\n kind: 'import-statement',\n original: './lib/feature-1',\n },\n {\n path: './lib/utils/math',\n kind: 'import-statement',\n original: './lib/utils/math',\n },\n ],\n inputs: {\n './src/index.ts': {\n bytes: 461,\n },\n './src/lib/feature-1.ts': {\n bytes: 376,\n },\n './src/lib/utils/math.ts': {\n bytes: 172,\n },\n },\n entryPoint: './src/index.ts',\n },\n 'static/js/async/src_lib_feature-2_ts.js': {\n path: 'static/js/async/src_lib_feature-2_ts.js',\n bytes: 708,\n imports: [\n {\n path: './lib/feature-2',\n kind: 'dynamic-import',\n original: './lib/feature-2',\n },\n ],\n inputs: {\n './src/lib/feature-2.ts': {\n bytes: 147,\n },\n },\n },\n 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js': {\n path: 'static/js/async/vendors-node_modules_minimatch_dist_esm_index_js.js',\n bytes: 79_545,\n imports: [\n {\n path: 'minimatch',\n kind: 'import-statement',\n original: 'minimatch',\n },\n ],\n inputs: {\n '../../../../../node_modules/minimatch/dist/esm/index.js': {\n bytes: 39_098,\n },\n },\n },\n });\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.ts", - "messages": [ - { - "ruleId": "sonarjs/no-duplicate-string", - "severity": 1, - "message": "Define a constant instead of duplicating this literal 5 times.", - "line": 64, - "column": 19, - "nodeType": "Literal", - "messageId": "defineConstant", - "endLine": 64, - "endColumn": 35 - }, - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'unifyBundlerStats' has too many lines (82). Maximum allowed is 50.", - "line": 67, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 174, - "endColumn": 2 - }, - { - "ruleId": "complexity", - "severity": 1, - "message": "Function 'unifyBundlerStats' has a complexity of 23. Maximum allowed is 20.", - "line": 67, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "complex", - "endLine": 174, - "endColumn": 2 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 81, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 85, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 92, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 114, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 98, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 112, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 105, - "column": 11, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 109, - "endColumn": 13 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 117, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 141, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 132, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 137, - "endColumn": 8 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 145, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 171, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 160, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 160, - "endColumn": 44 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 165, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 167, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 166, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 166, - "endColumn": 53 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 166, - "column": 9, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 166, - "endColumn": 30, - "suggestions": [ - { - "messageId": "suggestOptionalChain", - "fix": { - "range": [4721, 4722], - "text": "?." - }, - "desc": "Consider using the optional chain operator `?.` instead. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 170, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 170, - "endColumn": 39 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 191, - "column": 3, - "nodeType": "WhileStatement", - "messageId": "generic", - "endLine": 211, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 192, - "column": 21, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 192, - "endColumn": 35 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 192, - "column": 21, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 192, - "endColumn": 34 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 203, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 210, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 208, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 208, - "endColumn": 32 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 227, - "column": 3, - "nodeType": "WhileStatement", - "messageId": "generic", - "endLine": 243, - "endColumn": 4 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 228, - "column": 21, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 228, - "endColumn": 35 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 228, - "column": 21, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 228, - "endColumn": 34 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 234, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 242, - "endColumn": 6 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 240, - "column": 9, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 240, - "endColumn": 32 - } - ], - "suppressedMessages": [], - "errorCount": 11, - "fatalErrorCount": 0, - "warningCount": 14, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { minimatch } from 'minimatch';\nimport type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type SondaResourceKind = 'asset' | 'filesystem';\nexport type SondaResourceType = 'script' | 'style' | 'font' | 'image' | 'other';\nexport type SondaConnectionKind = 'import' | 'entrypoint' | 'dynamic-import';\n\nexport type SondaResource = {\n kind: SondaResourceKind;\n name: string;\n type: SondaResourceType;\n uncompressed: number;\n gzip?: number;\n brotli?: number;\n format?: string;\n};\n\nexport type SondaConnection = {\n kind: SondaConnectionKind;\n source: string;\n target: string;\n original: string | null;\n};\n\nexport type SondaCoreStats = {\n metadata: {\n version: string;\n integration: string;\n sources: boolean;\n gzip: boolean;\n brotli: boolean;\n };\n resources: SondaResource[];\n connections: SondaConnection[];\n dependencies: unknown[];\n issues: unknown[];\n sourcemaps: unknown[];\n};\n\nexport type SondaUnifyOptions = {\n excludeOutputs?: string[];\n};\n\n/**\n * Checks if path matches any exclude pattern. Filters unwanted files from bundle stats.\n */\nfunction shouldExcludeOutput(\n outputPath: string,\n excludePatterns: string[],\n): boolean {\n return excludePatterns.some(pattern => minimatch(outputPath, pattern));\n}\n\n/**\n * Converts Sonda connection kind to unified import kind\n */\nfunction mapConnectionKind(\n kind: SondaConnectionKind,\n): 'import-statement' | 'dynamic-import' {\n return kind === 'dynamic-import' ? 'dynamic-import' : 'import-statement';\n}\n\nexport function unifyBundlerStats(\n stats: SondaCoreStats,\n options: SondaUnifyOptions,\n): UnifiedStats {\n const { excludeOutputs = ['**/*.map', '**/*.d.ts'] } = options;\n\n // Filter asset resources (outputs)\n const assets = stats.resources.filter(r => r.kind === 'asset');\n const filesystemResources = stats.resources.filter(\n r => r.kind === 'filesystem',\n );\n\n // Build a map of entrypoints: output -> source\n const entryPointMap = new Map();\n for (const conn of stats.connections) {\n if (conn.kind === 'entrypoint') {\n entryPointMap.set(conn.target, conn.source);\n }\n }\n\n // Build a map of imports for each output\n const outputImportsMap = new Map();\n const outputInputsMap = new Map>();\n\n // Process connections to build import relationships\n for (const conn of stats.connections) {\n if (conn.kind === 'import' || conn.kind === 'dynamic-import') {\n // Find which output this source belongs to by tracing entrypoints\n const sourceFile = conn.source;\n\n // For each asset, check if this source is part of its dependency tree\n for (const asset of assets) {\n const entryPoint = entryPointMap.get(asset.name);\n if (\n entryPoint &&\n isPartOfDependencyTree(sourceFile, entryPoint, stats.connections)\n ) {\n const imports = outputImportsMap.get(asset.name) || [];\n imports.push({\n path: conn.target,\n kind: mapConnectionKind(conn.kind),\n ...(conn.original && { original: conn.original }),\n });\n outputImportsMap.set(asset.name, imports);\n }\n }\n }\n }\n\n // Build inputs map for each output\n for (const asset of assets) {\n const entryPoint = entryPointMap.get(asset.name);\n if (entryPoint) {\n const inputsMap = new Map();\n\n // Add the entry point itself\n const entryResource = filesystemResources.find(\n r => r.name === entryPoint,\n );\n if (entryResource) {\n inputsMap.set(entryPoint, entryResource.uncompressed);\n }\n\n // Add all dependencies\n const deps = getAllDependencies(entryPoint, stats.connections);\n for (const dep of deps) {\n const depResource = filesystemResources.find(r => r.name === dep);\n if (depResource) {\n inputsMap.set(dep, depResource.uncompressed);\n }\n }\n\n outputInputsMap.set(asset.name, inputsMap);\n }\n }\n\n const result: UnifiedStats = {};\n\n for (const asset of assets) {\n // Skip outputs that match exclude patterns\n if (shouldExcludeOutput(asset.name, excludeOutputs)) {\n continue;\n }\n\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.uncompressed,\n imports: outputImportsMap.get(asset.name) || [],\n inputs: {},\n };\n\n const entryPoint = entryPointMap.get(asset.name);\n if (entryPoint) {\n unifiedOutput.entryPoint = entryPoint;\n }\n\n const inputsMap = outputInputsMap.get(asset.name);\n if (inputsMap) {\n for (const [inputPath, bytes] of inputsMap) {\n unifiedOutput.inputs![inputPath] = { bytes };\n }\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n\n/**\n * Check if a source file is part of the dependency tree of an entry point\n */\nfunction isPartOfDependencyTree(\n source: string,\n entryPoint: string,\n connections: SondaConnection[],\n): boolean {\n if (source === entryPoint) {\n return true;\n }\n\n const visited = new Set();\n const queue = [entryPoint];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n if (current === source) {\n return true;\n }\n\n // Find all imports from current\n for (const conn of connections) {\n if (\n conn.source === current &&\n (conn.kind === 'import' || conn.kind === 'dynamic-import')\n ) {\n queue.push(conn.target);\n }\n }\n }\n\n return false;\n}\n\n/**\n * Get all dependencies of a source file\n */\nfunction getAllDependencies(\n source: string,\n connections: SondaConnection[],\n): string[] {\n const deps = new Set();\n const visited = new Set();\n const queue = [source];\n\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (visited.has(current)) {\n continue;\n }\n visited.add(current);\n\n for (const conn of connections) {\n if (\n conn.source === current &&\n (conn.kind === 'import' || conn.kind === 'dynamic-import')\n ) {\n deps.add(conn.target);\n queue.push(conn.target);\n }\n }\n }\n\n return [...deps];\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.sonda.unit.test.ts", - "messages": [], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.vite.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'UnifiedStatsImport' is defined but never used.", - "line": 4, - "column": 3, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 4, - "endColumn": 21 - }, - { - "ruleId": "sonarjs/no-unused-collection", - "severity": 2, - "message": "Either use this collection's contents or remove the collection.", - "line": 39, - "column": 9, - "nodeType": "Identifier", - "messageId": "unusedCollection", - "endLine": 39, - "endColumn": 18 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 40, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 42, - "endColumn": 4 - }, - { - "ruleId": "sonarjs/no-unused-collection", - "severity": 2, - "message": "Either use this collection's contents or remove the collection.", - "line": 44, - "column": 9, - "nodeType": "Identifier", - "messageId": "unusedCollection", - "endLine": 44, - "endColumn": 19 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 45, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 47, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 52, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 81, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 65, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 65, - "endColumn": 50 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 73, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 77, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 74, - "column": 9, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 76, - "endColumn": 10 - }, - { - "ruleId": "@typescript-eslint/no-non-null-assertion", - "severity": 2, - "message": "Forbidden non-null assertion.", - "line": 74, - "column": 9, - "nodeType": "TSNonNullExpression", - "messageId": "noNonNull", - "endLine": 74, - "endColumn": 30, - "suggestions": [ - { - "messageId": "suggestOptionalChain", - "fix": { - "range": [1842, 1843], - "text": "?." - }, - "desc": "Consider using the optional chain operator `?.` instead. This operator includes runtime checks, so it is safer than the compile-only non-null assertion operator." - } - ] - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 80, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 80, - "endColumn": 39 - } - ], - "suppressedMessages": [], - "errorCount": 7, - "fatalErrorCount": 0, - "warningCount": 4, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n UnifiedStatsImport,\n} from './unified-stats.types.js';\n\nexport type ViteAsset = {\n name: string;\n size: number;\n};\n\nexport type ViteModule = {\n name: string;\n size: number;\n chunks: string[];\n};\n\nexport type ViteChunk = {\n id: string;\n names: string[];\n files: string[];\n entry: boolean;\n initial: boolean;\n};\n\nexport type ViteCoreStats = {\n builtAt: number;\n assets: ViteAsset[];\n chunks: ViteChunk[];\n modules: ViteModule[];\n};\n\n/**\n * Converts Vite bundle stats to unified format. Processes assets, chunks, and modules for bundle analysis.\n */\nexport function unifyBundlerStats(stats: ViteCoreStats): UnifiedStats {\n const result: UnifiedStats = {};\n\n const chunksMap = new Map();\n for (const chunk of stats.chunks) {\n chunksMap.set(chunk.id, chunk);\n }\n\n const modulesMap = new Map();\n for (const module of stats.modules || []) {\n modulesMap.set(module.name, module);\n }\n\n // Filter out non-JS assets (like source maps)\n const jsAssets = stats.assets.filter(asset => asset.name.endsWith('.js'));\n\n for (const asset of jsAssets) {\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.size,\n imports: [],\n inputs: {},\n };\n\n // Find the chunk that contains this asset\n const chunk = stats.chunks.find(c => c.files.includes(asset.name));\n if (chunk) {\n // Set entry point if it's an entry chunk\n if (chunk.entry && chunk.names.length > 0) {\n unifiedOutput.entryPoint = chunk.names[0];\n }\n\n // Find modules that belong to this chunk\n const chunkModules =\n stats.modules?.filter(module => module.chunks.includes(chunk.id)) || [];\n\n // Add inputs\n for (const module of chunkModules) {\n unifiedOutput.inputs![module.name] = {\n bytes: module.size,\n };\n }\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.ts", - "messages": [ - { - "ruleId": "max-lines-per-function", - "severity": 1, - "message": "Function 'unifyBundlerStats' has too many lines (89). Maximum allowed is 50.", - "line": 66, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "exceed", - "endLine": 165, - "endColumn": 2 - }, - { - "ruleId": "complexity", - "severity": 1, - "message": "Function 'unifyBundlerStats' has a complexity of 22. Maximum allowed is 20.", - "line": 66, - "column": 8, - "nodeType": "FunctionDeclaration", - "messageId": "complex", - "endLine": 165, - "endColumn": 2 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 70, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 72, - "endColumn": 4 - }, - { - "ruleId": "sonarjs/no-unused-collection", - "severity": 2, - "message": "Either use this collection's contents or remove the collection.", - "line": 74, - "column": 9, - "nodeType": "Identifier", - "messageId": "unusedCollection", - "endLine": 74, - "endColumn": 19 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 75, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 77, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 79, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 162, - "endColumn": 4 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 87, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 106, - "endColumn": 6 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'entryName' is assigned a value but never used. Allowed unused elements of array destructuring must match /^_/u.", - "line": 87, - "column": 17, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 87, - "endColumn": 26 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 92, - "column": 9, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 103, - "endColumn": 10 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", - "line": 94, - "column": 11, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 102, - "endColumn": 12 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", - "line": 98, - "column": 13, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 101, - "endColumn": 14 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 99, - "column": 15, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 99, - "endColumn": 58 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 108, - "column": 5, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 147, - "endColumn": 6 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 114, - "column": 7, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 146, - "endColumn": 8 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 120, - "column": 11, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 122, - "endColumn": 12 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 125, - "column": 9, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 145, - "endColumn": 10 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (5). Maximum allowed is 4.", - "line": 126, - "column": 11, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 144, - "endColumn": 12 - }, - { - "ruleId": "max-depth", - "severity": 1, - "message": "Blocks are nested too deeply (6). Maximum allowed is 4.", - "line": 127, - "column": 13, - "nodeType": "IfStatement", - "messageId": "tooDeeply", - "endLine": 133, - "endColumn": 14 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 128, - "column": 15, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 132, - "endColumn": 17 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an array is not allowed.", - "line": 139, - "column": 13, - "nodeType": "CallExpression", - "messageId": "array", - "endLine": 143, - "endColumn": 15 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 158, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 158, - "endColumn": 44 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 161, - "column": 5, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 161, - "endColumn": 39 - } - ], - "suppressedMessages": [], - "errorCount": 8, - "fatalErrorCount": 0, - "warningCount": 14, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type {\n UnifiedStats,\n UnifiedStatsBundle,\n} from './unified-stats.types.js';\n\nexport type WebpackImportKind = 'import-statement' | 'dynamic-import';\n\nexport type WebpackReason = {\n moduleIdentifier: string | null;\n module: string | null;\n moduleName: string | null;\n type: string;\n userRequest: string;\n loc: string;\n};\n\nexport type WebpackAsset = {\n name: string;\n size: number;\n chunks: string[];\n chunkNames: string[];\n emitted: boolean;\n type: string;\n};\n\nexport type WebpackModule = {\n identifier: string;\n name: string;\n size: number;\n chunks: string[];\n depth: number | null;\n reasons: WebpackReason[];\n type: string;\n moduleType: string;\n issuer: string | null;\n issuerName: string | null;\n providedExports?: string[];\n};\n\nexport type WebpackChunk = {\n id: string;\n names: string[];\n files: string[];\n size: number;\n modules: WebpackModule[];\n parents: string[];\n children: string[];\n entry: boolean;\n initial: boolean;\n runtime?: string[];\n};\n\nexport type WebpackEntrypoint = {\n name: string;\n chunks: string[];\n assets: { name: string; size: number }[];\n};\n\nexport type WebpackCoreStats = {\n assets: WebpackAsset[];\n chunks: WebpackChunk[];\n modules: WebpackModule[];\n entrypoints: Record;\n};\n\nexport function unifyBundlerStats(stats: WebpackCoreStats): UnifiedStats {\n const result: UnifiedStats = {};\n\n const chunksMap = new Map();\n for (const chunk of stats.chunks) {\n chunksMap.set(chunk.id, chunk);\n }\n\n const modulesMap = new Map();\n for (const module of stats.modules) {\n modulesMap.set(module.identifier, module);\n }\n\n for (const asset of stats.assets) {\n const unifiedOutput: UnifiedStatsBundle = {\n path: asset.name,\n bytes: asset.size,\n imports: [],\n inputs: {},\n };\n\n for (const [entryName, entrypoint] of Object.entries(stats.entrypoints)) {\n if (\n entrypoint.assets.some(entryAsset => entryAsset.name === asset.name)\n ) {\n const entryChunks = entrypoint.chunks;\n for (const chunkId of entryChunks) {\n const chunk = chunksMap.get(chunkId);\n if (chunk?.entry) {\n const entryModule = chunk.modules.find(module =>\n module.reasons.some(reason => reason.type === 'entry'),\n );\n if (entryModule) {\n unifiedOutput.entryPoint = entryModule.name;\n break;\n }\n }\n }\n break;\n }\n }\n\n for (const chunkId of asset.chunks) {\n const chunk = chunksMap.get(chunkId);\n if (!chunk) {\n continue;\n }\n\n for (const module of chunk.modules) {\n if (module.type === 'runtime') {\n continue;\n }\n\n if (unifiedOutput.inputs) {\n unifiedOutput.inputs[module.name] = {\n bytes: module.size,\n };\n }\n\n for (const reason of module.reasons) {\n if (reason.type === 'import()') {\n if (unifiedOutput.imports) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'dynamic-import',\n original: reason.userRequest,\n });\n }\n } else if (\n (reason.type === 'harmony side effect evaluation' ||\n reason.type === 'harmony import specifier') &&\n unifiedOutput.imports\n ) {\n unifiedOutput.imports.push({\n path: reason.userRequest,\n kind: 'import-statement',\n original: reason.userRequest,\n });\n }\n }\n }\n }\n\n if (unifiedOutput.imports) {\n const uniqueImports = unifiedOutput.imports.filter(\n (importItem, index, self) =>\n index ===\n self.findIndex(\n item =>\n item.path === importItem.path && item.kind === importItem.kind,\n ),\n );\n unifiedOutput.imports = uniqueImports;\n }\n\n result[asset.name] = unifiedOutput;\n }\n\n return result;\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/unify/unify.webpack.unit.test.ts", - "messages": [ - { - "ruleId": "no-duplicate-imports", - "severity": 1, - "message": "'./unify.webpack.js' import is duplicated.", - "line": 3, - "column": 1, - "nodeType": "ImportDeclaration", - "messageId": "import", - "endLine": 3, - "endColumn": 60 - } - ], - "suppressedMessages": [], - "errorCount": 0, - "fatalErrorCount": 0, - "warningCount": 1, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { describe, expect, it } from 'vitest';\nimport { unifyBundlerStats } from './unify.webpack.js';\nimport type { WebpackCoreStats } from './unify.webpack.js';\n\ndescribe('unifyBundlerStats', () => {\n it('should transform basic webpack stats with assets and chunks', () => {\n const webpackStats: WebpackCoreStats = {\n assets: [\n {\n name: 'bundle.js',\n size: 16_823,\n chunks: ['main'],\n chunkNames: ['main'],\n emitted: true,\n type: 'asset',\n },\n ],\n chunks: [\n {\n id: 'main',\n names: ['main'],\n files: ['bundle.js'],\n size: 8415,\n modules: [\n {\n identifier: './src/index.ts',\n name: './src/index.ts',\n size: 463,\n chunks: ['main'],\n depth: 0,\n reasons: [\n {\n moduleIdentifier: null,\n module: null,\n moduleName: null,\n type: 'entry',\n userRequest: './src/index.ts',\n loc: 'main',\n },\n ],\n type: 'module',\n moduleType: 'javascript/auto',\n issuer: null,\n issuerName: null,\n providedExports: ['default', 'indexOnlyFunction'],\n },\n ],\n parents: [],\n children: [],\n entry: true,\n initial: true,\n runtime: ['main'],\n },\n ],\n modules: [\n {\n identifier: './src/index.ts',\n name: './src/index.ts',\n size: 463,\n chunks: ['main'],\n depth: 0,\n reasons: [\n {\n moduleIdentifier: null,\n module: null,\n moduleName: null,\n type: 'entry',\n userRequest: './src/index.ts',\n loc: 'main',\n },\n ],\n type: 'module',\n moduleType: 'javascript/auto',\n issuer: null,\n issuerName: null,\n providedExports: ['default', 'indexOnlyFunction'],\n },\n ],\n entrypoints: {\n main: {\n name: 'main',\n chunks: ['main'],\n assets: [{ name: 'bundle.js', size: 16_823 }],\n },\n },\n };\n\n expect(unifyBundlerStats(webpackStats)).toStrictEqual({\n 'bundle.js': {\n path: 'bundle.js',\n bytes: 16_823,\n imports: [],\n inputs: {\n './src/index.ts': {\n bytes: 463,\n },\n },\n entryPoint: './src/index.ts',\n },\n });\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/runner/utils.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-shadow", - "severity": 1, - "message": "'config' is already declared in the upper scope on line 9 column 3.", - "line": 11, - "column": 30, - "nodeType": "Identifier", - "messageId": "noShadow", - "endLine": 11, - "endColumn": 36 - }, - { - "ruleId": "functional/no-loop-statements", - "severity": 1, - "message": "Unexpected loop, use map or reduce instead.", - "line": 27, - "column": 3, - "nodeType": "ForOfStatement", - "messageId": "generic", - "endLine": 38, - "endColumn": 4 - }, - { - "ruleId": "functional/immutable-data", - "severity": 2, - "message": "Modifying an existing object/array is not allowed.", - "line": 36, - "column": 7, - "nodeType": "AssignmentExpression", - "messageId": "generic", - "endLine": 36, - "endColumn": 34 - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 0, - "warningCount": 2, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { minimatch } from 'minimatch';\nimport type { AuditOutput } from '@code-pushup/models';\nimport { formatBytes } from '@code-pushup/utils';\nimport type { BundleStatsConfig } from './types.js';\nimport type { UnifiedStats } from './unify/unified-stats.types.js';\n\nexport function filterUnifiedTreeByConfig(\n bundleStats: UnifiedStats,\n config: BundleStatsConfig[],\n): UnifiedStats {\n return config.reduce((acc, config) => {\n const filteredStats = filterUnifiedTreeByConfigSingle(bundleStats, config);\n return { ...acc, ...filteredStats };\n }, {});\n}\n\nexport function filterUnifiedTreeByConfigSingle(\n bundleStats: UnifiedStats,\n config: BundleStatsConfig,\n): UnifiedStats | null {\n const { selection } = config;\n const includePatterns = selection.includeOutputs ?? [];\n const excludePatterns = selection.excludeOutputs ?? [];\n\n const filteredStats: UnifiedStats = {};\n\n for (const [path, stats] of Object.entries(bundleStats)) {\n const included =\n includePatterns.length === 0 ||\n includePatterns.some((pattern: string) => minimatch(path, pattern));\n const excluded = excludePatterns.some((pattern: string) =>\n minimatch(path, pattern),\n );\n\n if (included && !excluded) {\n filteredStats[path] = stats;\n }\n }\n\n return Object.keys(filteredStats).length > 0 ? filteredStats : null;\n}\n\nexport function createDisplayValue(\n totalBytes: number,\n fileCount: number,\n): string {\n const formattedBytes = formatBytes(totalBytes);\n const formattedFileCount = `${fileCount} file${fileCount === 1 ? '' : 's'}`;\n return `${formattedBytes} (${formattedFileCount})`;\n}\n\nexport function createEmptyAudit(config: BundleStatsConfig): AuditOutput {\n return {\n slug: config.slug,\n score: 0,\n value: 0,\n displayValue: createDisplayValue(0, 0),\n details: {\n issues: [],\n },\n };\n}\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/stats-generation.int.test.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'writeFileSync' is defined but never used.", - "line": 1, - "column": 10, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 1, - "endColumn": 23 - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { writeFileSync } from 'node:fs';\nimport { cp } from 'node:fs/promises';\nimport path from 'node:path';\nimport { beforeAll, describe, expect, it } from 'vitest';\nimport {\n E2E_ENVIRONMENTS_DIR,\n TEST_OUTPUT_DIR,\n teardownTestFolder,\n} from '@code-pushup/test-utils';\nimport { executeProcess, readJsonFile } from '@code-pushup/utils';\n\nconst FIXTURES_DIR = path.join(\n 'packages',\n 'plugin-bundle-stats',\n 'mocks',\n 'fixtures',\n);\n\nconst tmpRoot = path.join(E2E_ENVIRONMENTS_DIR, 'plugin-bundle-stats');\n\nconst tmpTestOutputRoot = path.join(tmpRoot, TEST_OUTPUT_DIR);\n\nconst fixtureSharedRoot = path.join(FIXTURES_DIR, 'shared-source');\n\nconst SNAPSHOTS_DIR = path.join(\n 'packages',\n 'plugin-bundle-stats',\n 'src',\n 'lib',\n '__snapshots__',\n);\n\ndescribe('esbuild stats generation', () => {\n const tmpEsbuild = path.join(tmpTestOutputRoot, 'esbuild-stats');\n const esbuildDistDir = path.join(tmpEsbuild, 'dist');\n\n beforeAll(async () => {\n await cp(fixtureSharedRoot, tmpEsbuild, {\n recursive: true,\n });\n });\n\n afterAll(async () => {\n await teardownTestFolder(tmpEsbuild);\n });\n\n it('should create stats.json using esbuild', async () => {\n // Copy esbuild configuration\n await cp(path.join(FIXTURES_DIR, 'esbuild'), tmpEsbuild, {\n recursive: true,\n });\n\n const { code } = await executeProcess({\n command: 'node',\n args: ['esbuild.config.cjs'],\n cwd: tmpEsbuild,\n });\n\n expect(code).toBe(0);\n\n const statsPath = path.join(esbuildDistDir, 'stats.json');\n const stats = (await readJsonFile(statsPath)) as Record;\n\n expect(stats).toEqual(\n expect.objectContaining({\n inputs: expect.any(Object),\n outputs: expect.objectContaining({\n 'dist/index.js': expect.any(Object),\n 'dist/bin.js': expect.any(Object),\n }),\n }),\n );\n\n await cp(statsPath, path.join(SNAPSHOTS_DIR, 'esbuild.stats.json'));\n });\n});\n\ndescribe('webpack stats generation', () => {\n const tmpWebpack = path.join(tmpTestOutputRoot, 'webpack-stats');\n const webpackDistDir = path.join(tmpWebpack, 'dist');\n\n beforeAll(async () => {\n await cp(fixtureSharedRoot, tmpWebpack, {\n recursive: true,\n });\n });\n\n afterAll(async () => {\n await teardownTestFolder(tmpWebpack);\n });\n\n it('should create stats.json using webpack@5', async () => {\n await cp(path.join(FIXTURES_DIR, 'webpack'), tmpWebpack, {\n recursive: true,\n });\n\n const { code } = await executeProcess({\n command: 'node',\n args: ['webpack-build.cjs'],\n cwd: tmpWebpack,\n });\n\n expect(code).toBe(0);\n\n const statsPath = path.join(webpackDistDir, 'stats.json');\n const rawStats = (await readJsonFile(statsPath)) as Record;\n\n expect(rawStats).toEqual(\n expect.objectContaining({\n modules: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/src\\/index/),\n }),\n expect.objectContaining({\n name: expect.stringMatching(/src\\/utils/),\n }),\n ]),\n assets: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/bundle\\.js/),\n }),\n ]),\n }),\n );\n\n await cp(statsPath, path.join(SNAPSHOTS_DIR, 'webpack.stats.json'));\n });\n});\n\ndescribe('rsbuild stats generation', () => {\n const tmpRsbuild = path.join(tmpTestOutputRoot, 'rsbuild-stats');\n const rsbuildDistDir = path.join(tmpRsbuild, 'dist');\n\n beforeAll(async () => {\n await cp(fixtureSharedRoot, tmpRsbuild, {\n recursive: true,\n });\n });\n\n afterAll(async () => {\n await teardownTestFolder(tmpRsbuild);\n });\n\n it('should create stats.json using rsbuild', async () => {\n await executeProcess({\n command: 'mkdir',\n args: ['-p', 'dist'],\n cwd: tmpRsbuild,\n });\n\n await cp(path.join(FIXTURES_DIR, 'rsbuild'), path.join(tmpRsbuild), {\n recursive: true,\n });\n\n await cp(fixtureSharedRoot, path.join(tmpRsbuild, 'src'), {\n recursive: true,\n });\n\n const { code } = await executeProcess({\n command: 'node',\n args: ['rsbuild-build.cjs'],\n cwd: tmpRsbuild,\n });\n\n expect(code).toBe(0);\n\n const statsPath = path.join(rsbuildDistDir, 'stats.json');\n const rawStats = (await readJsonFile(statsPath)) as Record;\n\n expect(rawStats).toEqual(\n expect.objectContaining({\n modules: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/src\\/index/),\n }),\n expect.objectContaining({\n name: expect.stringMatching(/src\\/utils/),\n }),\n ]),\n assets: expect.arrayContaining([\n expect.objectContaining({\n name: expect.stringMatching(/bundle\\.js/),\n }),\n ]),\n }),\n );\n\n await cp(statsPath, path.join(SNAPSHOTS_DIR, 'rsbuild.stats.json'));\n });\n});\n", - "usedDeprecatedRules": [ - { - "ruleId": "vitest/no-done-callback", - "replacedBy": [] - } - ] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/src/lib/types.ts", - "messages": [ - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'TablePruningConfig' is defined but never used.", - "line": 4, - "column": 3, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 4, - "endColumn": 21 - }, - { - "ruleId": "@typescript-eslint/no-unused-vars", - "severity": 2, - "message": "'SelectionConfig' is defined but never used.", - "line": 8, - "column": 15, - "nodeType": null, - "messageId": "unusedVar", - "endLine": 8, - "endColumn": 30 - } - ], - "suppressedMessages": [], - "errorCount": 2, - "fatalErrorCount": 0, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import type { Group, PluginArtifactOptions } from '@code-pushup/models';\nimport type {\n InsightsTableConfig,\n TablePruningConfig,\n} from './runner/audits/details/table.js';\nimport type { DependencyTreeConfig } from './runner/audits/details/tree.js';\nimport type { PenaltyConfig, ScoringConfig } from './runner/audits/scoring.js';\nimport type { SelectionConfig } from './runner/audits/selection.js';\nimport type { SupportedBundlers } from './runner/types.js';\n\nexport type SelectionGeneralConfig = {\n include?: string[];\n exclude?: string[];\n};\n\nexport type PluginDependencyTreeOptions = Omit<\n Partial,\n 'enabled'\n>;\n\nexport type DependencyTreeOptions = DependencyTreeConfig;\n\nexport type SelectionOptions = SelectionGeneralConfig & {\n mode?: 'bundle' | 'matchingOnly' | 'withStartupDeps' | 'withAllDeps';\n includeOutputs?: string[];\n excludeOutputs?: string[];\n includeInputs?: string[];\n excludeInputs?: string[];\n includeImports?: string[];\n excludeImports?: string[];\n includeEntryPoints?: string[];\n excludeEntryPoints?: string[];\n};\n\nexport type PluginSelectionOptions = Omit<\n SelectionOptions,\n | 'include'\n | 'includeOutputs'\n | 'includeInputs'\n | 'includeImports'\n | 'includeEntryPoints'\n>;\n\nexport type PenaltyOptions = Omit & {\n artefactSize?: PenaltyConfig['artefactSize'] | number;\n};\n\nexport type ScoringOptions = {\n enabled?: boolean;\n totalSize?: ScoringConfig['totalSize'] | number;\n penalty?: PenaltyOptions;\n};\n\nexport type PluginPenaltyOptions = Omit;\n\nexport type PluginScoringOptions = {\n penalty?: PluginPenaltyOptions;\n};\n\nexport type InsightsTableOptions = InsightsTableConfig | false;\nexport type PluginInsightsTableOptions = InsightsTableConfig | false;\n\nexport type BundleStatsAuditOptions = {\n slug?: string;\n title: string;\n description?: string;\n selection?: SelectionOptions;\n scoring?: ScoringOptions;\n dependencyTree?: DependencyTreeOptions;\n insightsTable?: InsightsTableOptions;\n};\n\nexport type PluginBundleStatsAuditOptions = {\n selection?: PluginSelectionOptions;\n scoring?: PluginScoringOptions;\n dependencyTree?: PluginDependencyTreeOptions;\n insightsTable?: PluginInsightsTableOptions;\n};\n\nexport type PluginOptions = {\n groups?: Group[];\n bundler: SupportedBundlers;\n audits: BundleStatsAuditOptions[];\n} & PluginBundleStatsAuditOptions &\n PluginArtifactOptions;\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.int.config.ts", - "messages": [ - { - "ruleId": null, - "nodeType": null, - "fatal": true, - "severity": 2, - "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.int.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 1, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "/// \nimport { defineConfig } from 'vite';\nimport { tsconfigPathAliases } from '../../tools/vitest-tsconfig-path-aliases.js';\n\nexport default defineConfig({\n cacheDir: '../../node_modules/.vite/plugin-bundle-stats',\n test: {\n reporters: ['basic'],\n globals: true,\n cache: {\n dir: '../../node_modules/.vitest/plugin-bundle-stats',\n },\n alias: tsconfigPathAliases(),\n pool: 'threads',\n poolOptions: { threads: { singleThread: true } },\n coverage: {\n reporter: ['text', 'lcov'],\n reportsDirectory: '../../coverage/plugin-bundle-stats/int-tests',\n exclude: ['mocks/**', '**/types.ts'],\n },\n environment: 'node',\n include: ['src/**/*.int.test.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],\n globalSetup: ['../../global-setup.ts'],\n setupFiles: [\n '../../testing/test-setup/src/lib/cliui.mock.ts',\n '../../testing/test-setup/src/lib/reset.mocks.ts',\n '../../testing/test-setup/src/lib/chrome-path.mock.ts',\n ],\n },\n});\n", - "usedDeprecatedRules": [] - }, - { - "filePath": "/Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.unit.config.ts", - "messages": [ - { - "ruleId": null, - "nodeType": null, - "fatal": true, - "severity": 2, - "message": "Parsing error: /Users/michael_hladky/WebstormProjects/cli/packages/plugin-bundle-stats/vitest.unit.config.ts was not found by the project service. Consider either including it in the tsconfig.json or including it in allowDefaultProject." - } - ], - "suppressedMessages": [], - "errorCount": 1, - "fatalErrorCount": 1, - "warningCount": 0, - "fixableErrorCount": 0, - "fixableWarningCount": 0, - "source": "import { createUnitTestConfig } from '../../testing/test-setup-config/src/index.js';\n\nexport default createUnitTestConfig('plugin-bundle-stats');\n", - "usedDeprecatedRules": [] - } -] From d286494a6f7563ebcd3604f4370a9b86e18231e9 Mon Sep 17 00:00:00 2001 From: Michael Hladky <10064416+BioPhoton@users.noreply.github.com> Date: Wed, 10 Dec 2025 17:29:55 +0100 Subject: [PATCH 3/7] Potential fix for code scanning alert no. 13: Incomplete multi-character sanitization Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- .../src/lib/runner/audits/details/path-utils.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts index 80a6b94..58e9bd0 100644 --- a/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts @@ -13,7 +13,13 @@ export function splitPathSegments(path: string): string[] { * Normalizes a path for pattern matching by removing leading './' and ensuring consistent format. */ export function normalizePathForMatching(path: string): string { - return path.replace(/\.\.\//g, '').replace(/^\/+/, ''); + // Remove all instances of ../, applying repeatedly to catch overlapping or regenerated cases + let prev; + do { + prev = path; + path = path.replace(/\.\.\//g, ''); + } while (path !== prev); + return path.replace(/^\/+/, ''); } /** From 6076e90f82fab0050e02fb61ae009f8c8257dcd9 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 10 Dec 2025 17:33:57 +0100 Subject: [PATCH 4/7] refactor: wip --- .../src/lib/runner/audits/details/path-utils.ts | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts b/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts index 58e9bd0..0a9ea59 100644 --- a/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts +++ b/packages/plugin-bundle-stats/src/lib/runner/audits/details/path-utils.ts @@ -14,12 +14,13 @@ export function splitPathSegments(path: string): string[] { */ export function normalizePathForMatching(path: string): string { // Remove all instances of ../, applying repeatedly to catch overlapping or regenerated cases + let normalizedPath = path; let prev; do { - prev = path; - path = path.replace(/\.\.\//g, ''); - } while (path !== prev); - return path.replace(/^\/+/, ''); + prev = normalizedPath; + normalizedPath = normalizedPath.replace(/\.\.\//g, ''); + } while (normalizedPath !== prev); + return normalizedPath.replace(/^\/+/, ''); } /** From 721b2201909d61df94ae5f919af1a46adbe400e1 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 10 Dec 2025 17:48:21 +0100 Subject: [PATCH 5/7] refactor: add e2e tests --- e2e/plugin-bundle-stats-e2e/eslint.config.js | 12 + .../mocks/fixtures/code-pushup.config.ts | 25 ++ .../fixtures/stats/esbuild-minimal.stats.json | 315 ++++++++++++++++++ e2e/plugin-bundle-stats-e2e/project.json | 17 + .../tests/collect.e2e.test.ts | 53 +++ e2e/plugin-bundle-stats-e2e/tsconfig.json | 20 ++ .../tsconfig.test.json | 15 + .../vitest.e2e.config.ts | 5 + tsconfig.base.json | 3 + 9 files changed, 465 insertions(+) create mode 100644 e2e/plugin-bundle-stats-e2e/eslint.config.js create mode 100644 e2e/plugin-bundle-stats-e2e/mocks/fixtures/code-pushup.config.ts create mode 100644 e2e/plugin-bundle-stats-e2e/mocks/fixtures/stats/esbuild-minimal.stats.json create mode 100644 e2e/plugin-bundle-stats-e2e/project.json create mode 100644 e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts create mode 100644 e2e/plugin-bundle-stats-e2e/tsconfig.json create mode 100644 e2e/plugin-bundle-stats-e2e/tsconfig.test.json create mode 100644 e2e/plugin-bundle-stats-e2e/vitest.e2e.config.ts diff --git a/e2e/plugin-bundle-stats-e2e/eslint.config.js b/e2e/plugin-bundle-stats-e2e/eslint.config.js new file mode 100644 index 0000000..2656b27 --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/eslint.config.js @@ -0,0 +1,12 @@ +import tseslint from 'typescript-eslint'; +import baseConfig from '../../eslint.config.js'; + +export default tseslint.config(...baseConfig, { + files: ['**/*.ts'], + languageOptions: { + parserOptions: { + projectService: true, + tsconfigRootDir: import.meta.dirname, + }, + }, +}); diff --git a/e2e/plugin-bundle-stats-e2e/mocks/fixtures/code-pushup.config.ts b/e2e/plugin-bundle-stats-e2e/mocks/fixtures/code-pushup.config.ts new file mode 100644 index 0000000..4fd3a98 --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/mocks/fixtures/code-pushup.config.ts @@ -0,0 +1,25 @@ +import bundleStatsPlugin from '@code-pushup/bundle-stats-plugin'; +import type { CoreConfig } from '@code-pushup/models'; + +export default { + plugins: [ + await bundleStatsPlugin({ + bundler: 'esbuild', + artifactsPaths: 'stats/esbuild-minimal.stats.json', + audits: [ + { + title: 'Bundle Size', + description: 'Analyze bundle size and dependencies', + selection: { + mode: 'bundle', + includeOutputs: ['dist/**/*.js'], + }, + scoring: { + enabled: true, + totalSize: 1000000, // 1MB threshold + }, + }, + ], + }), + ], +} satisfies CoreConfig; diff --git a/e2e/plugin-bundle-stats-e2e/mocks/fixtures/stats/esbuild-minimal.stats.json b/e2e/plugin-bundle-stats-e2e/mocks/fixtures/stats/esbuild-minimal.stats.json new file mode 100644 index 0000000..699386d --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/mocks/fixtures/stats/esbuild-minimal.stats.json @@ -0,0 +1,315 @@ +{ + "inputs": { + "../../../../../node_modules/balanced-match/index.js": { + "bytes": 1219, + "imports": [], + "format": "cjs" + }, + "../../../../../node_modules/brace-expansion/index.js": { + "bytes": 4992, + "imports": [ + { + "path": "../../../../../node_modules/balanced-match/index.js", + "kind": "require-call", + "original": "balanced-match" + } + ], + "format": "cjs" + }, + "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js": { + "bytes": 336, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js": { + "bytes": 5631, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/unescape.js": { + "bytes": 847, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/ast.js": { + "bytes": 22588, + "imports": [ + { + "path": "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js", + "kind": "import-statement", + "original": "./brace-expressions.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + } + ], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/escape.js": { + "bytes": 848, + "imports": [], + "format": "esm" + }, + "../../../../../node_modules/minimatch/dist/esm/index.js": { + "bytes": 39098, + "imports": [ + { + "path": "../../../../../node_modules/brace-expansion/index.js", + "kind": "import-statement", + "original": "brace-expansion" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js", + "kind": "import-statement", + "original": "./assert-valid-pattern.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/ast.js", + "kind": "import-statement", + "original": "./ast.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/escape.js", + "kind": "import-statement", + "original": "./escape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/ast.js", + "kind": "import-statement", + "original": "./ast.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/escape.js", + "kind": "import-statement", + "original": "./escape.js" + }, + { + "path": "../../../../../node_modules/minimatch/dist/esm/unescape.js", + "kind": "import-statement", + "original": "./unescape.js" + } + ], + "format": "esm" + }, + "../shared-source/node_modules/my-lib/index.js": { + "bytes": 94, + "imports": [], + "format": "esm" + }, + "../shared-source/src/lib/utils/format.ts": { + "bytes": 590, + "imports": [ + { + "path": "../../../../../node_modules/minimatch/dist/esm/index.js", + "kind": "import-statement", + "original": "minimatch" + }, + { + "path": "../shared-source/node_modules/my-lib/index.js", + "kind": "import-statement", + "original": "my-lib" + } + ], + "format": "esm" + }, + "../shared-source/src/lib/feature-1.ts": { + "bytes": 489, + "imports": [ + { + "path": "../shared-source/src/lib/utils/format.ts", + "kind": "import-statement", + "original": "./utils/format" + } + ], + "format": "esm" + }, + "../shared-source/src/lib/utils/math.ts": { + "bytes": 240, + "imports": [], + "format": "esm" + }, + "../shared-source/src/lib/utils/string.ts": { + "bytes": 300, + "imports": [], + "format": "esm" + }, + "../shared-source/src/lib/feature-2.ts": { + "bytes": 53, + "imports": [], + "format": "esm" + }, + "../shared-source/src/index.ts": { + "bytes": 673, + "imports": [ + { + "path": "../shared-source/src/lib/feature-1.ts", + "kind": "import-statement", + "original": "./lib/feature-1" + }, + { + "path": "../shared-source/src/lib/utils/math.ts", + "kind": "import-statement", + "original": "./lib/utils/math" + }, + { + "path": "../shared-source/src/lib/utils/string.ts", + "kind": "import-statement", + "original": "./lib/utils/string" + }, + { + "path": "../shared-source/src/lib/feature-2.ts", + "kind": "dynamic-import", + "original": "./lib/feature-2" + } + ], + "format": "esm" + }, + "../shared-source/src/bin.ts": { + "bytes": 633, + "imports": [ + { + "path": "../shared-source/src/lib/feature-1.ts", + "kind": "import-statement", + "original": "./lib/feature-1" + }, + { + "path": "../shared-source/src/lib/utils/math.ts", + "kind": "import-statement", + "original": "./lib/utils/math" + }, + { + "path": "../shared-source/src/lib/utils/string.ts", + "kind": "import-statement", + "original": "./lib/utils/string" + } + ], + "format": "esm" + } + }, + "outputs": { + "dist/index.js": { + "imports": [ + { + "path": "dist/chunks/chunk-PKX4VJZC.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/feature-2-SERQNJVR.js", + "kind": "dynamic-import" + } + ], + "exports": ["default", "indexOnlyFunction"], + "entryPoint": "../shared-source/src/index.ts", + "inputs": { + "../shared-source/src/index.ts": { + "bytesInOutput": 386 + } + }, + "bytes": 595 + }, + "dist/bin.js": { + "imports": [ + { + "path": "dist/chunks/chunk-PKX4VJZC.js", + "kind": "import-statement" + }, + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": [], + "entryPoint": "../shared-source/src/bin.ts", + "inputs": { + "../shared-source/src/bin.ts": { + "bytesInOutput": 373 + } + }, + "bytes": 549 + }, + "dist/chunks/chunk-PKX4VJZC.js": { + "imports": [ + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": ["calculate", "externalFunction", "greet"], + "inputs": { + "../../../../../node_modules/balanced-match/index.js": { + "bytesInOutput": 1543 + }, + "../../../../../node_modules/brace-expansion/index.js": { + "bytesInOutput": 4784 + }, + "../../../../../node_modules/minimatch/dist/esm/index.js": { + "bytesInOutput": 23960 + }, + "../../../../../node_modules/minimatch/dist/esm/assert-valid-pattern.js": { + "bytesInOutput": 261 + }, + "../../../../../node_modules/minimatch/dist/esm/brace-expressions.js": { + "bytesInOutput": 3163 + }, + "../../../../../node_modules/minimatch/dist/esm/unescape.js": { + "bytesInOutput": 210 + }, + "../../../../../node_modules/minimatch/dist/esm/ast.js": { + "bytesInOutput": 15518 + }, + "../../../../../node_modules/minimatch/dist/esm/escape.js": { + "bytesInOutput": 165 + }, + "../shared-source/node_modules/my-lib/index.js": { + "bytesInOutput": 93 + }, + "../shared-source/src/lib/utils/format.ts": { + "bytesInOutput": 269 + }, + "../shared-source/src/lib/feature-1.ts": { + "bytesInOutput": 269 + }, + "../shared-source/src/lib/utils/math.ts": { + "bytesInOutput": 145 + }, + "../shared-source/src/lib/utils/string.ts": { + "bytesInOutput": 54 + } + }, + "bytes": 51348 + }, + "dist/chunks/feature-2-SERQNJVR.js": { + "imports": [ + { + "path": "dist/chunks/chunk-SK6HMZ5B.js", + "kind": "import-statement" + } + ], + "exports": ["chart"], + "entryPoint": "../shared-source/src/lib/feature-2.ts", + "inputs": { + "../shared-source/src/lib/feature-2.ts": { + "bytesInOutput": 38 + } + }, + "bytes": 130 + }, + "dist/chunks/chunk-SK6HMZ5B.js": { + "imports": [], + "exports": ["__commonJS", "__toESM"], + "inputs": {}, + "bytes": 1357 + } + } +} diff --git a/e2e/plugin-bundle-stats-e2e/project.json b/e2e/plugin-bundle-stats-e2e/project.json new file mode 100644 index 0000000..9b491d8 --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/project.json @@ -0,0 +1,17 @@ +{ + "name": "plugin-bundle-stats-e2e", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "e2e/plugin-bundle-stats-e2e/src", + "projectType": "application", + "targets": { + "lint": {}, + "e2e": { + "executor": "@nx/vitest:test", + "options": { + "configFile": "{projectRoot}/vitest.e2e.config.ts" + } + } + }, + "implicitDependencies": ["plugin-bundle-stats"], + "tags": ["scope:plugin", "type:e2e"] +} diff --git a/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts b/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts new file mode 100644 index 0000000..ecfa219 --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts @@ -0,0 +1,53 @@ +import { cp } from 'node:fs/promises'; +import path from 'node:path'; +import { afterAll, beforeAll, expect } from 'vitest'; +import { type Report, reportSchema } from '@code-pushup/models'; +import { nxTargetProject } from '@code-pushup/test-nx-utils'; +import { + E2E_ENVIRONMENTS_DIR, + TEST_OUTPUT_DIR, + omitVariableReportData, + restoreNxIgnoredFiles, + teardownTestFolder, +} from '@code-pushup/test-utils'; +import { executeProcess, readJsonFile } from '@code-pushup/utils'; + +describe('PLUGIN collect report with bundle-stats-plugin NPM package', () => { + const testFileDir = path.join( + E2E_ENVIRONMENTS_DIR, + nxTargetProject(), + TEST_OUTPUT_DIR, + 'collect', + ); + + const fixturesDir = path.join('e2e', nxTargetProject(), 'mocks/fixtures'); + + beforeAll(async () => { + await cp(fixturesDir, testFileDir, { recursive: true }); + await restoreNxIgnoredFiles(testFileDir); + }); + + afterAll(async () => { + await teardownTestFolder(testFileDir); + }); + + it('should run plugin over CLI and creates report.json', async () => { + const { code, stdout } = await executeProcess({ + command: 'npx', + // verbose exposes audits with perfect scores that are hidden in the default stdout + args: ['@code-pushup/cli', 'collect', '--verbose'], + cwd: testFileDir, + }); + + expect(code).toBe(0); + expect(stdout).toContain('bundle-stats audits'); + + const report = await readJsonFile( + path.join(testFileDir, '.code-pushup', 'report.json'), + ); + expect(() => reportSchema.parse(report)).not.toThrowError(); + expect( + omitVariableReportData(report as Report, { omitAuditData: true }), + ).toMatchSnapshot(); + }); +}); diff --git a/e2e/plugin-bundle-stats-e2e/tsconfig.json b/e2e/plugin-bundle-stats-e2e/tsconfig.json new file mode 100644 index 0000000..f5a2f89 --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/tsconfig.json @@ -0,0 +1,20 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "module": "ESNext", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "types": ["vitest"] + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.test.json" + } + ] +} diff --git a/e2e/plugin-bundle-stats-e2e/tsconfig.test.json b/e2e/plugin-bundle-stats-e2e/tsconfig.test.json new file mode 100644 index 0000000..a56a1a3 --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/tsconfig.test.json @@ -0,0 +1,15 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "types": ["vitest/globals", "vitest/importMeta", "vite/client", "node"], + "target": "ES2020" + }, + "include": [ + "vitest.e2e.config.ts", + "tests/**/*.e2e.test.ts", + "tests/**/*.d.ts", + "mocks/**/*.ts", + "../../testing/test-setup/src/vitest.d.ts" + ] +} diff --git a/e2e/plugin-bundle-stats-e2e/vitest.e2e.config.ts b/e2e/plugin-bundle-stats-e2e/vitest.e2e.config.ts new file mode 100644 index 0000000..42332fd --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/vitest.e2e.config.ts @@ -0,0 +1,5 @@ +import { createE2ETestConfig } from '../../testing/test-setup-config/src/index.js'; + +export default createE2ETestConfig('plugin-bundle-stats-e2e', { + testTimeout: 80_000, +}); diff --git a/tsconfig.base.json b/tsconfig.base.json index 1229edf..6e14edf 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -16,6 +16,9 @@ "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { + "@code-pushup/bundle-stats-plugin": [ + "packages/plugin-bundle-stats/src/index.ts" + ], "@code-pushup/knip-plugin": ["packages/plugin-knip/src/index.ts"], "@code-pushup/stylelint-plugin": [ "packages/plugin-stylelint/src/index.ts" From 519137e658e4c859631935bcdd76dfbaf2da3f7d Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 10 Dec 2025 17:52:25 +0100 Subject: [PATCH 6/7] refactor: wip --- .../__snapshots__/collect.e2e.test.ts.snap | 23 +++++++++++++++++++ .../tests/collect.e2e.test.ts | 2 +- 2 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap diff --git a/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap new file mode 100644 index 0000000..9d19f1e --- /dev/null +++ b/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -0,0 +1,23 @@ +// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html + +exports[`PLUGIN collect report with bundle-stats-plugin NPM package > should run plugin over CLI and creates report.json 1`] = ` +{ + "packageName": "@code-pushup/core", + "plugins": [ + { + "audits": [ + { + "slug": "bundle-size", + "title": "Bundle Size", + }, + ], + "description": "Official Code PushUp Bundle Stats plugin.", + "docsUrl": "https://npm.im/@code-pushup/bundle-stats-plugin", + "icon": "folder-rules", + "packageName": "@code-pushup/bundle-stats-plugin", + "slug": "bundle-stats", + "title": "Bundle Stats", + }, + ], +} +`; \ No newline at end of file diff --git a/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts b/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts index ecfa219..0128f0c 100644 --- a/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts +++ b/e2e/plugin-bundle-stats-e2e/tests/collect.e2e.test.ts @@ -40,7 +40,7 @@ describe('PLUGIN collect report with bundle-stats-plugin NPM package', () => { }); expect(code).toBe(0); - expect(stdout).toContain('bundle-stats audits'); + expect(stdout).toContain('Bundle Stats audits'); const report = await readJsonFile( path.join(testFileDir, '.code-pushup', 'report.json'), From 0707eec61de2bd3c748c745e2f13f5545f8622a8 Mon Sep 17 00:00:00 2001 From: Michael Hladky Date: Wed, 10 Dec 2025 18:04:47 +0100 Subject: [PATCH 7/7] refactor: wip --- .../__snapshots__/collect.e2e.test.ts.snap | 17 + packages/plugin-bundle-stats/docs/wip.md | 2110 +++++++++++++++++ 2 files changed, 2127 insertions(+) create mode 100644 packages/plugin-bundle-stats/docs/wip.md diff --git a/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap b/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap index 9d19f1e..d389f8e 100644 --- a/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap +++ b/e2e/plugin-bundle-stats-e2e/tests/__snapshots__/collect.e2e.test.ts.snap @@ -7,12 +7,29 @@ exports[`PLUGIN collect report with bundle-stats-plugin NPM package > should run { "audits": [ { + "description": "Analyze bundle size and dependencies + +
+⚙️ Configuration + +- **Scoring:** + - Total Size: >\`976.56 kB\` threshold + +- **Issues:** + - Info: \`0\` violations - Analysis only, no penalties + +- **Selection:** + - Mode: \`bundle\` + - Include Outputs: \`dist/**/*.js\` + +
", "slug": "bundle-size", "title": "Bundle Size", }, ], "description": "Official Code PushUp Bundle Stats plugin.", "docsUrl": "https://npm.im/@code-pushup/bundle-stats-plugin", + "groups": [], "icon": "folder-rules", "packageName": "@code-pushup/bundle-stats-plugin", "slug": "bundle-stats", diff --git a/packages/plugin-bundle-stats/docs/wip.md b/packages/plugin-bundle-stats/docs/wip.md new file mode 100644 index 0000000..b3d92e6 --- /dev/null +++ b/packages/plugin-bundle-stats/docs/wip.md @@ -0,0 +1,2110 @@ +# 📦 **Bundle Budget Plugin** + +**Bundle size tracking for your build artifacts** +Track, compare, and prevent bundle size regressions to maintain web performance (e.g. LCP) across product areas. + +--- + +### 🧪 **Reference PR** + +👉 [**#1024 – BundleBudget Plugin PoC Implementation**](https://github.com/code-pushup/cli/pull/1024) + +--- + +## User story + +As a developer, I want to **track bundle size regressions per product area and route**, +so that we can **avoid performance regressions** and optimize **LCP over time**. + +The plugin should: + +- Analyze `stats.json` output from different bundler. +- Identify and compare **main**, **initial**, and **lazy** chunks over glob matching +- Use **chunk input fingerprinting** to map renamed chunk files. +- Group chunk sizes by route/product (e.g., `/route-1`, `/route-2`). +- give penalties for site and blacklisted imports +- visualise inputs as well as static imports as they directly contribute to the real bundle size. +- Store and compare bundle stats across versions/releases. + +## Metric + +**Bundle size** in bytes. +Parsed from `--stats-json` output and grouped by file. + +| **Property** | **Value** | **Description** | +| ---------------- | -------------------: | ----------------------------------- | +| **value** | `132341` | Total size of all chunks. | +| **displayValue** | `13.4 MB / 13 Files` | Display value inc. number of files. | + +## Integration Requirements + +The plugin can be implemented in 2 ways: + +1. Using stats files +2. Crawling the filesystem + +As stats file serve significantly more details and are state of the art when debugging bundle size this issue favours this approach. + +### Using Stats Files + +Bundle stats are detailed metadata about your build outputs—listing each generated file, its original inputs, and any static imports—exported via a metafile (e.g. from ESBuild or other bundlers). + +Generate a stats file with ESBuild: + +```shell +esbuild src/index.js --bundle --outfile=dist/bundle.js --metafile=stats.json +``` + +The resulting file maintains the following data structure: + +```txt +EsbuildBundleStats # Root object containing all bundle stats +├── inputs (Record) # Map of each source input file to its metadata +│ └── # File path of a specific input module +│ ├── bytes: number # Size of this input module in bytes +│ └── imports (MetafileImport[]) # List of static imports declared by this input +│ └── [ ] # Array of import entries +│ ├── path: string # Resolved filesystem path of the imported module +│ ├── kind: ImportKind # Import type (e.g. "import", "require", "dynamic") +│ ├── external?: boolean # True if marked external (excluded from bundle) +│ └── original?: string # Original import specifier in source code +└── outputs (Record)# Map of each generated output file to its metadata + └── # File path of a specific output chunk + ├── bytes: number # Total size of this output file in bytes + ├── inputs (Record) # Map of input modules contributing to this output + │ └── # Path of an input that fed into this output + │ └── bytesInOutput: number # Number of bytes this input contributed to the output + ├── imports (MetafileImport[]) # List of static imports found in this output + │ └── [ ] # Array of import entries + │ ├── path: string # Resolved filesystem path of the imported module + │ ├── kind: ImportKind # Import type (e.g. "import", "require", "dynamic") + │ ├── external?: boolean # True if marked external (excluded from bundle) + │ └── original?: string # Original import specifier in source code + ├── exports: string[] # List of named exports provided by this bundle + └── entryPoint?: string # Entry-point module path for this output chunk, if any +``` + +#### File Type Definitions + +| **Type** | **Structure** | **Description** | +| --------------: | -------------------------------- | ------------------------------------------------------------------------------------------- | +| `inputs` | `Record` | Map of each source file path to its metadata (bytes and imports). | +| `imports` | `MetafileImport[]` | Array of import entries, each with `path`, `kind`, and optional flags. | +| 📄 `outputs` | `Record` | Map of each output file path to its metadata (bytes, inputs, imports, exports, entryPoint). | +| 📍 `entryPoint` | `string` (optional) | The entry-point module path for this output chunk, if present. | + +The plugin will use this information to gather the configured artefact groups. + +### Crawling the filesystem + +> [!note] +> No research done as not scaleable + +## Setup and Requirements + +### 📦 Package Dependencies + +- **Dev Dependencies:** + - None required, optional CLI runner for local debugging. +- **Optional Dependencies:** + - [esbuild](https://www.npmjs.com/package/esbuild) + - [rsbuild](https://www.npmjs.com/package/rsbuild) + - [webpack](https://www.npmjs.com/package/webpack) + - [vite](https://www.npmjs.com/package/vite) + - or any tool that emits `--metafile`/`stats.json`. + +### 📝 Configuration Files + +- `angular.json` / `vite.config.ts` or equivalent – for custom build config. +- No required config file for the plugin itself. + +--- + +### Bundle Stats + +The following is a minimal stats representation used to explain different features of the plugin. It will be referred to as **Example Stats**. + +``` +stats.json +└── outputs + ├── dist/index.js // entryPoint: src/index.ts + │ ├── inputs + │ │ └── src/index.ts + │ │ ├── src/lib/feature-1.ts // import-statement + │ │ │ └── src/lib/utils/format.ts // import-statement + │ │ ├── src/lib/utils/math.ts // import-statement + │ │ └── src/lib/feature-2.ts // dynamic-import + │ └── imports + │ ├── dist/chunks/chunk-U6O5K65G.js // import-statement + │ └── dist/chunks/feature-2-X2YVDBQK.js // dynamic-import + ├── dist/bin.js // entryPoint: src/bin.ts + │ ├── inputs + │ │ └── src/bin.ts + │ │ ├── src/lib/feature-1.ts // import-statement + │ │ │ └── src/lib/utils/format.ts // import-statement + │ │ └── src/lib/utils/math.ts // import-statement + │ └── imports + │ └── dist/chunks/chunk-U6O5K65G.js // import-statement + ├── dist/chunks/chunk-U6O5K65G.js + │ └── inputs + │ ├── src/lib/utils/format.ts + │ ├── src/lib/feature-1.ts + │ └── src/lib/utils/math.ts + └── dist/chunks/feature-2-X2YVDBQK.js // entryPoint: src/lib/feature-2.ts + └── inputs + └── src/lib/feature-2.ts +``` + +## Features + +@TODO + +### General + +The audit name is provided over the `title` property. Internally a audit `slug` is derived from the + +- **`title`**: A unique identifier for this group. +- **`description`**: One two sentences explaining the purpose of the audit + +**Types** + +```ts +type Audit = { + slug?: string; + title: string; + description?: string; +}; +``` + +**Example Configuration** + +```ts +const audit1: Audit = { + title: 'Initial Bundles', +}; + +const audit2: Audit = { + slug: 'app-core', + title: '🧱App Core', + description: 'This audit checks the core functionality of the app.', +}; +``` + +Every audit gets the merged configuration of the global and audit specific configuration listed in the description. + +**Configuration Example** + +```ts +const config: BundleStatsConfig = { + title: 'Initial Bundles', + description: 'This audit checks the initial bundles of the app.', +}; +``` + +**Report Output** + +```txt +This audit checks the initial bundles of the app. +
+⚙️ Config Summary + +**Selection** +• `includeOutputs`: `**/*` + +**Scoring** +• `totalSize`: `0 B – 97.66 kB` + +**Insights** +• 🔧 `**/math.ts` +• 🔧 `**/format.ts` +• 🧩 `**/*feature-2*` +• 🏁 `src/index.ts, src/bin.ts` +• 🤝 `dist/chunks/chunk-*.js` +• 📦 `**/node_modules/**` +• 📦 `dist/index.js, dist/bin.js` + +
+``` + +### Selection + +To select files for an audit, glob patterns are used to include and exclude parts of the output files. +All options are provided as glob patterns matching either `path`, `path` in `inputs` or `entryPoint`. + +**Types** + +```ts +export interface SelectionOptions { + mode: 'bundle' | 'onlyMatching' | 'withAllDeps' | 'withStartupDeps'; + + // targeting output path of a `OutputNode` + includeOutputs: string[]; + excludeOutputs: string[]; + + // targeting input paths of a `OutputNode` + includeInputs: string[]; + excludeInputs: string[]; +} +``` + +**Example Configuration** + +```ts +const selection: SelectionOptions = { + mode: 'bundle', + includeOutputs: ['**/features/*'], + excludeOutputs: ['**/features/legacy/**'], + excludeInputs: ['**/ui/**'], +}; +``` + +#### Selection Behaviour + +- **🎯Glob syntax**: Supports standard glob patterns like `*`, `**`, `?`, `[abc]`. +- **Include → Exclude**: Selection starts with `include*` patterns (for outputs and inputs), followed by `exclude*` to remove matches. +- **Precedence**: If a file matches both `include` and `exclude`, it will be excluded. +- **🔗 Dependency handling** is controlled by `mode`: + - `'bundle'` and `'onlyMatching'` ignore imports. + - `'withAllDependencies'` and `'withStartupDependencies'`: preserve imports even if excluded + +--- + +> All examples target this stats data. +> +> **Example Stats** +> +> The following is a minimal stats representation used to explain different features of the selection process. +> +> ``` +> stats.json +> └── outputs +> ├── dist/index.js 309kB // entryPoint: src/index.ts +> │ ├── inputs +> │ │ └── src/index.ts +> │ │ ├── src/lib/feature-1.ts 100kB // import-statement +> │ │ │ └── src/lib/utils/format.ts 100kB // import-statement +> │ │ ├── src/lib/utils/math.ts 100kB // import-statement +> │ │ └── src/lib/feature-2.ts 100kB // dynamic-import +> │ └── imports +> │ ├── dist/chunks/chunk-U6O5K65G.js // import-statement +> │ └── dist/chunks/feature-2-X2YVDBQK.js // dynamic-import +> ├── dist/bin.js 309kB // entryPoint: src/bin.ts +> │ ├── inputs +> │ │ ├── src/lib/feature-1.ts 100kB // import-statement +> │ │ │ └── src/lib/utils/format.ts 100kB // import-statement +> │ │ └── src/lib/utils/math.ts 100kB // import-statement +> │ └── imports +> │ └── dist/chunks/chunk-U6O5K65G.js // import-statement +> ├── dist/chunks/chunk-U6O5K65G.js 309kB +> │ └── inputs +> │ ├── src/lib/utils/format.ts 100kB +> │ ├── src/lib/feature-1.ts 100kB +> │ └── src/lib/utils/math.ts 100kB +> └── dist/chunks/feature-2-X2YVDBQK.js 109kB // entryPoint: src/lib/feature-2.ts +> └── inputs +> └── src/lib/feature-2.ts 100kB +> +> ``` + +--- + +##### Include Output + +Select only `dist/index.js` and its dependencies. + +**Selection Options** + +```ts +{ + includeOutputs: ['**/dist/index.js']; +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js // entryPoint: src/index.ts + │ ├── inputs + │ └── imports + │ └── dist/chunks/chunk-U6O5K65G.js // import-statement + └── 🔗 dist/chunks/chunk-U6O5K65G.js // imported by `dist/index.js` + └── inputs +``` + +The target output and its imported dependencies are included. + +##### Include/Exclude Output + +Select all outputs except bin files. + +**Selection Options** + +```ts +{ + includeOutputs: ["**/*"], + excludeOutputs: ["**/bin.js"] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js // entryPoint: src/index.ts + ├── 🔗 dist/chunks/chunk-U6O5K65G.js // imported by `dist/index.js` + ├── 🔗 dist/chunks/feature-2-X2YVDBQK.js // imported by `dist/index.js` + └── // excluded: dist/bin.js +``` + +All outputs are included except those matching the exclude pattern. + +##### Include Input + +Select outputs that contain specific input files. + +**Selection Options** + +```ts +{ + includeInputs: ['**/feature-2.ts']; +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── dist/index.js // entryPoint: src/index.ts + │ └── inputs + │ └── src/index.ts + │ └── 🎯 src/lib/feature-2.ts // dynamic-import + └── 🔗 dist/chunks/feature-2-X2YVDBQK.js // contains feature-2.ts + └── inputs + └── 🎯 src/lib/feature-2.ts +``` + +Only outputs containing the specified input files are included. + +##### Include/Exclude Input + +Select all outputs but exclude those containing feature-2 files. + +**Selection Options** + +```ts +{ + includeOutputs: ["**/*"], + excludeInputs: ["**/feature-2.ts"] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/bin.js // entryPoint: src/bin.ts + ├── 🔗 dist/chunks/chunk-U6O5K65G.js // imported by `dist/bin.js` + ├── // excluded: dist/index.js (contains feature-2.ts) + └── // excluded: dist/chunks/feature-2-X2YVDBQK.js (contains feature-2.ts) +``` + +Outputs containing the excluded input files are filtered out. + +##### Include/Exclude Mixed + +Select feature outputs but exclude utility files. + +**Selection Options** + +```ts +{ + includeOutputs: ['**/features/*', '**/index.js'], + excludeOutputs: ['**/bin.js'], + excludeInputs: ['**/utils/**'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js // matches includeOutputs + │ └── inputs + │ └── src/index.ts + │ ├── src/lib/feature-1.ts 100kB + │ └── src/lib/feature-2.ts 100kB + └── 🔗 dist/chunks/feature-2-X2YVDBQK.js // imported by `dist/index.js` + └── inputs + └── src/lib/feature-2.ts 100kB +``` + +Complex filtering combines output and input patterns for precise selection. + +--- + +##### Mode: `onlyMatching` + +Select only input files that match a pattern — exclude outputs, imports, and bundler overhead. + +**Selection Options** + +```ts +{ + mode: 'onlyMatching', + includeInputs: ['**/lib/utils/format.ts'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── dist/chunks/chunk-U6O5K65G.js 100kB // excludes overhead + └── inputs + └── 🎯 src/lib/utils/format.ts 100kB // matches `includeInputs` +``` + +Only the bytes from matching input files are counted, excluding bundler overhead. + +##### Mode: `bundle` + +Include the full output bundle with overhead and its bundled inputs but not external chunks. + +**Selection Options** + +```ts +{ + mode: 'bundle', + includeOutputs: ['**/dist/index.js'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + └── 🎯 dist/index.js 209kB // matches `includeOutputs` + └── inputs + ├── src/lib/utils/format.ts 100kB + └── src/lib/utils/math.ts 100kB +``` + +Only what's bundled directly in the output file is included. + +##### Mode: `withStartupDeps` + +Include the output and all static imports required at startup. + +**Selection Options** + +```ts +{ + mode: 'withStartupDeps', + includeOutputs: ['**/dist/index.js'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js 209kB + │ └── inputs + │ ├── src/lib/utils/format.ts 100kB + │ └── src/lib/utils/math.ts 100kB + └── 🔗 dist/chunks/chunk-U6O5K65G.js 109kB // statically imported by `dist/index.js` + └── inputs + └── src/lib/utils/log.ts 100kB +``` + +Static imports are preserved even if they would be excluded by patterns. + +##### Mode: `withAllDeps` + +Include the output and all imported files — both static and dynamic. + +**Selection Options** + +```ts +{ + mode: 'withAllDeps', + includeOutputs: ['**/dist/index.js'] +} +``` + +**Selection Result:** + +``` +stats.json +└── outputs + ├── 🎯 dist/index.js 209kB + │ └── inputs + │ ├── src/lib/utils/format.ts 100kB + │ └── src/lib/utils/math.ts 100kB + ├── 🔗 dist/chunks/chunk-U6O5K65G.js 109kB // static import + │ └── inputs + │ └── src/lib/utils/log.ts 100kB + └── 🔗 dist/chunks/feature-2-X2YVDBQK.js 109kB // dynamic import + └── inputs + └── src/lib/feature-2.ts 100kB +``` + +Both static and dynamic dependencies are included in their entirety. + +### Scoring + +> **What makes up the output bytes:** +> +> - **Inputs**: Sum of `bytesInOutput` from contributing files +> - **Overhead**: Bundler-generated code (runtime, wrappers, loaders, etc.) +> +> 📌 `output.bytes = inputs + overhead` + +The plugin assigns a **score** in the range `[0 … 1]` to each artefact (or artefact selection) based on: + +1. **Size** vs. a configurable maximum threshold +2. **Diagnostics penalties** (errors & warnings, including blacklist violations as warnings) + +A perfect score (`1`) means “within budget”; lower values indicate regressions. + +The selection process of a scored set of files is explained in detail in [File Selection](#File-Selection) + +**Types** + +```ts + +export interface ScoringOptions { + // targeting output path of a `OutputNode` + totalSize: number | MinMax; + penalty: { + artefactSize?: number | MinMax; + blacklist?: string[]; + } +``` + +**Example Configuration** + +```ts +const selection: SelectionOptions = { + includeOutputs: ['**/features/*'], + excludeOutputs: ['**/features/legacy/**'], + excludeInputs: ['**/ui/**'], + includeEntryPoints: ['**/features/auth/*.ts'], +}; +``` + +#### Total Size + +Every artefact selection has budgets assigned under `budget`. + +- **`totalSize`**: Total bytes of all files in a selection. + +**Examples** + +```ts +const scoring1: Scoring = { + totalSize: 300_000, +}; + +const scoring2: Scoring = { + totalSize: [10_000, 300_000], +}; +``` + +#### Panelties + +To give actionable feedback to users of the plugin you can add penalties a set of penalties: + +- **`artefactSize`**: Byte size of a files in a selection. +- **`blacklist`**: List of globs to flag inputs as well as imports as forbidden + +**Types** + +```ts +type Penalty = { + artefactSize?: number | MinMax; + blacklist?: string[]; +}; +``` + +**Example Configuration** + +```ts +const penalty1: Penalty = { + artefactSize: 50_000, +}; + +const penalty2: Penalty = { + artefactSize: [1_000, 50_000], + blacklist: ['node_modules/old-charting-lib'], +}; +``` + +#### Scoring Parameters + +| **Parameter** | **Description** | +| ------------: | ---------------------------------------------------------------------- | +| `S` | Actual bytes | +| `M` | Size threshold bytes | +| `E` | Count of issues of severity errors (🚨) | +| `W` | Count of issues of severity warnings (⚠️), including blacklist matches | +| `we` | Weight per error (default `1`) | +| `ww` | Weight per warning (default `0.5`) | + +##### Size score + +$` +\mathrm{sizeScore} = +\begin{cases} +1, & S \le M\\[6pt] +\max\bigl(0,\;1 - \tfrac{S - M}{M}\bigr), & S > M +\end{cases} +`$ + +##### Issues penalty + +$` +\mathrm{penalty} = we \times E \;+\; ww \times W +`$ + +##### Final blended score + +$` +\mathrm{finalScore} = \max\!\Bigl(0,\;\mathrm{sizeScore} - \frac{\mathrm{penalty}}{we + ww}\Bigr) +`$ + +```mermaid +xychart-beta + title "Score vs Artifact Size (with penalty shift)" + x-axis [0, 1, 1.25, 1.5, 1.75, 2] + y-axis "Score" 0 --> 1 + line Original [1, 1, 0.75, 0.5, 0.25, 0] + line Penalized [0.5, 0.5, 0.25, 0, 0, 0] +``` + +### Issues + +To give users actionable feedback we need to be able to tell _WHAT_ happened, _WHERE_ it is, and _HOW_ to fix it. + +Issues are configured per audit under the `scoring.penalty` property. +The plugin creates **diagnostics** for each penalty. The table below shows all diagnostic types: + +| Diagnostic | Description | Config Key | Default | Severity | Recommended Action | +| --------------- | ----------------------------------------------------------------------------------------------------- | ----------------- | ------- | -------- | ----------------------------------------------------------------------- | +| **Blacklisted** | Artifact contains an import matching a forbidden glob pattern. | `blacklist` | — | 🚨 Error | Remove or replace the forbidden dependency. | +| **Too Large** | Artifact exceeds the maximum allowed size. May indicate an unoptimized bundle or accidental check-in. | `maxArtifactSize` | `5 MB` | 🚨 Error | Review and optimize (e.g. code splitting, compression). | +| **Too Small** | Artifact is below the minimum expected size. Could signal missing dependencies or incomplete build. | `minArtifactSize` | `1 KB` | ⚠️ Warn | Verify that the build output is complete and dependencies are included. | + +#### Too Large Issues + +Artifacts that exceed the maximum allowed size threshold. This typically indicates unoptimized bundles, accidental inclusion of large files, or missing code splitting strategies. + +**Configuration**: `scoring.artifactSize` + +**Example Issues:** + +| Severity | Message | Source file | Location | +| -------- | ----------------------------------------------------------------------------------------------- | -------------------- | -------- | +| 🚨 error | `main.js` is **6.12 MB** (exceeds 5 MB); consider splitting or compressing this bundle. | `dist/lib/main.js` | | +| 🚨 error | `vendor.js` is **2.05 MB** (exceeds 1.5 MB); apply tree-shaking or extract shared dependencies. | `dist/lib/vendor.js` | | + +**Use Cases**: + +- **Code Splitting**: Break large bundles into smaller chunks +- **Tree Shaking**: Remove unused code from dependencies +- **Compression**: Enable gzip/brotli compression +- **Asset Optimization**: Optimize images and other assets +- **Lazy Loading**: Load code only when needed + +#### Too Small Issues + +Artifacts that fall below the minimum expected size threshold. This could signal missing dependencies, incomplete builds, or configuration issues. + +**Configuration**: `scoring.artifactSize` + +**Example Issues:** + +| Severity | Message | Source file | Location | +| ---------- | ---------------------------------------------------------------------------------------- | --------------------- | -------- | +| ⚠️ warning | `utils.js` is **50 kB** (below 100 kB); confirm that expected dependencies are included. | `dist/lib/utils.js` | | +| ⚠️ warning | `styles.css` is **10 B** (below 1 kB); confirm that expected dependencies are included. | `dist/lib/styles.css` | | + +**Use Cases**: + +- **Dependency Check**: Verify all required dependencies are included +- **Build Verification**: Ensure the build process completed successfully +- **Configuration Review**: Check bundler configuration for missing entries +- **Source Validation**: Confirm source files contain expected content + +#### Blacklisted Issues + +Artifacts containing imports that match forbidden glob patterns. This helps enforce dependency policies and prevent usage of deprecated or unsafe libraries. + +**Configuration**: `scoring.blacklist` + +**Example Issues:** + +| Severity | Message | Source file | Location | +| -------- | -------------------------------------------------------------------------------------------------------- | --------------------- | -------- | +| 🚨 error | `node_modules/old-charting-lib/index.js` matches a blacklist pattern; remove or replace this dependency. | `src/main-ASDFGAH.js` | | + +**Use Cases**: + +- **Dependency Replacement**: Replace blacklisted libraries with approved alternatives +- **Code Refactoring**: Remove usage of forbidden dependencies +- **Policy Review**: Update dependency policies if needed +- **Security Audit**: Investigate security implications of blacklisted dependencies + +### Insights Table + +The insights table summarizes different areas of the selected files by grouping data based on patterns. It aggregates bytes from outputs, their inputs, and overhead. + +**Process for accurate data:** + +For each **group**, evaluate its **patterns** and: + +- Sum bytes from inputs whose paths match the pattern +- Include output file bytes if the file path matches the pattern (including bundler overhead) + +Each byte can only be assigned once to avoid duplication. + +**After processing:** + +- Unmatched bytes go to the fallback "_Rest_" group +- Remaining bundler overhead (from unmatched outputs) is also included in _Rest_ + +**Types** + +```ts +type InsightsOptions = { + title?: string; + patterns: string[]; + icon?: string; +}[]; +``` + +**Complete Example Configuration** + +```ts +const insightsOptions: InsightsOptions = [ + { + title: 'App Shell', + icon: '🖥️', + patterns: ['**/app/**', '**/main.ts'], + }, + { + title: 'Angular', + icon: '🅰️', + patterns: [ + '**/node_modules/@angular/**', + '**/node_modules/ngx-*/**', + '**/node_modules/@ngrx/**', + '**/node_modules/ng-*/**', + '**/node_modules/*angular*', + '**/zone.js/**', + ], + }, + { + title: 'Styles', + icon: '🎨', + patterns: ['**/*.css', '**/*.scss'], + }, + { + title: 'Shared Utilities', + icon: '🧩', + patterns: ['**/shared/**', '**/utils/**'], + }, + { + title: 'Feature: Checkout', + icon: '🛒', + patterns: ['**/features/checkout/**'], + }, + { + title: 'Feature: Profile', + icon: '👤', + patterns: ['**/features/profile/**'], + }, + { + title: 'Third-party Vendors', + icon: '📦', + patterns: ['**/node_modules/**'], + }, +]; +``` + +**Example Output:** + +| Group | Size | Modules | +| ---------------------- | -------- | ------- | +| 📦 Third-party Vendors | 1.78 MB | 152 | +| 🖥️ App Shell | 85.32 kB | 14 | +| 🅰️ Angular | 236.4 kB | 19 | +| 🎨 Styles | 12.2 kB | 7 | +| 🧩 Shared Utilities | 98.3 kB | 28 | +| 🛒 Feature: Checkout | 142.9 kB | 33 | +| 👤 Feature: Profile | 65.7 kB | 21 | +| Rest | 27.4 kB | 6 | + +### Dependency Tree + +The dependency tree provides users with a quick understanding of the dependencies graph of selected artifacts. It serves as a replacement for opening bundle stats in the browser to search for respective files. + +**Types** + +```ts +export type ViewMode = 'all' | 'onlyMatching'; + +export type GeneralViewConfig = { + enabled: boolean; + mode: ViewMode; +}; + +export type DependencyTreeConfig = GeneralViewConfig & { + groups: GroupingRule[] | false; + pruning: PruningConfig; +}; + +export interface GroupingRule { + include: string | string[]; + exclude?: string | string[]; + title?: string; + icon?: string; + numSegments?: number; +} + +export interface PruningConfig { + maxChildren?: number; + maxDepth?: number; + startDepth?: number; + minSize?: number; + pathLength?: number | false; +} +``` + +**Example Configuration** + +```ts +const treeConfig: DependencyTreeConfig = { + mode: 'all', + groups: [ + { + title: 'Angular Router', + include: ['node_modules/@angular/router/**'], + exclude: ['**/*.spec.ts'], + icon: '🅰️', + numSegments: 3, + }, + ], + pruning: { + maxChildren: 3, + maxDepth: 2, + startDepth: 1, + minSize: 10_000, + pathLength: 50, + }, +}; +``` + +--- + +> All examples target this stats data structure. +> +> **Example Stats** +> +> ``` +> stats.json +> └── outputs +> └── dist/index.js 400kB +> ├── inputs +> │ ├── src/index.ts 50kB +> │ ├── src/lib/feature-1.ts 100kB +> │ └── src/lib/utils/format.ts 75kB +> └── imports +> └── dist/chunks/vendor.js +> ``` + +--- + +#### Mode: `all` + +Shows complete dependency tree including all outputs, inputs, and imports with full bundler overhead. + +**Tree Configuration** + +```ts +{ + mode: 'all'; +} +``` + +**Tree Result:** + +```txt +example-group +├── dist/index.js +│ ├── src/index.ts +│ ├── src/lib/feature-1.ts +│ └── src/lib/utils/format.ts +├── dist/chunks/vendor.js +│ └── node_modules/@angular/router/index.ts +└── dist/styles.css +``` + +#### Mode: `onlyMatching` + +Shows only the bytes that match selection patterns, excluding bundler overhead. + +**Tree Configuration** + +```ts +{ + mode: 'onlyMatching'; +} +``` + +**Tree Result:** + +```txt +example-group +├── dist/index.js +│ ├── src/index.ts +│ ├── src/lib/feature-1.ts +│ └── src/lib/utils/format.ts +├── dist/chunks/vendor.js +│ └── node_modules/@angular/router/index.ts +└── dist/styles.css +``` + +--- + +#### Grouping - Disabled + +**Tree Result:** + +```txt +example-group +└── entry-2.js + ├── node_modules/@angular/router/provider.ts + ├── node_modules/@angular/router/service.ts + │ └── node_modules/@angular/router/utils.ts + └── node_modules/lodash/chunk.js +``` + +#### Grouping - Basic + +**Grouping Configuration** + +```ts +{ + groups: [ + { + title: 'Angular Router', + include: ['node_modules/@angular/router/**'], + exclude: ['**/*.spec.ts'], + icon: '🅰️', + }, + ]; +} +``` + +**Tree Result:** + +```txt +example-group +└── entry-2.js + ├── 🅰️ Angular Router + │ ├── node_modules/@angular/router/provider.ts + │ ├── node_modules/@angular/router/service.ts + │ └── node_modules/@angular/router/utils.ts + └── node_modules/lodash/chunk.js +``` + +#### Grouping - Include/Exclude + +GroupingRule supports flexible pattern matching with include/exclude logic: + +- **`include`**: Patterns to match files for inclusion in the group +- **`exclude`**: Patterns to exclude from the group (optional) +- **Pattern precedence**: Files matching both include and exclude will be excluded + +**Advanced Grouping Configuration** + +```ts +{ + groups: [ + { + title: 'React Components', + include: ['**/components/**/*.tsx', '**/components/**/*.jsx'], + exclude: ['**/*.test.*', '**/*.spec.*'], + icon: '⚛️', + }, + { + title: 'Node Modules', + include: ['node_modules/**'], + exclude: ['node_modules/**/*.d.ts'], + icon: '📦', + }, + ]; +} +``` + +#### Grouping - NumSegments + +The `numSegments` property controls how files are grouped by their path structure. + +**Without numSegments:** + +```txt +example-group +└── entry.js + ├── src/components/ui/Button.tsx + ├── src/components/ui/Modal.tsx + ├── src/components/forms/Input.tsx + └── src/components/forms/Select.tsx +``` + +**Grouping Configuration** + +```ts +{ + groups: [ + { + title: 'Components', + include: ['**/components/**'], + numSegments: 2, + }, + ]; +} +``` + +**With numSegments:** + +```txt +example-group +└── entry.js + └── Components + ├── ui + │ ├── Button.tsx + │ └── Modal.tsx + └── forms + ├── Input.tsx + └── Select.tsx +``` + +--- + +#### Pruning - MaxChildren + +**Unpruned:** + +```txt +example-group +├── index.js +│ ├── src/app.ts +│ ├── src/components/Header.ts +│ ├── src/components/Footer.ts +│ ├── src/utils/math.ts +│ └── src/main.css +├── vendor.js +│ ├── node_modules/react.ts +│ ├── node_modules/react-dom.ts +│ └── node_modules/lodash.js +└── logo.svg +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + maxChildren: 3, + maxDepth: 2 + } +} +``` + +**Pruned Result:** + +```txt +example-group +├── index.js +│ ├── src/app.ts +│ ├── src/components/Header.ts +│ └── … 3 more inputs +├── vendor.js +│ ├── node_modules/react.ts +│ └── … 2 more inputs +└── logo.svg +``` + +#### Pruning - MinSize + +**With small files:** + +```txt +example-group 840 kB 10 files +└── index.js 840 kB 9 files + ├── src/app.js 400 kB + ├── src/large-1.js 200 kB + ├── src/medium-1.js 100 kB + ├── src/small-1.js 30 kB + ├── src/small-2.js 25 kB + ├── src/small-3.js 20 kB + └── … 4 more files 65 kB +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + minSize: 50_000; + } +} +``` + +**Pruned Result:** + +```txt +example-group 840 kB 10 files +└── index.js 840 kB 9 files + ├── src/app.js 400 kB + ├── src/large-1.js 200 kB + ├── src/medium-1.js 100 kB + └── … 6 more files 140 kB +``` + +--- + +#### Pruning - StartDepth + +Controls the depth at which the tree analysis begins, useful for skipping top-level wrapper nodes. + +**Without startDepth:** + +```txt +example-group +└── main-bundle + └── app-core + ├── src/components/Button.tsx + ├── src/components/Modal.tsx + └── src/utils/helpers.ts +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + startDepth: 2; + } +} +``` + +**With startDepth:** + +```txt +example-group +├── src/components/Button.tsx +├── src/components/Modal.tsx +└── src/utils/helpers.ts +``` + +#### Pruning - PathLength + +Controls how long file paths can be before truncation, or disables truncation entirely. + +**Full path:** + +```txt +example-group +└── src/lib/utils/helper/format/left-pad.js +``` + +**Pruning Configuration** + +```ts +{ + pruning: { + pathLength: 30; + } +} +``` + +**Shortened path:** + +```txt +example-group +└── src/.../left-pad.js +``` + +**Disable truncation:** + +```ts +{ + pruning: { + pathLength: false; + } +} +``` + +--- + +#### Formatting - Size + +**Raw bytes:** + +```txt +example-group 537170 +└── main.js 300000 +``` + +**Formatted:** + +```txt +example-group 537.17 kB +└── main.js 300 kB +``` + +#### Formatting - Pluralization + +**Unpluralized:** + +```txt +example-group 3 +├── main.js 1 +└── utils.js 2 +``` + +**Pluralized:** + +```txt +example-group 3 modules +├── main.js 1 module +└── utils.js 2 modules +``` + +#### Formatting - RedundantInfo + +**With redundancy:** + +```txt +example-group 300 kB 3 modules +└── index.js 100 kB 1 module + ├── src/app.js 100 kB 1 module + └── … 2 more inputs 200 kB 2 modules +``` + +**Cleaned up:** + +```txt +example-group 300 kB 3 modules +└── index.js 100 kB + ├── src/app.js + └── … 2 more inputs 200 kB +``` + +### Insights Table + +The grouping table provides a summary view of bundle statistics organized by user-defined groups. It aggregates file sizes and counts for quick analysis of different parts of your bundle. + +**Types** + +```ts +export type PatternList = readonly string[]; + +export type SharedViewConfig = { + enabled?: boolean; + mode?: 'onlyMatching' | 'all'; +}; + +export interface TablePruningConfig { + enabled?: boolean; + maxChildren?: number; + minSize?: number; +} + +export type InsightsTableConfig = SharedViewConfig & { + groups: GroupingRule[]; + pruning?: TablePruningConfig; +}; + +export interface GroupingRule { + includeInputs: string | PatternList; + excludeInputs?: string | PatternList; + title?: string; + icon?: string; + numSegments?: number; +} +``` + +**Example Configuration** + +```ts +const tableConfig: InsightsTableConfig = { + mode: 'all', + groups: [ + { + title: 'Features', + includeInputs: ['**/feature-*.ts'], + excludeInputs: ['**/*.spec.ts'], + icon: '🎯', + }, + { + title: 'Utils', + includeInputs: ['**/utils/**'], + icon: '🔧', + }, + ], + pruning: { + enabled: true, + maxChildren: 10, + minSize: 1000, + }, +}; +``` + +--- + +> All examples target this stats data structure. +> +> **Example Stats** +> +> ``` +> stats.json +> └── outputs +> ├── dist/app.js 300kB +> │ ├── inputs +> │ │ ├── src/index.ts 50kB +> │ │ ├── src/feature-1.ts 100kB +> │ │ ├── src/feature-2.ts 75kB +> │ │ └── src/utils/format.ts 25kB +> │ └── imports +> │ └── dist/chunks/vendor.js +> └── dist/chunks/vendor.js 200kB +> └── inputs +> └── node_modules/lodash/index.js 150kB +> ``` + +--- + +#### Mode: `all` + +Shows complete bundle statistics including outputs, inputs, imports and bundler overhead. + +**Table Configuration** + +```ts +{ + mode: 'all', + groups: [ + { + title: 'Features', + includeInputs: ['**/feature-*.ts'] + } + ] +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ----------- | ------- | ------ | +| 🎯 Features | 2 | 175 kB | +| Rest | - | 325 kB | + +#### Mode: `onlyMatching` + +Shows only the bytes that match selection patterns, excluding bundler overhead. + +**Table Configuration** + +```ts +{ + mode: 'onlyMatching', + groups: [ + { + title: 'Features', + includeInputs: ['**/feature-*.ts'] + } + ] +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ----------- | ------- | ------ | +| 🎯 Features | 2 | 175 kB | + +--- + +#### Grouping - Include + +Select files using single or multiple glob patterns. + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Source Code', + includeInputs: ['**/src/**/*.ts', '**/src/**/*.tsx'], + }, + ]; +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ----------- | ------- | ------ | +| Source Code | 4 | 250 kB | +| Rest | - | 250 kB | + +#### Grouping - Include/Exclude + +Combine include and exclude patterns for precise file selection. + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Application Code', + includeInputs: '**/src/**', + excludeInputs: ['**/utils/**', '**/*.spec.ts'], + }, + ]; +} +``` + +**File Matching:** + +```txt +stats.json +└── outputs + └── dist/app.js + ├── 🎯 src/index.ts // included by **/src/** + ├── 🎯 src/feature-1.ts // included by **/src/** + ├── 🎯 src/feature-2.ts // included by **/src/** + └── ❌ src/utils/format.ts // excluded by **/utils/** +``` + +**Table Result:** + +| Group | Modules | Size | +| ---------------- | ------- | ------ | +| Application Code | 3 | 225 kB | +| Rest | - | 275 kB | + +#### Grouping - Icons and Titles + +Customize group display with icons and titles, or let titles be auto-generated from patterns. + +**Manual Titles with Icons:** + +```ts +{ + groups: [ + { + title: 'Core Features', + includeInputs: '**/features/**/*.ts', + icon: '🎯', + }, + { + title: 'Shared Utils', + includeInputs: '**/shared/**', + icon: '🔧', + }, + { + title: 'Third Party', + includeInputs: 'node_modules/**', + icon: '📦', + }, + ]; +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ---------------- | ------- | ------ | +| 🎯 Core Features | 8 | 450 kB | +| 🔧 Shared Utils | 12 | 125 kB | +| 📦 Third Party | 45 | 2.1 MB | +| Rest | - | 75 kB | + +**Auto-Generated Titles:** + +```ts +{ + groups: [ + { + includeInputs: '**/components/feature-*.tsx', + }, + { + includeInputs: ['**/utils/**', '**/helpers/**'], + }, + ]; +} +``` + +**Table Result:** + +| Group | Modules | Size | +| --------------------- | ------- | ------ | +| components/feature-\* | 5 | 175 kB | +| utils/**, helpers/** | 8 | 125 kB | +| Rest | - | 200 kB | + +#### Grouping - NumSegments + +Control how paths are grouped using the `numSegments` property for hierarchical organization. + +**Without numSegments:** + +```txt +└── src/components/ui/Button.tsx +├── src/components/ui/Modal.tsx +├── src/components/forms/Input.tsx +└── src/components/forms/Select.tsx +``` + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Components', + includeInputs: '**/components/**', + numSegments: 2, + }, + ]; +} +``` + +**With numSegments (creates subgroups):** + +```txt +└── Components + ├── ui (Button.tsx, Modal.tsx) + └── forms (Input.tsx, Select.tsx) +``` + +--- + +#### Rest Group - Unmatched Files + +Files that don't match any group pattern are collected in the "Rest" group. + +**Group Configuration** + +```ts +{ + groups: [ + { + title: 'Features Only', + includeInputs: '**/feature-*.ts', + }, + ]; +} +``` + +**File Matching:** + +```txt +stats.json +└── outputs + └── dist/app.js 300kB + ├── 🎯 src/feature-1.ts // matches group + ├── 🎯 src/feature-2.ts // matches group + ├── ❓ src/index.ts // unmatched -> Rest + └── ❓ src/utils/format.ts // unmatched -> Rest +``` + +**Table Result:** + +| Group | Modules | Size | +| ------------- | ------- | ------ | +| Features Only | 2 | 175 kB | +| Rest | - | 275 kB | + +#### Rest Group - Bundler Overhead + +When using `onlyMatching` mode, bundler overhead becomes part of the Rest group. + +**Group Configuration** + +```ts +{ + mode: 'onlyMatching', + groups: [ + { + title: 'Source Files', + includeInputs: '**/src/**' + } + ] +} +``` + +**File Analysis:** + +```txt +dist/app.js total: 300kB +├── src files: 250kB // matches group +└── bundler overhead: 50kB // becomes Rest +``` + +**Table Result:** + +| Group | Modules | Size | +| ------------ | ------- | ------ | +| Source Files | 4 | 250 kB | +| Rest | - | 50 kB | + +--- + +#### Pruning - Max Children + +Limit the number of groups displayed in the table. + +**Group Configuration** + +```ts +{ + groups: [ + { title: 'Features', includeInputs: '**/feature-*.ts' }, + { title: 'Utils', includeInputs: '**/utils/**' }, + { title: 'Components', includeInputs: '**/components/**' }, + { title: 'Services', includeInputs: '**/services/**' }, + { title: 'Helpers', includeInputs: '**/helpers/**' } + ], + pruning: { + enabled: true, + maxChildren: 3 + } +} +``` + +**Table Result:** + +| Group | Modules | Size | +| ---------- | ------- | ------ | +| Features | 2 | 175 kB | +| Components | 5 | 125 kB | +| Services | 3 | 100 kB | +| Rest | - | 200 kB | + +_Utils and Helpers groups were moved to Rest due to maxChildren limit_ + +#### Pruning - Min Size + +Filter out groups smaller than the specified threshold. + +**Group Configuration** + +```ts +{ + groups: [ + { title: 'Large Feature', includeInputs: '**/large-feature.ts' }, // 100kB + { title: 'Medium Feature', includeInputs: '**/medium-feature.ts' }, // 50kB + { title: 'Small Feature', includeInputs: '**/small-feature.ts' }, // 10kB + { title: 'Tiny Feature', includeInputs: '**/tiny-feature.ts' } // 2kB + ], + pruning: { + enabled: true, + minSize: 25000 // 25kB threshold + } +} +``` + +**Table Result:** + +| Group | Modules | Size | +| -------------- | ------- | ------ | +| Large Feature | 1 | 100 kB | +| Medium Feature | 1 | 50 kB | +| Rest | - | 262 kB | + +_Small and Tiny features were moved to Rest due to minSize threshold_ + +--- + +## Implementation details + +### Limitations + +From feedback sessions on this issue we collected a couple of things that popped up regularly but are not directly possible with the plugin. + +- Any action triggered by a comparison of 2 measures. + - increased size by X% + - increased size by XkB + - increased files by X + +For example to implement a failing CI on 20% increase for a specific audit you would have to read the comparison json created by the GH action or over the `@code-pushup/ci` package directly and process it with your custom logic. + +### Data Processing Pipeline + +```mermaid +flowchart LR + subgraph Stats Generation + A[Esbuild ➔ stats.json] + B[Webpack ➔ stats.json] + C[Vite ➔ stats.json] + end + + D[Unify Stats] + E[Merge Options] + F[Group Stats by Audits] + G[Compute Size Scores] + H[Compute Issue Penalties] + I[Score Audit] + subgraph Generate Audits + J[Add Issues] + K[Add Table] + L[Add Tree] +end + A --> D + B --> D + C --> D + D --> E + E --> F + F --> G + F --> H + G --> I + H --> I + I --> J + J --> K + K --> L + +``` + +### Plugin Configuration + +The plugin integrates with supported bundlers to analyze bundle statistics and generate audit reports. Configure the plugin with bundler type, artifact paths, and audit settings. + +**Types** + +```ts +export type BundleStatsPluginOptions = { + bundler: SUPPORTED_BUNDLERS; + artefactsPaths: string; + generateArtefacts?: string; + audits: BundleStatsAuditOption[]; + artefactTree?: TreeOptions; + insightsTable?: InsightsOptions; + scoring?: Omit; +}; +``` + +**Minimal Example Configuration** + +```ts +const pluginOptions: PluginOptions = { + bundler: 'webpack', + artefactsPaths: './dist/stats.json', + generateArtefacts: + 'esbuild src/index.js --bundle --outfile=dist/bundle.js --metafile=stats.json', + audits: [ + { + title: 'Initial Bundles', + selection: { + includeOutputs: ['**/*.js'], + }, + scoring: { + totalSize: 500_000, + }, + }, + ], +}; +``` + +#### Artefacts Gathering + +The plugin can generate artefacts from the `stats.json` file. The plugin can either use an existing `stats.json` file or generate a new one if the `generateArtefacts` option is provided. + +**Types** + +```ts +type ArtefactsOptions = { + bundler: SUPPORTED_BUNDLERS; + artefactsPaths: string; + generateArtefacts?: string; +}; +``` + +**Example Configuration:** + +```ts +const options: PluginOptions = { + bundler: 'esbuild', + artefactsPaths: './dist/stats.json', + // ... +}; +``` + +**Full Example Configuration:** + +```ts +const options: PluginOptions = { + bundler: 'esbuild', + artefactsPaths: './dist/stats.json', + generateArtefacts: + 'esbuild src/index.js --bundle --outfile=dist/bundle.js --metafile=stats.json', + // ... +}; +``` + +#### Options Merging + +The Plugin and audit share a set of options: + +- `insightsTable` - The insights to use (grouping) +- `selection` - The filtering of output files to analyse +- `scoring` - The scoring penalty (not the totalSize) to use (penalty) +- `artefactTree` - The artefact tree to use (pruning, grouping, formatting) + +```ts +// 🔁 Options Merging – Plugin vs Audit-Level Config + +const pluginOptions: PluginOptions = { + artefactTree: { + groups: ['shared/'], // 📥 merged into audit.artefactTree.groups + pruning: { maxDepth: 3 }, // ❌ overwritten by audit.artefactTree.pruning + }, + insightsTable: ['node_modules', 'zone.js'], // 📥 merged into audit.insightsTable + selection: { + } + scoring: { + penalty: { + artefactSize: [0, 3_000_000], + blacklist: ['/*.min.js'], // 📥 merged into audit.penalty.blacklist + }, +}, +audits: [ + { + title: 'Initial Size Audit', + scoring: { + totalSize: 500_000, // 🔄 overwrites plugin totalSize + penalty: { + blacklist: ['/legacy/'], // 📥 merged with plugin.penalty.blacklist + }, + }, + insightsTable: ['feature:core'], // 📥 merged with plugin.insightsTable + artefactTree: { + groups: ['features/**'], // 📥 merged with plugin.artefactTree.groups + pruning: { maxChildren: 10 }, // ❌ overwrites plugin.artefactTree.pruning + }, +}, +], +}; +``` + +#### Audit Configuration + +Each audit defines a specific bundle analysis with its own selection criteria, scoring thresholds, and reporting options. Audits can override plugin-level settings or inherit them for consistency across multiple audits. + +**Types** + +```ts +export type BundleStatsAuditOption = { + slug?: string; + title: string; + description?: string; + selection: SelectionOptions; + scoring: ScoringOptions; + artefactTree?: TreeOptions; + insightsTable?: InsightsOptions; +}; +``` + +**Minimal Example Configuration** + +```ts +const auditConfig: BundleStatsAuditOption = { + title: 'All Bundles', + selection: { includeOutputs: ['**/*.js'] }, + scoring: { totalSize: 500_000 }, +}; +``` + +**Full Example Configuration** + +```ts +const auditConfig: BundleStatsAuditOption = { + slug: 'initial-bundles', + title: 'Initial Bundle Size', + description: + 'Monitors the size of initial JavaScript bundles loaded on page load.', + selection: { + includeOutputs: ['**/main.js', '**/vendor.js'], + excludeOutputs: ['**/chunks/**'], + }, + scoring: { + totalSize: 500_000, + penalty: { + artefactSize: [50_000, 200_000], + blacklist: ['**/legacy/**', '**/deprecated/**'], + }, + }, + artefactTree: { + groups: [ + { + title: 'App Code', + patterns: ['**/src/**'], + icon: '🎯', + }, + { + title: 'Node Modules', + patterns: ['**/node_modules/**'], + icon: '📦', + }, + ], + pruning: { + maxChildren: 3, + maxDepth: 1, + }, + }, + insightsTable: [ + { + title: 'App Code', + patterns: ['**/src/**'], + icon: '🎯', + }, + { + title: 'Node Modules', + patterns: ['**/node_modules/**'], + icon: '📦', + }, + ], +}; +``` + +--- + +## Market Research - Viewer + +### sonda.dev + +**Repo:** [https://sonda.dev/](https://sonda.dev/) + +## Market Research - CI + +### SizeLimit + +**Repo:** [https://github.com/ai/size-limit](https://github.com/ai/size-limit) + +**Setup** + +```js +import type { SizeLimitConfig } from '../../packages/size-limit' + +module.exports = [ + { + path: "index.js", + import: "{ createStore }", + limit: "500 ms" + } +] satisfies SizeLimitConfig +``` + +**Relevant Options:** + +- **path**: relative paths to files. The only mandatory option. + It could be a path `"index.js"`, a [pattern] `"dist/app-*.js"` + or an array `["index.js", "dist/app-*.js", "!dist/app-exclude.js"]`. +- **import**: partial import to test tree-shaking. It could be `"{ lib }"` + to test `import { lib } from 'lib'`, `*` to test all exports, + or `{ "a.js": "{ a }", "b.js": "{ b }" }` to test multiple files. +- **limit**: size or time limit for files from the `path` option. It should be + a string with a number and unit, separated by a space. + Format: `100 B`, `10 kB`, `500 ms`, `1 s`. +- **name**: the name of the current section. It will only be useful + if you have multiple sections. +- **message**: an optional custom message to display additional information, + such as guidance for resolving errors, relevant links, or instructions + for next steps when a limit is exceeded. + +* **gzip**: with `true` it will use Gzip compression and disable + Brotli compression. +* **brotli**: with `false` it will disable any compression. +* **ignore**: an array of files and dependencies to exclude from + the project size calculation. + +### Bundle Stats + +**repo:** [https://github.com/relative-ci/bundle-stats?tab=readme-ov-file](https://github.com/relative-ci/bundle-stats?tab=readme-ov-file) + +**Setup** + +```js +const { BundleStatsWebpackPlugin } = require('bundle-stats-webpack-plugin'); + +module.exports = { + plugins: [ + new BundleStatsWebpackPlugin({ + compare: true, + baseline: true, + html: true, + }), + ], +}; +``` + +**Relevant Options** + +- `compare` | Enable comparison to baseline bundle +- `baseline` | Save stats as baseline for future runs +- `html` | Output visual HTML report +- `json` | Output JSON snapshot +- `stats` | (advanced) Customize Webpack stats passed into plugin +- `silent` | Disable logging + +--- + +### BundleMon + +**Repo:** [https://github.com/LironEr/bundlemon](https://github.com/LironEr/bundlemon) + +**Setup** + +```json +"bundlemon": { + "baseDir": "./build", + "files": [ + { + "path": "index.html", + "maxSize": "2kb", + "maxPercentIncrease": 5 + }, + { + "path": "bundle..js", + "maxSize": "10kb" + }, + { + "path": "assets/**/*.{png,svg}" + } + ] +} +``` + +**Relevant Options** + +- `path` (string, required) – Glob pattern relative to baseDir (e.g. `"**/*.js"`) +- `friendlyName` (string, optional) – Human-readable name (e.g. `"Main Bundle"`) +- `compression` ("none" | "gzip", optional) – Override default compression (e.g. `"gzip"`) +- `maxSize` (string, optional) – Max size: `"2000b"`, `"20kb"`, `"1mb"` +- `maxPercentIncrease` (number, optional) – Max % increase: `0.5` = 0.5%, `4` = 4%, `200` = 200%