diff --git a/.node-scripts/validate-changed-package-versions.js b/.node-scripts/validate-changed-package-versions.js index 5239e716..ac028bdc 100644 --- a/.node-scripts/validate-changed-package-versions.js +++ b/.node-scripts/validate-changed-package-versions.js @@ -114,7 +114,9 @@ function getLatestReleasedVersion(changedPackage) { function isPackageThatHasNotPublished(changedPackage) { return [ - "packages/ENGINE-TEMPLATE" + "packages/ENGINE-TEMPLATE", + // TODO: remove once @salesforce/code-analyzer-uibundle-engine is published to npm (W-23659201) + "packages/code-analyzer-uibundle-engine" ].includes(changedPackage.replace("\\","/")); } diff --git a/package-lock.json b/package-lock.json index 01cb8e60..c06fda87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -43,29 +43,29 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.29.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.3.tgz", - "integrity": "sha512-LIVqM46zQWZhj17qA8wb4nW/ixr2y1Nw+r1etiAWgRM6U1IqP+LNhL1yg440jYZR72jCWcWbLWzIosH+uP1fqg==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.29.7.tgz", + "integrity": "sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==", "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.0.tgz", - "integrity": "sha512-CGOfOJqWjg2qW/Mb6zNsDm+u5vFQ8DxXfbM09z69p5Z6+mE1ikP2jUXw+j42Pf1XTYED2Rni5f95npYeuwMDQA==", - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.29.0", - "@babel/generator": "^7.29.0", - "@babel/helper-compilation-targets": "^7.28.6", - "@babel/helper-module-transforms": "^7.28.6", - "@babel/helpers": "^7.28.6", - "@babel/parser": "^7.29.0", - "@babel/template": "^7.28.6", - "@babel/traverse": "^7.29.0", - "@babel/types": "^7.29.0", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz", + "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.29.7", + "@babel/generator": "^7.29.7", + "@babel/helper-compilation-targets": "^7.29.7", + "@babel/helper-module-transforms": "^7.29.7", + "@babel/helpers": "^7.29.7", + "@babel/parser": "^7.29.7", + "@babel/template": "^7.29.7", + "@babel/traverse": "^7.29.7", + "@babel/types": "^7.29.7", "@jridgewell/remapping": "^2.3.5", "convert-source-map": "^2.0.0", "debug": "^4.1.0", @@ -83,46 +83,21 @@ }, "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==", "license": "ISC", "bin": { "semver": "bin/semver.js" } }, - "node_modules/@babel/eslint-parser": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.28.6.tgz", - "integrity": "sha512-QGmsKi2PBO/MHSQk+AAgA9R6OHQr+VqnniFE0eMWZcVcfBZoA2dKn2hUsl3Csg/Plt9opRUWdY7//VXsrIlEiA==", - "license": "MIT", - "peer": true, - "dependencies": { - "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", - "eslint-visitor-keys": "^2.1.0", - "semver": "^6.3.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || >=14.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.11.0", - "eslint": "^7.5.0 || ^8.0.0 || ^9.0.0" - } - }, - "node_modules/@babel/eslint-parser/node_modules/semver": { - "version": "6.3.1", - "license": "ISC", - "peer": true, - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/@babel/generator": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.7.tgz", - "integrity": "sha512-DkXD5OJQaAQIdZ1bt3UZdEnHAn9Imd3IVBdX03UFe+ony9Ojw5pzr9YVKGDY1jt+Gcn/FnGkNf8r+Vj5NOJWtQ==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.8.tgz", + "integrity": "sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==", "license": "MIT", "dependencies": { - "@babel/parser": "^7.29.7", - "@babel/types": "^7.29.7", + "@babel/parser": "^7.29.8", + "@babel/types": "^7.29.8", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "jsesc": "^3.0.2" @@ -144,13 +119,13 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.28.6.tgz", - "integrity": "sha512-JYtls3hqi15fcx5GaSNL7SCTJ2MNmjrkHXg4FSpOA/grxK8KwyZ5bubHsCq8FXCkua6xhuaaBit+3b7+VZRfcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.29.7.tgz", + "integrity": "sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==", "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.28.6", - "@babel/helper-validator-option": "^7.27.1", + "@babel/compat-data": "^7.29.7", + "@babel/helper-validator-option": "^7.29.7", "browserslist": "^4.24.0", "lru-cache": "^5.1.1", "semver": "^6.3.1" @@ -161,6 +136,8 @@ }, "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==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -189,14 +166,14 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.6.tgz", - "integrity": "sha512-67oXFAYr2cDLDVGLXTEABjdBJZ6drElUSI7WKp70NrpyISso3plG9SAGEF6y7zbha/wOzUByWWTJvEDVNIUGcA==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.29.7.tgz", + "integrity": "sha512-UPUVSyXbOh627KiCIGQSgwWzGeBKLkaJ9PJEdrngIwMSzxLR4jS4+f1f1jb7VzBbg8nFLaYotvVPFCTqdrmTAg==", "license": "MIT", "dependencies": { - "@babel/helper-module-imports": "^7.28.6", - "@babel/helper-validator-identifier": "^7.28.5", - "@babel/traverse": "^7.28.6" + "@babel/helper-module-imports": "^7.29.7", + "@babel/helper-validator-identifier": "^7.29.7", + "@babel/traverse": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -242,25 +219,25 @@ } }, "node_modules/@babel/helpers": { - "version": "7.29.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.2.tgz", - "integrity": "sha512-HoGuUs4sCZNezVEKdVcwqmZN8GoHirLUcLaYVNBK2J0DadGtdcqgr3BCbvH8+XUo4NGjNl3VOtSjEKNzqfFgKw==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.29.7.tgz", + "integrity": "sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==", "license": "MIT", "dependencies": { - "@babel/template": "^7.28.6", - "@babel/types": "^7.29.0" + "@babel/template": "^7.29.7", + "@babel/types": "^7.29.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/parser": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.7.tgz", - "integrity": "sha512-hnORnjP/1P/zFEndoeX+n+t1RwWRJiJpM/jO7FW32Kn9r5+sJB2JWOdYo4L6k78j15eCwY3Gm/7364B1EMwtNg==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.8.tgz", + "integrity": "sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==", "license": "MIT", "dependencies": { - "@babel/types": "^7.29.7" + "@babel/types": "^7.29.8" }, "bin": { "parser": "bin/babel-parser.js" @@ -271,6 +248,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -282,6 +261,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -293,6 +274,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -304,6 +287,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -317,11 +302,13 @@ } }, "node_modules/@babel/plugin-syntax-import-attributes": { - "version": "7.27.1", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.29.7.tgz", + "integrity": "sha512-zGYcYfq/WmZ4V+kBIXQon9dSSc8ircGZqw9ZaNhhGj9nZkeBu1jHLBDQqYYi5WA9uawvA2sIMbry2nCFhf5Djg==", "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.27.1" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -332,6 +319,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -343,6 +332,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -369,6 +360,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -380,6 +373,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -391,6 +386,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -402,6 +399,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -413,6 +412,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -424,6 +425,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -435,6 +438,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -449,6 +454,8 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -462,13 +469,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.28.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.28.6.tgz", - "integrity": "sha512-+nDNmQye7nlnuuHDboPbGm00Vqg3oO8niRRL27/4LYHUsHYh0zJ1xWOz0uRwNFmM1Avzk8wZbc6rdiYhomzv/A==", + "version": "7.29.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.29.7.tgz", + "integrity": "sha512-ngr+82Sh0xMz25TPCZi+nC2iTzjfCdWS2ONXTp/PtSCHCgaCNBpdMqgvJ2ccdLlClVZ7sisIgB914j/JFe+RZA==", "devOptional": true, "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.28.6" + "@babel/helper-plugin-utils": "^7.29.7" }, "engines": { "node": ">=6.9.0" @@ -577,17 +584,17 @@ } }, "node_modules/@babel/traverse": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.7.tgz", - "integrity": "sha512-EhlfNQtZ+NK22w5BM61ciuiq1m58ed33Wr1Xan//ZRTy6hgjnwyCffRYwzsGXdASJSUJ1guZILsErh1eQcl+zw==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.29.8.tgz", + "integrity": "sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==", "license": "MIT", "dependencies": { "@babel/code-frame": "^7.29.7", - "@babel/generator": "^7.29.7", + "@babel/generator": "^7.29.8", "@babel/helper-globals": "^7.29.7", - "@babel/parser": "^7.29.7", + "@babel/parser": "^7.29.8", "@babel/template": "^7.29.7", - "@babel/types": "^7.29.7", + "@babel/types": "^7.29.8", "debug": "^4.3.1" }, "engines": { @@ -595,9 +602,9 @@ } }, "node_modules/@babel/types": { - "version": "7.29.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.7.tgz", - "integrity": "sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==", + "version": "7.29.8", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.8.tgz", + "integrity": "sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==", "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.29.7", @@ -609,8 +616,6 @@ }, "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==", "devOptional": true, "license": "MIT" }, @@ -685,8 +690,6 @@ }, "node_modules/@eslint/config-array": { "version": "0.21.2", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", - "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "license": "Apache-2.0", "dependencies": { "@eslint/object-schema": "^2.1.7", @@ -699,8 +702,6 @@ }, "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==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -709,8 +710,6 @@ }, "node_modules/@eslint/config-array/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -1002,8 +1001,6 @@ }, "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==", "license": "ISC", "dependencies": { "string-width": "^5.1.2", @@ -1019,8 +1016,6 @@ }, "node_modules/@isaacs/cliui/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -1031,8 +1026,6 @@ }, "node_modules/@isaacs/cliui/node_modules/strip-ansi": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -1145,8 +1138,6 @@ }, "node_modules/@jest/console": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-30.4.1.tgz", - "integrity": "sha512-v3bhyxUh9Hgmo5p6hAOXe14/R3ZxZDOsvHleh4B07z3m/x4/ngPUXEm9XwK4sF4u+f+P2ORb0Ge+MgpaqRMVDA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1163,8 +1154,6 @@ }, "node_modules/@jest/core": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-30.4.2.tgz", - "integrity": "sha512-TZJA6cPJUFxoWhxaLo8t0VX/MZX2wPWr0uIDvLSHIvN4gu9h02vSzqI2kBADG1ExqQlC+cY09xKMSreivvrChQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1211,8 +1200,6 @@ }, "node_modules/@jest/diff-sequences": { "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/diff-sequences/-/diff-sequences-30.4.0.tgz", - "integrity": "sha512-zOpzlfUs45l6u7jm39qr87JCHUDsaeCtvL+kQe/Vn9jSnRB4/5IPXISm0h9I1vZW/o00Kn4UTJ2MOlhnUGwv3g==", "devOptional": true, "license": "MIT", "engines": { @@ -1221,8 +1208,6 @@ }, "node_modules/@jest/environment": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-30.4.1.tgz", - "integrity": "sha512-AK9yNRqgKxiabqMoe4oW+3/TSSeV8vkdC7BGaxZdU0AFXfOpofTLqdru2GXKZghP3sdgwE9XXpnVwfZ8JnFV4w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1237,8 +1222,6 @@ }, "node_modules/@jest/expect": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-ginrj6TMgh2GshLUGCjO94Ptx9HhdZA/I6A9iUfyeLKFtdAjnKzHDgzgP9HYQgbxM1lbXScQ2eUBz2lGeVDPWA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1251,8 +1234,6 @@ }, "node_modules/@jest/expect-utils": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-30.4.1.tgz", - "integrity": "sha512-ZBn5CglH8fBsQsvs4VWNzD4aWfUYks+IdOOQU3MEK71ol/BcVm+P+rtb1KpiFBpSWSCE27uOahyyf1vfqOVbcQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1264,8 +1245,6 @@ }, "node_modules/@jest/fake-timers": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-30.4.1.tgz", - "integrity": "sha512-iW5umdmfPeWzehrVhugFQZqCchSCud5S1l2YT0O9ZhjRR0ExclANDZkiSBwzqtnlOn0J1JXvO+HZ6rkuyOVOgQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1290,8 +1269,6 @@ }, "node_modules/@jest/globals": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-30.4.1.tgz", - "integrity": "sha512-ZbuY4cmXC8DkxYjfvT2DbcHWL2T6vmsMhXCDcmTB2T0y0gaezBI77ufq5ZAIdcRkYZ7NEQEDg1xFeKbxUJ5v5Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1306,8 +1283,6 @@ }, "node_modules/@jest/pattern": { "version": "30.4.0", - "resolved": "https://registry.npmjs.org/@jest/pattern/-/pattern-30.4.0.tgz", - "integrity": "sha512-RAWn3+f9u8BsHijKJ71uHcFp6vmyEt6VvoWXkl6hKF3qVIuWNmudVjg12DlBPGup/frIl5UcUlH5HfEuvHpEXg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1320,8 +1295,6 @@ }, "node_modules/@jest/reporters": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-30.4.1.tgz", - "integrity": "sha512-/SnkPCzEQpUaBH81kjdEdDdo2WZl5hxw+BmLDGWjRkm8o7XlhjwsU36cqwe5PGBE5WYpBvDzRSdXx9rbGuJtNA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1363,8 +1336,6 @@ }, "node_modules/@jest/schemas": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-30.4.1.tgz", - "integrity": "sha512-i6b4qw5qnP8c5FEeBJg/uZQ4ddrkN6Ca8qISJh0pr7a5hfn3h3v5x60BEbOC7OYAGZNMs1LfFLwnW2CuK8F57Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1376,8 +1347,6 @@ }, "node_modules/@jest/snapshot-utils": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/snapshot-utils/-/snapshot-utils-30.4.1.tgz", - "integrity": "sha512-ObY4ljvQ95mt6iwKtVLetR/4yXiAgl3H4nJxhztr0MTjrN97TwDYrnCp/kF60Ec9HdhkWTHSu+Hg05aXfngpOA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1392,8 +1361,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1407,8 +1374,6 @@ }, "node_modules/@jest/test-result": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-30.4.1.tgz", - "integrity": "sha512-/ZG7pgEiOmmWkN9TplKbOu4id2N5lh7FHwRwlkgBVAzGdRH+OkkQ8wX/kIxg4zmd3ZQvAL1RwL2yWsvNYYECTw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1423,8 +1388,6 @@ }, "node_modules/@jest/test-sequencer": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-30.4.1.tgz", - "integrity": "sha512-PeYE+4td5rKjoRPxztObrXU+H8hsjZfxKMXOcmrr34JerSyB/ROOxbbicz8B7A5j9R9VayDnVPvBmedqCsFCdw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1439,8 +1402,6 @@ }, "node_modules/@jest/transform": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-30.4.1.tgz", - "integrity": "sha512-Wz0LyktlTvRefoymh+n64hQ84KNXsRGcwdoZ8CSa0Ea+fgYcHZlnk+hDP7v2MS7il2bQ5uTEIxf4/NNfhMN4KQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1465,8 +1426,6 @@ }, "node_modules/@jest/types": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-30.4.1.tgz", - "integrity": "sha512-f1x/vJXIfjOlEmejYpbkbgw1gOqpPECwMvMEtBqe47j7H2Hg8h8w3o3ikhSXq3MI15kg+oQ0exWO0uCtTNJLoQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -1492,8 +1451,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==", "license": "MIT", "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", @@ -1521,8 +1478,6 @@ }, "node_modules/@jsforce/jsforce-node": { "version": "3.10.14", - "resolved": "https://registry.npmjs.org/@jsforce/jsforce-node/-/jsforce-node-3.10.14.tgz", - "integrity": "sha512-p8Ug1SypcAT7Q0zZA0+7fyBmgUpB/aXkde4Bxmu0S/O4p28CVwgYvKyFd9vswmHIhFabd/QqUCrlYuVhYdr2Ew==", "license": "MIT", "dependencies": { "@sindresorhus/is": "^4", @@ -1542,8 +1497,6 @@ }, "node_modules/@jsforce/jsforce-node/node_modules/agent-base": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", "license": "MIT", "dependencies": { "debug": "4" @@ -1554,8 +1507,6 @@ }, "node_modules/@jsforce/jsforce-node/node_modules/https-proxy-agent": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", "license": "MIT", "dependencies": { "agent-base": "6", @@ -1567,8 +1518,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==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -1583,8 +1532,6 @@ }, "node_modules/@jsonjoy.com/buffers": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/buffers/-/buffers-1.2.1.tgz", - "integrity": "sha512-12cdlDwX4RUM3QxmUbVJWqZ/mrK6dFQH4Zxq6+r1YXKXYBNgZXndx2qbCJwh3+WWkCSn67IjnlG3XYTvmvYtgA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -1599,8 +1546,6 @@ }, "node_modules/@jsonjoy.com/codegen": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/codegen/-/codegen-1.0.0.tgz", - "integrity": "sha512-E8Oy+08cmCf0EK/NMxpaJZmOxPqM+6iSe2S4nlSBrPZOORoDJILxtbSUEDKQyTamm/BVAhIGllOBNU79/dwf0g==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -1615,8 +1560,6 @@ }, "node_modules/@jsonjoy.com/json-pack": { "version": "1.21.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pack/-/json-pack-1.21.0.tgz", - "integrity": "sha512-+AKG+R2cfZMShzrF2uQw34v3zbeDYUqnQ+jg7ORic3BGtfw9p/+N6RJbq/kkV8JmYZaINknaEQ2m0/f693ZPpg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/base64": "^1.1.2", @@ -1641,8 +1584,6 @@ }, "node_modules/@jsonjoy.com/json-pointer": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/json-pointer/-/json-pointer-1.0.2.tgz", - "integrity": "sha512-Fsn6wM2zlDzY1U+v4Nc8bo3bVqgfNTGcn6dMgs6FjrEnt4ZCe60o6ByKRjOGlI2gow0aE/Q41QOigdTqkyK5fg==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/codegen": "^1.0.0", @@ -1661,8 +1602,6 @@ }, "node_modules/@jsonjoy.com/util": { "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@jsonjoy.com/util/-/util-1.9.0.tgz", - "integrity": "sha512-pLuQo+VPRnN8hfPqUTLTHk126wuYdXVxE6aDmjSeV4NCAgyxWbiOIeNJVtID3h1Vzpoi9m4jXezf73I6LgabgQ==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/buffers": "^1.0.0", @@ -1743,21 +1682,24 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.4.tgz", - "integrity": "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.2.2.tgz", + "integrity": "sha512-JfB4kuJQjaoHuCTseIINHtHWeJnvgEcxjwA5t/Y00ZgaOO1Crz3fjT/p8kT28zA/Caz7oiUMn3d6H2yOVCVwuw==", "license": "MIT", "optional": true, "dependencies": { - "@tybys/wasm-util": "^0.10.1" + "@tybys/wasm-util": "^0.10.3" + }, + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=23.5.0" }, "funding": { "type": "github", "url": "https://github.com/sponsors/Brooooooklyn" }, "peerDependencies": { - "@emnapi/core": "^1.7.1", - "@emnapi/runtime": "^1.7.1" + "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.3", + "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.3" } }, "node_modules/@nicolo-ribaudo/eslint-scope-5-internals": { @@ -1769,8 +1711,6 @@ }, "node_modules/@nodable/entities": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@nodable/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-9uGyhaQavEUMC8AIddIjau4NsnsXhou+j5sBAGojCM1oxmQpVKTWR/9JxABD6UAv12vpIms55fPZKFQEhG6uBg==", "funding": [ { "type": "github", @@ -1810,14 +1750,10 @@ }, "node_modules/@pinojs/redact": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", - "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", "license": "MIT" }, "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==", "license": "MIT", "optional": true, "engines": { @@ -1826,8 +1762,6 @@ }, "node_modules/@pkgr/core": { "version": "0.2.9", - "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.2.9.tgz", - "integrity": "sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==", "devOptional": true, "license": "MIT", "engines": { @@ -1843,8 +1777,6 @@ }, "node_modules/@salesforce-ux/eslint-plugin-slds": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@salesforce-ux/eslint-plugin-slds/-/eslint-plugin-slds-1.2.1.tgz", - "integrity": "sha512-DeByr0oCNnKKnDKOhHt2kzeOGgN7lf/WnD43y20YFMhN2kWZ/aDHMG2fRwWSuG4iBBjHXIGFb9SdJoN8+murOg==", "license": "ISC", "dependencies": { "@eslint/css": "^0.9.0", @@ -1913,10 +1845,12 @@ "resolved": "packages/code-analyzer-sfge-engine", "link": true }, + "node_modules/@salesforce/code-analyzer-uibundle-engine": { + "resolved": "packages/code-analyzer-uibundle-engine", + "link": true + }, "node_modules/@salesforce/core": { "version": "8.31.2", - "resolved": "https://registry.npmjs.org/@salesforce/core/-/core-8.31.2.tgz", - "integrity": "sha512-naqnq7Z+gbl1LdnyNvrGrNUoeMUQtCOsnrS6DfqeuLMJTFqcL9Dq0/od+xcuqi0+l7HTyH0/gU1BQitWpd1rag==", "license": "BSD-3-Clause", "dependencies": { "@jsforce/jsforce-node": "^3.10.13", @@ -1945,8 +1879,6 @@ }, "node_modules/@salesforce/core/node_modules/ajv": { "version": "8.18.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz", - "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -1961,8 +1893,6 @@ }, "node_modules/@salesforce/core/node_modules/fast-levenshtein": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz", - "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==", "license": "MIT", "dependencies": { "fastest-levenshtein": "^1.0.7" @@ -1970,14 +1900,10 @@ }, "node_modules/@salesforce/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==", "license": "MIT" }, "node_modules/@salesforce/core/node_modules/zod": { "version": "4.3.6", - "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", - "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" @@ -1996,8 +1922,6 @@ }, "node_modules/@salesforce/kit": { "version": "3.2.6", - "resolved": "https://registry.npmjs.org/@salesforce/kit/-/kit-3.2.6.tgz", - "integrity": "sha512-O8S4LWerHa9Zosqh+IoQjgLtpxMOfObRxaRnUdRV4MLtFUi+bQxQiyFvve6eEaBaMP1b1xVDQpvSvQ+PXEDGFQ==", "license": "Apache-2.0", "dependencies": { "@salesforce/ts-types": "^2.0.12" @@ -2005,8 +1929,6 @@ }, "node_modules/@salesforce/ts-types": { "version": "2.0.12", - "resolved": "https://registry.npmjs.org/@salesforce/ts-types/-/ts-types-2.0.12.tgz", - "integrity": "sha512-BIJyduJC18Kc8z+arUm5AZ9VkPRyw1KKAm+Tk+9LT99eOzhNilyfKzhZ4t+tG2lIGgnJpmytZfVDZ0e2kFul8g==", "license": "BSD-3-Clause", "engines": { "node": ">=18.0.0" @@ -2014,15 +1936,11 @@ }, "node_modules/@sinclair/typebox": { "version": "0.34.49", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.34.49.tgz", - "integrity": "sha512-brySQQs7Jtn0joV8Xh9ZV/hZb9Ozb0pmazDIASBkYKCjXrXU3mpcFahmK/z4YDhGkQvP9mWJbVyahdtU5wQA+A==", "devOptional": true, "license": "MIT" }, "node_modules/@sindresorhus/is": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "license": "MIT", "engines": { "node": ">=10" @@ -2033,8 +1951,6 @@ }, "node_modules/@sinonjs/commons": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", - "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "devOptional": true, "license": "BSD-3-Clause", "dependencies": { @@ -2043,8 +1959,6 @@ }, "node_modules/@sinonjs/fake-timers": { "version": "15.4.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-15.4.0.tgz", - "integrity": "sha512-DsG+8/LscQIQg68J6Ef3dv10u6nVyetYn923s3/sus5eaGfTo1of5WMZSLf0UJc9KDuKPilPH0UDJCjvNbDNCA==", "devOptional": true, "license": "BSD-3-Clause", "dependencies": { @@ -2056,9 +1970,9 @@ "license": "MIT" }, "node_modules/@tybys/wasm-util": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.2.tgz", - "integrity": "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "license": "MIT", "optional": true, "dependencies": { @@ -2067,8 +1981,6 @@ }, "node_modules/@types/archiver": { "version": "6.0.4", - "resolved": "https://registry.npmjs.org/@types/archiver/-/archiver-6.0.4.tgz", - "integrity": "sha512-ULdQpARQ3sz9WH4nb98mJDYA0ft2A8C4f4fovvUcFwINa1cgGjY36JCAYuP5YypRq4mco1lJp1/7jEMS2oR0Hg==", "dev": true, "license": "MIT", "dependencies": { @@ -2077,8 +1989,6 @@ }, "node_modules/@types/babel__core": { "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", - "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2091,8 +2001,6 @@ }, "node_modules/@types/babel__generator": { "version": "7.27.0", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.27.0.tgz", - "integrity": "sha512-ufFd2Xi92OAVPYsy+P4n7/U7e68fex0+Ee8gSG9KX7eo084CWiQ4sdxktvdl0bOPupXtVJPY19zk6EwWqUQ8lg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2101,8 +2009,6 @@ }, "node_modules/@types/babel__template": { "version": "7.4.4", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", - "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2112,8 +2018,6 @@ }, "node_modules/@types/babel__traverse": { "version": "7.28.0", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.28.0.tgz", - "integrity": "sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2178,8 +2082,6 @@ }, "node_modules/@types/node": { "version": "20.19.39", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.39.tgz", - "integrity": "sha512-orrrD74MBUyK8jOAD/r0+lfa1I2MO6I+vAkmAWzMYbCcgrN4lCrmK52gRFQq/JRxfYPfonkr4b0jcY7Olqdqbw==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -2187,8 +2089,6 @@ }, "node_modules/@types/readdir-glob": { "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@types/readdir-glob/-/readdir-glob-1.1.5.tgz", - "integrity": "sha512-raiuEPUYqXu+nvtY2Pe8s8FEmZ3x5yAH4VkLdihcPdalvsHltomrRC9BzuStrJ9yk06470hS0Crw0f1pXqD+Hg==", "dev": true, "license": "MIT", "dependencies": { @@ -2232,8 +2132,6 @@ }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.65.0.tgz", - "integrity": "sha512-IEgob78X12rHpUmtcwFsXhZdVGJtwTVP8FiCLZkR6GlYVrl2PcuB+KhCE5BlVC/eQpQnu8WXRtkHZuPar+gCRA==", "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.12.2", @@ -2260,8 +2158,6 @@ }, "node_modules/@typescript-eslint/parser": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.65.0.tgz", - "integrity": "sha512-CZ4nMxWwgu1HEEFNkeaCptra9QCtkmKdgf3sWh1rl1trIhmxLilgTV4cwcbQ4wemnT4sWQN8CaKOmdYx+g2gMA==", "license": "MIT", "dependencies": { "@typescript-eslint/scope-manager": "8.65.0", @@ -2284,8 +2180,6 @@ }, "node_modules/@typescript-eslint/project-service": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.65.0.tgz", - "integrity": "sha512-SxnPhbTsGahizDgbu7oqFH/xVtzIqMd/s+WtnSxNxJZJpLbdT5IPdzg8EZxO3+PoKahXmwJLeNQOpKJb3/bi7Q==", "license": "MIT", "dependencies": { "@typescript-eslint/tsconfig-utils": "^8.65.0", @@ -2305,8 +2199,6 @@ }, "node_modules/@typescript-eslint/scope-manager": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.65.0.tgz", - "integrity": "sha512-Esbl8OSYiVxBokYgWPf7VVWg/BE798wXhimnn9ML9Pt5qoDf8bfQlgjlKXR/k98+AcNzlLKYrpCcrcuZ9DZLgg==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.65.0", @@ -2322,8 +2214,6 @@ }, "node_modules/@typescript-eslint/tsconfig-utils": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.65.0.tgz", - "integrity": "sha512-j6GzGqCiRdA7Qhur2VVmKZAkBLfnHFQfx4TaJGL9RMveZqCo48jSHHO0DTgizEnGhtWnqmbtCUSrqSkdiY/0Hg==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2338,8 +2228,6 @@ }, "node_modules/@typescript-eslint/type-utils": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.65.0.tgz", - "integrity": "sha512-YjaZ7PRI5qY7ax2L3PbvX0rRyGtipAReCWs0mhhDBHjH/vl0g0BonaGXrKdKpMbIIsMIwDgbk/xzkBTyAltS5g==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.65.0", @@ -2362,8 +2250,6 @@ }, "node_modules/@typescript-eslint/types": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.65.0.tgz", - "integrity": "sha512-JSSwWNy+H0E/01jJEM+hrX6N0OFDzFzeIhHFSAS01tlVaevpG8cFyYRPhS5yjGOvBUx3sqQHVMjCL1CAZZMxBg==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -2375,8 +2261,6 @@ }, "node_modules/@typescript-eslint/typescript-estree": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.65.0.tgz", - "integrity": "sha512-JboAE2swaYt4tb1fHhHTABE2K+OLy09XfcTbhnk4Pw96f9dd2e9iYsJ28gBggHlo5z5x1rkyWvcPoTuNTd4oGg==", "license": "MIT", "dependencies": { "@typescript-eslint/project-service": "8.65.0", @@ -2402,8 +2286,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" @@ -2411,8 +2293,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.8.tgz", - "integrity": "sha512-JZyDyq3D4AUifKTPOB7DELf6XsB3WdPuNxCtob1vFXPsSXhdAiHBWJ/tJ8HAc9aH84BK+5JFZLNkJKx3G9kzQg==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -2423,8 +2303,6 @@ }, "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": { "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" @@ -2438,8 +2316,6 @@ }, "node_modules/@typescript-eslint/utils": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.65.0.tgz", - "integrity": "sha512-gXiwIHsYreboxeJucHKPvgwl7dXt50mF8s1/c00cP/WoVTyWKFdtfhRWwZiXYFU5H2O8vVoSLNrexFZjYS/SGA==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.9.1", @@ -2461,8 +2337,6 @@ }, "node_modules/@typescript-eslint/visitor-keys": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.65.0.tgz", - "integrity": "sha512-8C71BQkGjiMmXtop7pHVJu1l2NNShFdkCyD6a2ezzs5vU/L3LRtb69EtcteFwz0mYMPzIgOw0n6OV4VBUWZd7A==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.65.0", @@ -2478,8 +2352,6 @@ }, "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", - "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", "license": "Apache-2.0", "engines": { "node": "^20.19.0 || ^22.13.0 || >=24" @@ -2520,8 +2392,6 @@ }, "node_modules/@unrs/resolver-binding-darwin-arm64": { "version": "1.12.2", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", - "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", "cpu": [ "arm64" ], @@ -2590,6 +2460,9 @@ "cpu": [ "arm64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2603,6 +2476,9 @@ "cpu": [ "arm64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2616,6 +2492,9 @@ "cpu": [ "loong64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2629,6 +2508,9 @@ "cpu": [ "loong64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2642,6 +2524,9 @@ "cpu": [ "ppc64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2655,6 +2540,9 @@ "cpu": [ "riscv64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2668,6 +2556,9 @@ "cpu": [ "riscv64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2681,6 +2572,9 @@ "cpu": [ "s390x" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2694,6 +2588,9 @@ "cpu": [ "x64" ], + "libc": [ + "glibc" + ], "license": "MIT", "optional": true, "os": [ @@ -2707,6 +2604,9 @@ "cpu": [ "x64" ], + "libc": [ + "musl" + ], "license": "MIT", "optional": true, "os": [ @@ -2785,8 +2685,6 @@ }, "node_modules/abort-controller": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", - "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", "license": "MIT", "dependencies": { "event-target-shim": "^5.0.0" @@ -2821,8 +2719,6 @@ }, "node_modules/ajv": { "version": "6.14.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", - "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -2844,8 +2740,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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -2892,8 +2786,6 @@ }, "node_modules/anynum": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/anynum/-/anynum-1.0.1.tgz", - "integrity": "sha512-N6//FLET/tXYNM/F6ABca1oH6fWB+KlTt909Le28WMDBk8oaT4vY17DCrwg2MvmuqUKt3Ni4N5dGJ/EoBgcO6A==", "funding": [ { "type": "github", @@ -2904,8 +2796,6 @@ }, "node_modules/archiver": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/archiver/-/archiver-7.0.1.tgz", - "integrity": "sha512-ZcbTaIqJOfCc03QwD468Unz/5Ir8ATtvAHsK+FdXbDIbGfihqh9mrvdcYunQzqn4HrvWWaFyaxJhGZagaJJpPQ==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.2", @@ -2922,8 +2812,6 @@ }, "node_modules/archiver-utils": { "version": "5.0.2", - "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-5.0.2.tgz", - "integrity": "sha512-wuLJMmIBQYCsGZgYLTy5FIB2pF6Lfb6cXMSF8Qywwk3t20zWnAi7zLcQFdKQmIB8wyZpY5ER38x08GbwtR2cLA==", "license": "MIT", "dependencies": { "glob": "^10.0.0", @@ -2940,8 +2828,6 @@ }, "node_modules/archiver-utils/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -2956,8 +2842,6 @@ }, "node_modules/archiver-utils/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==", "funding": [ { "type": "github", @@ -2976,8 +2860,6 @@ }, "node_modules/archiver-utils/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -2985,8 +2867,6 @@ }, "node_modules/archiver/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -3001,8 +2881,6 @@ }, "node_modules/archiver/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==", "funding": [ { "type": "github", @@ -3021,8 +2899,6 @@ }, "node_modules/archiver/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -3177,8 +3053,6 @@ }, "node_modules/asap": { "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", "license": "MIT" }, "node_modules/ast-types": { @@ -3204,8 +3078,6 @@ }, "node_modules/async": { "version": "3.2.6", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.6.tgz", - "integrity": "sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==", "license": "MIT" }, "node_modules/async-function": { @@ -3217,14 +3089,10 @@ }, "node_modules/asynckit": { "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", "license": "MIT" }, "node_modules/atomic-sleep": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", - "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -3259,8 +3127,6 @@ }, "node_modules/b4a": { "version": "1.8.1", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.8.1.tgz", - "integrity": "sha512-aiqre1Nr0B/6DgE2N5vwTc+2/oQZ4Wh1t4NznYY4E00y8LCt6NqdRv81so00oo27D8MVKTpUa/MwUUtBLXCoDw==", "license": "Apache-2.0", "peerDependencies": { "react-native-b4a": "*" @@ -3273,8 +3139,6 @@ }, "node_modules/babel-jest": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-30.4.1.tgz", - "integrity": "sha512-fATAbM8piYxkiXQp3RBXmZHxZVNJZAVXXfyeyCN2Tida3+qJ8ea9UxhiJ2y4fLO90ZImKt6k9FlcH2+rLkJGhw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3313,8 +3177,6 @@ }, "node_modules/babel-plugin-jest-hoist": { "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-30.4.0.tgz", - "integrity": "sha512-9EdtWM/sSfXLOGLwSn+GS6pIXyBnL07/8gyJlwFXjWy4DxMOyItqyUT29d4lQiS380EZwYlX7/At4PgBS+m2aA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3351,8 +3213,6 @@ }, "node_modules/babel-preset-jest": { "version": "30.4.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-30.4.0.tgz", - "integrity": "sha512-lBY4jxsNmCnSiu7kquw8ZC9F4+XLMOKypT3RnNHPvU2Kpd4W0xaPuLr5ZkRyOsvLYAY4yaW1ZwTW4xB7NIiZzg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3372,8 +3232,6 @@ }, "node_modules/bare-events": { "version": "2.9.1", - "resolved": "https://registry.npmjs.org/bare-events/-/bare-events-2.9.1.tgz", - "integrity": "sha512-Z0oHEHAFDZkffN8Qc39zNZjQlMDkPJRyyyZieU1VH7u8c5S+qHZ2S8ixdKIAxEjfHO7FJxXmJWgteOghVanIsg==", "license": "Apache-2.0", "peerDependencies": { "bare-abort-controller": "*" @@ -3386,8 +3244,6 @@ }, "node_modules/bare-fs": { "version": "4.7.2", - "resolved": "https://registry.npmjs.org/bare-fs/-/bare-fs-4.7.2.tgz", - "integrity": "sha512-aTvMFUWkBmjzKtEQMDGGDNF8bkfpD5N1b/FCwt7A3wrU4t1o/e/85Wzkluh6JlODCjqVESYCkQCdTXqZ9G7VFg==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.5.4", @@ -3410,8 +3266,6 @@ }, "node_modules/bare-os": { "version": "3.9.1", - "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.9.1.tgz", - "integrity": "sha512-6M5XjcnsygQNPMCMPXSK379xrJFiZ/AEMNBmFEmQW8d/789VQATvriyi5r0HYTL9TkQ26rn3kgdTG3aisbrXkQ==", "license": "Apache-2.0", "engines": { "bare": ">=1.14.0" @@ -3419,8 +3273,6 @@ }, "node_modules/bare-path": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/bare-path/-/bare-path-3.0.1.tgz", - "integrity": "sha512-ghj2DSK/2e99a1anTVPCV4m4YIYtrbXhfM7V3D7XZLOTsybnYyaJloymGqssQc8l/or0UoDyRtNQkmkEF/ysgQ==", "license": "Apache-2.0", "dependencies": { "bare-os": "^3.0.1" @@ -3428,8 +3280,6 @@ }, "node_modules/bare-stream": { "version": "2.13.1", - "resolved": "https://registry.npmjs.org/bare-stream/-/bare-stream-2.13.1.tgz", - "integrity": "sha512-Vp0cnjYyrEC4whYTymQ+YZi6pBpfiICZO3cfRG8sy67ZNWe951urv1x4eW1BKNngw3U+3fPYb5JQvHbCtxH7Ow==", "license": "Apache-2.0", "dependencies": { "streamx": "^2.25.0", @@ -3454,8 +3304,6 @@ }, "node_modules/bare-url": { "version": "2.4.5", - "resolved": "https://registry.npmjs.org/bare-url/-/bare-url-2.4.5.tgz", - "integrity": "sha512-K+y9xF1tN+CdPu4qWwr0QiK1Al07eFPGYK5M2pDXcmHdMdgC/tT/bpmMe1hrmRHaidKLkXrC+cRNYf3XVDUhSQ==", "license": "Apache-2.0", "dependencies": { "bare-path": "^3.0.0" @@ -3463,8 +3311,6 @@ }, "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==", "funding": [ { "type": "github", @@ -3483,8 +3329,6 @@ }, "node_modules/base64url": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz", - "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==", "license": "MIT", "engines": { "node": ">=6.0.0" @@ -3499,8 +3343,6 @@ }, "node_modules/basic-ftp": { "version": "5.3.1", - "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.3.1.tgz", - "integrity": "sha512-bopVNp6ugyA150DDuZfPFdt1KZ5a94ZDiwX4hMgZDzF+GttD80lEy8kj98kbyhLXnPvhtIo93mdnLIjpCAeeOw==", "license": "MIT", "engines": { "node": ">=10.0.0" @@ -3520,8 +3362,6 @@ }, "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==", "license": "MIT", "dependencies": { "fill-range": "^7.1.1" @@ -3582,8 +3422,6 @@ }, "node_modules/buffer": { "version": "6.0.3", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", - "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", "funding": [ { "type": "github", @@ -3606,8 +3444,6 @@ }, "node_modules/buffer-crc32": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-1.0.0.tgz", - "integrity": "sha512-Db1SbgBS/fg/392AblrMJk97KggmvYhr4pB5ZIMTWtaivCPMWLkmb7m21cJvpvgK+J3nsU2CmmixNBZx4vFj/w==", "license": "MIT", "engines": { "node": ">=8.0.0" @@ -3615,14 +3451,10 @@ }, "node_modules/buffer-equal-constant-time": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", - "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", "license": "BSD-3-Clause" }, "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==", "devOptional": true, "license": "MIT" }, @@ -3676,8 +3508,6 @@ }, "node_modules/camel-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", "license": "MIT", "dependencies": { "pascal-case": "^3.1.2", @@ -3712,8 +3542,6 @@ }, "node_modules/capital-case": { "version": "1.0.4", - "resolved": "https://registry.npmjs.org/capital-case/-/capital-case-1.0.4.tgz", - "integrity": "sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -3737,8 +3565,6 @@ }, "node_modules/change-case": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-4.1.2.tgz", - "integrity": "sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==", "license": "MIT", "dependencies": { "camel-case": "^4.1.2", @@ -3757,8 +3583,6 @@ }, "node_modules/char-regex": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "devOptional": true, "license": "MIT", "engines": { @@ -3785,15 +3609,11 @@ }, "node_modules/cjs-module-lexer": { "version": "2.2.0", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-2.2.0.tgz", - "integrity": "sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==", "devOptional": true, "license": "MIT" }, "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==", "devOptional": true, "license": "ISC", "dependencies": { @@ -3807,15 +3627,11 @@ }, "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==", "devOptional": true, "license": "MIT" }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3829,8 +3645,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -3847,8 +3661,6 @@ }, "node_modules/co": { "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "devOptional": true, "license": "MIT", "engines": { @@ -3858,8 +3670,6 @@ }, "node_modules/collect-v8-coverage": { "version": "1.0.3", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.3.tgz", - "integrity": "sha512-1L5aqIkwPfiodaMgQunkF1zRhNqifHBmtbbbxcr6yVxxBnliw4TDOW6NxpO8DJLgJ16OT+Y4ztZqP6p/FtXnAw==", "devOptional": true, "license": "MIT" }, @@ -3879,14 +3689,10 @@ }, "node_modules/colorette": { "version": "2.0.20", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", - "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" @@ -3904,8 +3710,6 @@ }, "node_modules/compress-commons": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-6.0.2.tgz", - "integrity": "sha512-6FqVXeETqWPoGcfzrXb37E50NP0LXT8kAMu5ooZayhWWdgEY4lBEEcbQNXtkuKQsGduxiIcI4gOTsxTmuq/bSg==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", @@ -3920,8 +3724,6 @@ }, "node_modules/compress-commons/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -3936,8 +3738,6 @@ }, "node_modules/compress-commons/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==", "funding": [ { "type": "github", @@ -3956,8 +3756,6 @@ }, "node_modules/compress-commons/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -3969,8 +3767,6 @@ }, "node_modules/constant-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-3.0.4.tgz", - "integrity": "sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -3988,8 +3784,6 @@ }, "node_modules/crc-32": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/crc-32/-/crc-32-1.2.2.tgz", - "integrity": "sha512-ROmzCKrTnOwybPcJApAA6WBWij23HVfGVNKqqrZpuyZOHqK2CwHSvpGuyt/UNNvaIjEd8X5IFGp4Mh+Ie1IHJQ==", "license": "Apache-2.0", "bin": { "crc32": "bin/crc32.njs" @@ -4000,8 +3794,6 @@ }, "node_modules/crc32-stream": { "version": "6.0.0", - "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-6.0.0.tgz", - "integrity": "sha512-piICUB6ei4IlTv1+653yq5+KoqfBYmj9bw6LqXoOneTMDXk5nM1qt12mFW1caG3LlJXEKW1Bp0WggEmIfQB34g==", "license": "MIT", "dependencies": { "crc-32": "^1.2.0", @@ -4013,8 +3805,6 @@ }, "node_modules/crc32-stream/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -4029,8 +3819,6 @@ }, "node_modules/crc32-stream/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==", "funding": [ { "type": "github", @@ -4049,8 +3837,6 @@ }, "node_modules/crc32-stream/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -4086,8 +3872,6 @@ }, "node_modules/csprng": { "version": "0.1.2", - "resolved": "https://registry.npmjs.org/csprng/-/csprng-0.1.2.tgz", - "integrity": "sha512-D3WAbvvgUVIqSxUfdvLeGjuotsB32bvfVPd+AaaTWMtyUeC9zgCnw5xs94no89yFLVsafvY9dMZEhTwsY/ZecA==", "license": "MIT", "dependencies": { "sequin": "*" @@ -4098,14 +3882,10 @@ }, "node_modules/csv-parse": { "version": "5.6.0", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-5.6.0.tgz", - "integrity": "sha512-l3nz3euub2QMg5ouu5U09Ew9Wf6/wQ8I++ch1loQ0ljmzhmfZYrH9fflS22i/PQEvsPvxCwxgz5q7UB8K1JO4Q==", "license": "MIT" }, "node_modules/csv-stringify": { "version": "6.8.1", - "resolved": "https://registry.npmjs.org/csv-stringify/-/csv-stringify-6.8.1.tgz", - "integrity": "sha512-tZ6X6TKQyQgCo5OptXcyAbfN1pwmoxEqELPQ7KFazNErx7kiVsDK8o+VYRXhfMl4N9vvOOLXuioquR2MeP847A==", "license": "MIT" }, "node_modules/damerau-levenshtein": { @@ -4166,8 +3946,6 @@ }, "node_modules/dateformat": { "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", "license": "MIT", "engines": { "node": "*" @@ -4190,8 +3968,6 @@ }, "node_modules/dedent": { "version": "1.7.2", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.7.2.tgz", - "integrity": "sha512-WzMx3mW98SN+zn3hgemf4OzdmyNhhhKz5Ay0pUfQiMQ3e1g+xmTJWp/pKdwKVXhdSkAEGIIzqeuWrL3mV/AXbA==", "devOptional": true, "license": "MIT", "peerDependencies": { @@ -4209,8 +3985,6 @@ }, "node_modules/deepmerge": { "version": "4.3.1", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", - "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", "devOptional": true, "license": "MIT", "engines": { @@ -4261,8 +4035,6 @@ }, "node_modules/delayed-stream": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -4270,8 +4042,6 @@ }, "node_modules/detect-newline": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "devOptional": true, "license": "MIT", "engines": { @@ -4290,8 +4060,6 @@ }, "node_modules/dot-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -4320,14 +4088,10 @@ }, "node_modules/eastasianwidth": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", "license": "MIT" }, "node_modules/ecdsa-sig-formatter": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", - "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -4339,8 +4103,6 @@ }, "node_modules/emittery": { "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "devOptional": true, "license": "MIT", "engines": { @@ -4356,8 +4118,6 @@ }, "node_modules/end-of-stream": { "version": "1.4.5", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.5.tgz", - "integrity": "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==", "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -4365,8 +4125,6 @@ }, "node_modules/error-ex": { "version": "1.3.4", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz", - "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -4666,8 +4424,6 @@ }, "node_modules/eslint-plugin-import": { "version": "2.32.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", - "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", @@ -4741,8 +4497,6 @@ }, "node_modules/eslint-plugin-jest": { "version": "29.16.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-29.16.0.tgz", - "integrity": "sha512-0WFBxDHlT2ratGQfnFQEVIsgQJ5cfd+0IV8Kc6U3X2onB8ATLG23voD2Ch5G9fCkEpCPmCMuzW0tbS0kYb8biw==", "license": "MIT", "dependencies": { "@typescript-eslint/utils": "^8.0.0" @@ -4845,8 +4599,6 @@ }, "node_modules/eslint-plugin-react-hooks": { "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-7.1.1.tgz", - "integrity": "sha512-f2I7Gw6JbvCexzIInuSbZpfdQ44D7iqdWX01FKLvrPgqxoE7oMj8clOfto8U6vYiz4yd5oKu39rRSVOe1zRu0g==", "license": "MIT", "dependencies": { "@babel/core": "^7.24.4", @@ -5106,8 +4858,6 @@ }, "node_modules/event-target-shim": { "version": "5.0.1", - "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", - "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", "license": "MIT", "engines": { "node": ">=6" @@ -5115,8 +4865,6 @@ }, "node_modules/events": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", "license": "MIT", "engines": { "node": ">=0.8.x" @@ -5124,8 +4872,6 @@ }, "node_modules/events-universal": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/events-universal/-/events-universal-1.0.1.tgz", - "integrity": "sha512-LUd5euvbMLpwOF8m6ivPCbhQeSiYVNb8Vs0fQ8QjXo0JTkEHpz8pxdQf0gStltaPpw0Cca8b39KxvK9cfKRiAw==", "license": "Apache-2.0", "dependencies": { "bare-events": "^2.7.0" @@ -5133,8 +4879,6 @@ }, "node_modules/execa": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -5157,15 +4901,11 @@ }, "node_modules/execa/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==", "devOptional": true, "license": "ISC" }, "node_modules/exit-x": { "version": "0.2.2", - "resolved": "https://registry.npmjs.org/exit-x/-/exit-x-0.2.2.tgz", - "integrity": "sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==", "devOptional": true, "license": "MIT", "engines": { @@ -5174,8 +4914,6 @@ }, "node_modules/expect": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-30.4.1.tgz", - "integrity": "sha512-PMARsyh/JtqC20HoGqlFcIlQAyqUtW4PlI1rup1uhYJtKuwAjbvWi3GQMAn+STdHum/dk8xrKfUM1+5SAwpolA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -5192,8 +4930,6 @@ }, "node_modules/fast-copy": { "version": "3.0.2", - "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", - "integrity": "sha512-dl0O9Vhju8IrcLndv2eU4ldt1ftXMqqfgN4H1cpmGV7P6jeB9FwpN9a2c8DPGE1Ys88rNUJVYDHq73CGAGOPfQ==", "license": "MIT" }, "node_modules/fast-deep-equal": { @@ -5202,14 +4938,10 @@ }, "node_modules/fast-fifo": { "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz", - "integrity": "sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==", "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==", "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", @@ -5224,8 +4956,6 @@ }, "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==", "license": "ISC", "dependencies": { "is-glob": "^4.0.1" @@ -5244,14 +4974,10 @@ }, "node_modules/fast-safe-stringify": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", - "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", "license": "MIT" }, "node_modules/fast-uri": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", - "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -5266,8 +4992,6 @@ }, "node_modules/fast-xml-builder": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-xml-builder/-/fast-xml-builder-1.2.0.tgz", - "integrity": "sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==", "funding": [ { "type": "github", @@ -5282,8 +5006,6 @@ }, "node_modules/fast-xml-parser": { "version": "4.5.6", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.6.tgz", - "integrity": "sha512-Yd4vkROfJf8AuJrDIVMVmYfULKmIJszVsMv7Vo71aocsKgFxpdlpSHXSaInvyYfgw2PRuObQSW2GFpVMUjxu9A==", "funding": [ { "type": "github", @@ -5300,8 +5022,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">= 4.9.1" @@ -5316,8 +5036,6 @@ }, "node_modules/faye": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/faye/-/faye-1.4.1.tgz", - "integrity": "sha512-Cg/khikhqlvumHO3efwx2tps2ZgQRjUMrO24G0quz7MMzRYYaEjU224YFXOeuPIvanRegIchVxj6pmHK1W0ikA==", "license": "Apache-2.0", "dependencies": { "asap": "*", @@ -5333,8 +5051,6 @@ }, "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==", "license": "Apache-2.0", "dependencies": { "websocket-driver": ">=0.5.1" @@ -5363,8 +5079,6 @@ }, "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==", "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" @@ -5467,8 +5181,6 @@ }, "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==", "license": "ISC", "dependencies": { "cross-spawn": "^7.0.6", @@ -5483,8 +5195,6 @@ }, "node_modules/form-data": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.6.tgz", - "integrity": "sha512-vKatAh4SlVfgbv+YtmhiRjhEMJsYpsG1Y2rMQtR+SVSbytsSD1YGzDIcrAJmdFec88u/+VoGmxnl+80gL1tRCQ==", "license": "MIT", "dependencies": { "asynckit": "^0.4.0", @@ -5499,8 +5209,6 @@ }, "node_modules/fs-extra": { "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", "dev": true, "license": "MIT", "dependencies": { @@ -5575,8 +5283,6 @@ }, "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==", "devOptional": true, "license": "ISC", "engines": { @@ -5626,8 +5332,6 @@ }, "node_modules/get-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "devOptional": true, "license": "MIT", "engines": { @@ -5666,9 +5370,6 @@ }, "node_modules/glob": { "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "foreground-child": "^3.1.0", @@ -5697,8 +5398,6 @@ }, "node_modules/glob-to-regex.js": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/glob-to-regex.js/-/glob-to-regex.js-1.2.0.tgz", - "integrity": "sha512-QMwlOQKU/IzqMUOAZWubUOT8Qft+Y0KQWnX9nK3ch0CJg0tTp4TvGZsTfudYKv2NzoQSyPcnA6TYeIQ3jGichQ==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -5713,8 +5412,6 @@ }, "node_modules/globals": { "version": "17.7.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", - "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", "license": "MIT", "engines": { "node": ">=18" @@ -5757,8 +5454,6 @@ }, "node_modules/handlebars": { "version": "4.7.9", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.9.tgz", - "integrity": "sha512-4E71E0rpOaQuJR2A3xDZ+GM1HyWYv1clR58tC8emQNeQe3RH7MAzSbat+V0wG78LQBo6m6bzSG/L4pBuCsgnUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -5842,8 +5537,6 @@ }, "node_modules/hasown": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", - "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -5854,8 +5547,6 @@ }, "node_modules/header-case": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-2.0.4.tgz", - "integrity": "sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==", "license": "MIT", "dependencies": { "capital-case": "^1.0.4", @@ -5864,8 +5555,6 @@ }, "node_modules/help-me": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/help-me/-/help-me-5.0.0.tgz", - "integrity": "sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==", "license": "MIT" }, "node_modules/hermes-estree": { @@ -5881,15 +5570,11 @@ }, "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==", "devOptional": true, "license": "MIT" }, "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==", "license": "MIT" }, "node_modules/http-proxy-agent": { @@ -5916,8 +5601,6 @@ }, "node_modules/human-signals": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "devOptional": true, "license": "Apache-2.0", "engines": { @@ -5940,8 +5623,6 @@ }, "node_modules/hyperdyperid": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/hyperdyperid/-/hyperdyperid-1.2.0.tgz", - "integrity": "sha512-Y93lCzHYgGWdrJ66yIktxiaGULYc6oGiABxhcO5AufBeOyoIdZF7bIfLaOrbM0iGIOXQQgxxRrFEnb+Y6w1n4A==", "license": "MIT", "engines": { "node": ">=10.18" @@ -5949,8 +5630,6 @@ }, "node_modules/ieee754": { "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", "funding": [ { "type": "github", @@ -5976,8 +5655,6 @@ }, "node_modules/immediate": { "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==", "license": "MIT" }, "node_modules/import-fresh": { @@ -5996,8 +5673,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6069,8 +5744,6 @@ }, "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==", "devOptional": true, "license": "MIT" }, @@ -6192,8 +5865,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=8" @@ -6201,8 +5872,6 @@ }, "node_modules/is-generator-fn": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "devOptional": true, "license": "MIT", "engines": { @@ -6258,8 +5927,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=0.12.0" @@ -6327,8 +5994,6 @@ }, "node_modules/is-stream": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "license": "MIT", "engines": { "node": ">=8" @@ -6381,8 +6046,6 @@ }, "node_modules/is-unsafe": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-unsafe/-/is-unsafe-1.0.1.tgz", - "integrity": "sha512-CLK2+VdgERgD96EYm5lUQssZYlRg2tkZnbsxZoacmSiRxiFJ4Nk4SzjCl+Ur+v3kXIY9dTIdb3IH22y1mZ56LA==", "funding": [ { "type": "github", @@ -6471,8 +6134,6 @@ }, "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==", "devOptional": true, "license": "BSD-3-Clause", "dependencies": { @@ -6486,8 +6147,6 @@ }, "node_modules/istanbul-lib-source-maps": { "version": "5.0.6", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz", - "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==", "devOptional": true, "license": "BSD-3-Clause", "dependencies": { @@ -6501,8 +6160,6 @@ }, "node_modules/istanbul-reports": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", - "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "devOptional": true, "license": "BSD-3-Clause", "dependencies": { @@ -6530,8 +6187,6 @@ }, "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==", "license": "BlueOak-1.0.0", "dependencies": { "@isaacs/cliui": "^8.0.2" @@ -6545,8 +6200,6 @@ }, "node_modules/jest": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-30.4.2.tgz", - "integrity": "sha512-Yi1jqNC/Oq0N4hBgNH/YvBpP1P57QqundgytzYqy3yqAa7NZPNjSoi4SGbRAXDMdBzNE6xBCi5U7RgfrvMEUVQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6572,8 +6225,6 @@ }, "node_modules/jest-changed-files": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-30.4.1.tgz", - "integrity": "sha512-IuctmYrxi21iOSOaIXpJWalHyPAsVv0GeBHKDn8C1CA4W5htHn7INL+wdnL4Bo0+olEndvAFkmb++tIQJG+vvg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6587,8 +6238,6 @@ }, "node_modules/jest-circus": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-30.4.2.tgz", - "integrity": "sha512-rvHH7VlY6LgbJXJTQ87GW62g1FntOtbhh0zT+v04kC+pgL6aBKyYINXxWukCpj3dcIBMw5/XUbtDS9dU9JTXeQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6619,8 +6268,6 @@ }, "node_modules/jest-cli": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-30.4.2.tgz", - "integrity": "sha512-jfA2ocvVHMXS2QijrJ0d31ektP+d/W0T5RpcTX2Pq+3sVqHlsXVCM2+FmwpL+bdY8OfHpIg9xMxLF17Zg0U49Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6652,8 +6299,6 @@ }, "node_modules/jest-config": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-30.4.2.tgz", - "integrity": "sha512-rNHAShJQqQwFNoL0hbf3BphSBOWnpOUAKvidLS/AjNVLPfoj5mSf4jQMfW3cYOs6hXeZC7nF7mDHaBnbxELOzg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6703,8 +6348,6 @@ }, "node_modules/jest-diff": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-30.4.1.tgz", - "integrity": "sha512-CRpFK0RtLriVDGcPPAnR6HMVI8bSR2jnUIgralhauzYQZIb4RH9AtEInTuQr65LmmGggGcRT6HIASxwqsVsmlA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6719,8 +6362,6 @@ }, "node_modules/jest-docblock": { "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-30.4.0.tgz", - "integrity": "sha512-ZPMabUZCx5MpbZ2eBYSvZ0J8fvo3dR9oM+eeUpb3aKNQFuS2tu3Duw1TNlMoP8k3WQgKGJuhcMFvwcVuq6T7oA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6732,8 +6373,6 @@ }, "node_modules/jest-each": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-30.4.1.tgz", - "integrity": "sha512-/8MJbH6fuj48TstjrMf+u/pd06Qezz5xOXvZA6442heNOWr8bdeoGZX2d9fCn028CoMgYmroH9//zky5GfyYmA==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6749,8 +6388,6 @@ }, "node_modules/jest-environment-node": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-30.4.1.tgz", - "integrity": "sha512-4FZYVOk85hz2AyT6BbarKy9u37g6DbrDyCdFhsnDdXqyrueYQvB+0zO4f/kqLCRD0BsPRXPMNJeQwihKZV8naw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6768,8 +6405,6 @@ }, "node_modules/jest-haste-map": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-30.4.1.tgz", - "integrity": "sha512-rFrcONd8jeFsyw+Z9CrScJgglRf2+NFmNam8dKu7n+SoHqNYT47mn0DdEcVUZJpvh7Iz6/si7f7yUH7GJHVgnw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6793,8 +6428,6 @@ }, "node_modules/jest-haste-map/node_modules/picomatch": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "devOptional": true, "license": "MIT", "engines": { @@ -6806,8 +6439,6 @@ }, "node_modules/jest-leak-detector": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-30.4.1.tgz", - "integrity": "sha512-IpmyiioeHxiWDhesHnUFmOxcTzwCwKpgACgWajtAP+nYQXiY7DakTxB6Bx9JFiRMljr0AX1PvnQdaU1KFoz6NQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6820,8 +6451,6 @@ }, "node_modules/jest-matcher-utils": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-30.4.1.tgz", - "integrity": "sha512-zvYfX5CaeEkFrrLS9suWe9rvJrm9J1Iv3ua8kIBv9GEPzcnsfBf0bob37la7s67fs0nlBC3EuvkOLnXQKxtx4A==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6836,8 +6465,6 @@ }, "node_modules/jest-message-util": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-30.4.1.tgz", - "integrity": "sha512-kwCKIvq0MCW1HzLoGola9Te6JUdzgV0loyKJ3Qghrkz9i5/RRIHsL95BMQc2HBBhlBKC4j22K9p11TGHH8RBpQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6858,8 +6485,6 @@ }, "node_modules/jest-message-util/node_modules/picomatch": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz", - "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==", "devOptional": true, "license": "MIT", "engines": { @@ -6871,8 +6496,6 @@ }, "node_modules/jest-mock": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-30.4.1.tgz", - "integrity": "sha512-/i8SVb8/NSB7RfNi8gfqu8gxLV23KaL5EpAttyb9iz8qWRIqXRLflycz/32wXsYkOnaUlx8NAKnJYtpsmXUmfw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6886,8 +6509,6 @@ }, "node_modules/jest-pnp-resolver": { "version": "1.2.3", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", - "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "devOptional": true, "license": "MIT", "engines": { @@ -6904,8 +6525,6 @@ }, "node_modules/jest-regex-util": { "version": "30.4.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.4.0.tgz", - "integrity": "sha512-mWlvLviKIgIQ8VCuM1xRdD0TWp3zlzionlmDBjuXVBs+VkmXq6FgW9T4Emr7oGz/Rk6feDCGyiugolcQEyp3mg==", "devOptional": true, "license": "MIT", "engines": { @@ -6914,8 +6533,6 @@ }, "node_modules/jest-resolve": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-30.4.1.tgz", - "integrity": "sha512-Zry8Yq/yJcNAZ7dJ5F2heic8AheXvbFZ7XI5V+h28nrYZ7Qoyy4dItq8OodjnYD270mvX+ZudmrNV9cysqhW5Q==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6934,8 +6551,6 @@ }, "node_modules/jest-resolve-dependencies": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-30.4.2.tgz", - "integrity": "sha512-gDiVh1I+GxYzz9oXlyw+1wv6VOYX1WYxMOfjsA3iGKePV2oxmbHhwxfkALxNxYy1ciw6APWwkW2zZONwP97aEQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6948,8 +6563,6 @@ }, "node_modules/jest-runner": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-30.4.2.tgz", - "integrity": "sha512-2dw0PslVYXxffXGpLo+Ejad+KcI1Qkjn7f4X4619gf21oCUmL+SPfjqIa/losUem3yEOvfNZe/F1HWUcNpODcg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -6982,8 +6595,6 @@ }, "node_modules/jest-runtime": { "version": "30.4.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-30.4.2.tgz", - "integrity": "sha512-3/5e8iPz2k/VLqlr8DgTftYyLUv8Su3FkCAO2/Od81UsUTpSxOrS6O5x5KkoQwyUjmpYyDJKeyAvg2T2nvpNkQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7016,8 +6627,6 @@ }, "node_modules/jest-snapshot": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-30.4.1.tgz", - "integrity": "sha512-tEOkkfOMppUyeiHwjZswOQ3lcnoTnws/q5FnGIaeIh/jmoU0ZlgMYRR8sTlTj+nNGCoJ0RDq6SfxGxCsyMTPmw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7049,8 +6658,6 @@ }, "node_modules/jest-util": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-30.4.1.tgz", - "integrity": "sha512-vjQb1sACEiv13DKJMDToJpzVW0joCsIQrmbg0fi7CyOOt+g9jTuQl2A216pWRBYhOVt53XbL/2LbMKg1BECWOw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7078,8 +6685,6 @@ }, "node_modules/jest-validate": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-30.4.1.tgz", - "integrity": "sha512-PDWi4SOwLnwqNDfHZjOcsEFyZ4fc/2W2gVL3DEoyqnB6jCQMLRtfBong8s6omIw3lI0HWOus12xfnFmQtjW3fw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7096,8 +6701,6 @@ }, "node_modules/jest-validate/node_modules/camelcase": { "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "devOptional": true, "license": "MIT", "engines": { @@ -7109,8 +6712,6 @@ }, "node_modules/jest-watcher": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-30.4.1.tgz", - "integrity": "sha512-/l9UonmvCwjHH7d2h3iAwIloLc1H0S8mJZ/LNK3i86hqwPAz8otUJjP9MfYtz9Tt77Su5FD2xGjZn8d31IZHlw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7129,8 +6730,6 @@ }, "node_modules/jest-worker": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-30.4.1.tgz", - "integrity": "sha512-SHynN/q/QD++iNyvMdy+WMmbCGk8jIsNcRxycXbWubSOhvo6T+j2afcfUSl+3hYsiBebOTo0cT7c2H7CXugu1g==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7146,8 +6745,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7162,8 +6759,6 @@ }, "node_modules/joycon": { "version": "3.1.1", - "resolved": "https://registry.npmjs.org/joycon/-/joycon-3.1.1.tgz", - "integrity": "sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==", "license": "MIT", "engines": { "node": ">=10" @@ -7175,8 +6770,6 @@ }, "node_modules/js-yaml": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", - "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", "funding": [ { "type": "github", @@ -7197,8 +6790,6 @@ }, "node_modules/js2xmlparser": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", - "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", "license": "Apache-2.0", "dependencies": { "xmlcreate": "^2.0.4" @@ -7220,8 +6811,6 @@ }, "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==", "devOptional": true, "license": "MIT" }, @@ -7245,8 +6834,6 @@ }, "node_modules/jsonfile": { "version": "6.2.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.1.tgz", - "integrity": "sha512-zwOTdL3rFQ/lRdBnntKVOX6k5cKJwEc1HdilT71BWEu7J41gXIB2MRp+vxduPSwZJPWBxEzv4yH1wYLJGUHX4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -7258,8 +6845,6 @@ }, "node_modules/jsonwebtoken": { "version": "9.0.3", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.3.tgz", - "integrity": "sha512-MT/xP0CrubFRNLNKvxJ2BYfy53Zkm++5bX9dtuPbqAeQpTVe0MQTFhao8+Cp//EmJp244xt6Drw/GVEGCUj40g==", "license": "MIT", "dependencies": { "jws": "^4.0.1", @@ -7293,8 +6878,6 @@ }, "node_modules/jszip": { "version": "3.10.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz", - "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==", "license": "(MIT OR GPL-3.0-or-later)", "dependencies": { "lie": "~3.3.0", @@ -7305,8 +6888,6 @@ }, "node_modules/jwa": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.1.tgz", - "integrity": "sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==", "license": "MIT", "dependencies": { "buffer-equal-constant-time": "^1.0.1", @@ -7316,8 +6897,6 @@ }, "node_modules/jws": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jws/-/jws-4.0.1.tgz", - "integrity": "sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==", "license": "MIT", "dependencies": { "jwa": "^2.0.1", @@ -7347,8 +6926,6 @@ }, "node_modules/lazystream": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", "license": "MIT", "dependencies": { "readable-stream": "^2.0.5" @@ -7359,8 +6936,6 @@ }, "node_modules/leven": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "devOptional": true, "license": "MIT", "engines": { @@ -7380,8 +6955,6 @@ }, "node_modules/lie": { "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", "license": "MIT", "dependencies": { "immediate": "~3.0.5" @@ -7389,8 +6962,6 @@ }, "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==", "devOptional": true, "license": "MIT" }, @@ -7409,44 +6980,30 @@ }, "node_modules/lodash": { "version": "4.18.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz", - "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==", "license": "MIT" }, "node_modules/lodash.includes": { "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", - "integrity": "sha512-W3Bx6mdkRTGtlJISOvVD/lbqjTlPPUDTMnlXZFnVwi9NKJ6tiAk6LVdlhZMm17VZisqhKcgzpO5Wz91PCt5b0w==", "license": "MIT" }, "node_modules/lodash.isboolean": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", - "integrity": "sha512-Bz5mupy2SVbPHURB98VAcw+aHh4vRV5IPNhILUCsOzRmsTmSQ17jIuqopAentWoehktxGd9e/hbIXq980/1QJg==", "license": "MIT" }, "node_modules/lodash.isinteger": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", - "integrity": "sha512-DBwtEWN2caHQ9/imiNeEA5ys1JoRtRfY3d7V9wkqtbycnAmTvRRmbHKDV4a0EYc678/dia0jrte4tjYwVBaZUA==", "license": "MIT" }, "node_modules/lodash.isnumber": { "version": "3.0.3", - "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", - "integrity": "sha512-QYqzpfwO3/CWf3XP+Z+tkQsfaLL/EnUlXWVkIk5FUPc4sBdTehEqZONuyRt2P67PXAk+NXmTBcc97zw9t1FQrw==", "license": "MIT" }, "node_modules/lodash.isplainobject": { "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==", "license": "MIT" }, "node_modules/lodash.isstring": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", - "integrity": "sha512-0wJxfxH1wgO3GrbuP+dTTk7op+6L41QCXbGINEmD+ny/G/eCqGzxyCsh7159S+mgDDcoarnBw6PC1PS5+wUGgw==", "license": "MIT" }, "node_modules/lodash.memoize": { @@ -7460,8 +7017,6 @@ }, "node_modules/lodash.once": { "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", - "integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==", "license": "MIT" }, "node_modules/loose-envify": { @@ -7476,8 +7031,6 @@ }, "node_modules/lower-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -7492,8 +7045,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7532,8 +7083,6 @@ }, "node_modules/memfs": { "version": "4.38.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-4.38.1.tgz", - "integrity": "sha512-exfrOkkU3m0EpbQ0iQJP93HUbkprnIBU7IUnobSNAzHkBUzsklLwENGLEm8ZwJmMuLoFEfv1pYQ54wSpkay4kQ==", "license": "Apache-2.0", "dependencies": { "@jsonjoy.com/json-pack": "^1.11.0", @@ -7558,8 +7107,6 @@ }, "node_modules/merge2": { "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "license": "MIT", "engines": { "node": ">= 8" @@ -7574,8 +7121,6 @@ }, "node_modules/micromatch": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "license": "MIT", "dependencies": { "braces": "^3.0.3", @@ -7587,8 +7132,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==", "license": "MIT", "engines": { "node": ">= 0.6" @@ -7596,8 +7139,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==", "license": "MIT", "dependencies": { "mime-db": "1.52.0" @@ -7608,8 +7149,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==", "devOptional": true, "license": "MIT", "engines": { @@ -7649,8 +7188,6 @@ }, "node_modules/multistream": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/multistream/-/multistream-3.1.0.tgz", - "integrity": "sha512-zBgD3kn8izQAN/TaL1PCMv15vYpf+Vcrsfub06njuYVYlzUldzpopTlrEZ53pZVEbfn3Shtv7vRFoOv6LOV87Q==", "license": "MIT", "dependencies": { "inherits": "^2.0.1", @@ -7659,8 +7196,6 @@ }, "node_modules/multistream/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==", "license": "MIT", "dependencies": { "inherits": "^2.0.3", @@ -7673,8 +7208,6 @@ }, "node_modules/napi-postinstall": { "version": "0.3.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", - "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "devOptional": true, "license": "MIT", "bin": { @@ -7693,8 +7226,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" }, @@ -7707,8 +7238,6 @@ }, "node_modules/no-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", "license": "MIT", "dependencies": { "lower-case": "^2.0.2", @@ -7717,8 +7246,6 @@ }, "node_modules/node-fetch": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", - "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==", "license": "MIT", "dependencies": { "whatwg-url": "^5.0.0" @@ -7764,8 +7291,6 @@ }, "node_modules/npm-run-path": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -7876,8 +7401,6 @@ }, "node_modules/on-exit-leak-free": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", - "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", "license": "MIT", "engines": { "node": ">=14.0.0" @@ -7892,8 +7415,6 @@ }, "node_modules/onetime": { "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8004,14 +7525,10 @@ }, "node_modules/pako": { "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", "license": "(MIT AND Zlib)" }, "node_modules/param-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -8030,8 +7547,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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8049,8 +7564,6 @@ }, "node_modules/pascal-case": { "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -8059,8 +7572,6 @@ }, "node_modules/path-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-3.0.4.tgz", - "integrity": "sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==", "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -8076,8 +7587,6 @@ }, "node_modules/path-expression-matcher": { "version": "1.6.1", - "resolved": "https://registry.npmjs.org/path-expression-matcher/-/path-expression-matcher-1.6.1.tgz", - "integrity": "sha512-h7bxdzhHk8Knyc4Tj+jMaa7fEEoUJy7p1qtbVgkYg1Uhpe5Np5VuGXCRZnkZvU+Q42M1vStt0ifa3ueykRJPmQ==", "funding": [ { "type": "github", @@ -8109,8 +7618,6 @@ }, "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==", "license": "BlueOak-1.0.0", "dependencies": { "lru-cache": "^10.2.0", @@ -8125,8 +7632,6 @@ }, "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==", "license": "ISC" }, "node_modules/picocolors": { @@ -8145,8 +7650,6 @@ }, "node_modules/pino": { "version": "9.14.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.14.0.tgz", - "integrity": "sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==", "license": "MIT", "dependencies": { "@pinojs/redact": "^0.4.0", @@ -8167,8 +7670,6 @@ }, "node_modules/pino-abstract-transport": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.2.0.tgz", - "integrity": "sha512-Guhh8EZfPCfH+PMXAb6rKOjGQEoy0xlAIn+irODG5kgfYV+BQ0rGYYWTIel3P5mmyXqkYkPmdIkywsn6QKUR1Q==", "license": "MIT", "dependencies": { "readable-stream": "^4.0.0", @@ -8177,8 +7678,6 @@ }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -8193,8 +7692,6 @@ }, "node_modules/pino-abstract-transport/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==", "funding": [ { "type": "github", @@ -8213,8 +7710,6 @@ }, "node_modules/pino-abstract-transport/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -8222,8 +7717,6 @@ }, "node_modules/pino-pretty": { "version": "11.3.0", - "resolved": "https://registry.npmjs.org/pino-pretty/-/pino-pretty-11.3.0.tgz", - "integrity": "sha512-oXwn7ICywaZPHmu3epHGU2oJX4nPmKvHvB/bwrJHlGcbEWaVcotkpyVHMKLKmiVryWYByNp0jpgAcXpFJDXJzA==", "license": "MIT", "dependencies": { "colorette": "^2.0.7", @@ -8247,8 +7740,6 @@ }, "node_modules/pino-pretty/node_modules/pino-abstract-transport": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", - "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", "license": "MIT", "dependencies": { "split2": "^4.0.0" @@ -8256,8 +7747,6 @@ }, "node_modules/pino-pretty/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -8272,8 +7761,6 @@ }, "node_modules/pino-pretty/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==", "funding": [ { "type": "github", @@ -8292,8 +7779,6 @@ }, "node_modules/pino-pretty/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -8301,14 +7786,10 @@ }, "node_modules/pino-std-serializers": { "version": "7.1.0", - "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-7.1.0.tgz", - "integrity": "sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==", "license": "MIT" }, "node_modules/pino/node_modules/pino-abstract-transport": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-2.0.0.tgz", - "integrity": "sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==", "license": "MIT", "dependencies": { "split2": "^4.0.0" @@ -8324,8 +7805,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8337,8 +7816,6 @@ }, "node_modules/pkg-dir/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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8351,8 +7828,6 @@ }, "node_modules/pkg-dir/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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8364,8 +7839,6 @@ }, "node_modules/pkg-dir/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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8380,8 +7853,6 @@ }, "node_modules/pkg-dir/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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8407,8 +7878,6 @@ }, "node_modules/pretty-format": { "version": "30.4.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-30.4.1.tgz", - "integrity": "sha512-K6KiKMHTL4jjX4u3Kir2EW07nRfcqVTXIImx50wbjHQTcZPgg+gjVeNTIT3l3L1Rd4UefxfogquC9J37SoFyyw==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8434,8 +7903,6 @@ }, "node_modules/process": { "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", "license": "MIT", "engines": { "node": ">= 0.6.0" @@ -8447,8 +7914,6 @@ }, "node_modules/process-warning": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-5.0.0.tgz", - "integrity": "sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==", "funding": [ { "type": "github", @@ -8476,8 +7941,6 @@ }, "node_modules/proper-lockfile": { "version": "4.1.2", - "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", - "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", "license": "MIT", "dependencies": { "graceful-fs": "^4.2.4", @@ -8487,8 +7950,6 @@ }, "node_modules/proper-lockfile/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==", "license": "ISC" }, "node_modules/proxy-agent": { @@ -8521,8 +7982,6 @@ }, "node_modules/pump": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", - "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -8538,8 +7997,6 @@ }, "node_modules/pure-rand": { "version": "7.0.1", - "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-7.0.1.tgz", - "integrity": "sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==", "devOptional": true, "funding": [ { @@ -8573,23 +8030,17 @@ }, "node_modules/quick-format-unescaped": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", - "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", "license": "MIT" }, "node_modules/react-is-18": { "name": "react-is", "version": "18.3.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", - "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "devOptional": true, "license": "MIT" }, "node_modules/react-is-19": { "name": "react-is", "version": "19.2.6", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-19.2.6.tgz", - "integrity": "sha512-XjBR15BhXuylgWGuslhDKqlSayuqvqBX91BP8pauG8kd1zY8kotkNWbXksTCNRarse4kuGbe2kIY05ARtwNIvw==", "devOptional": true, "license": "MIT" }, @@ -8612,8 +8063,6 @@ }, "node_modules/readdir-glob": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/readdir-glob/-/readdir-glob-1.1.3.tgz", - "integrity": "sha512-v05I2k7xN8zXvPD9N+z/uhXPaj0sUFCe2rcWZIpBsqxfP7xXFQ0tipAd/wjj1YxWyWtUS5IDJpOG82JKt2EAVA==", "license": "Apache-2.0", "dependencies": { "minimatch": "^5.1.0" @@ -8621,8 +8070,6 @@ }, "node_modules/readdir-glob/node_modules/minimatch": { "version": "5.1.9", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", - "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -8633,8 +8080,6 @@ }, "node_modules/real-require": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.2.0.tgz", - "integrity": "sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==", "license": "MIT", "engines": { "node": ">= 12.13.0" @@ -8680,8 +8125,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==", "devOptional": true, "license": "MIT", "engines": { @@ -8690,8 +8133,6 @@ }, "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==", "license": "MIT", "engines": { "node": ">=0.10.0" @@ -8717,8 +8158,6 @@ }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -8730,8 +8169,6 @@ }, "node_modules/resolve-cwd/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==", "devOptional": true, "license": "MIT", "engines": { @@ -8747,8 +8184,6 @@ }, "node_modules/retire": { "version": "5.4.3", - "resolved": "https://registry.npmjs.org/retire/-/retire-5.4.3.tgz", - "integrity": "sha512-a+CNXfbCTC/kAQLeFxfN9/kts1NlFMo5lrjBefmFssdOJy0XYPNpRN4k63hwIhhzyzPvHziZrQHWKdJNf6Lp5g==", "license": "Apache-2.0", "dependencies": { "ansi-colors": "^4.1.1", @@ -8767,8 +8202,6 @@ }, "node_modules/retry": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "license": "MIT", "engines": { "node": ">= 4" @@ -8970,8 +8403,6 @@ }, "node_modules/safe-stable-stringify": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.5.0.tgz", - "integrity": "sha512-b3rppTKm9T+PsVCBEOUR46GWI7fdOs00VKZ1+9c1EWDaDMvjQc6tUwuFyIprgGgTcWoVHSKrU8H31ZHA2e0RHA==", "license": "MIT", "engines": { "node": ">=10" @@ -8979,8 +8410,6 @@ }, "node_modules/sax": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.6.0.tgz", - "integrity": "sha512-6R3J5M4AcbtLUdZmRv2SygeVaM7IhrLXu9BmnOGmmACak8fiUtOsYNWUS4uK7upbmHIBbLBeFeI//477BKLBzA==", "license": "BlueOak-1.0.0", "engines": { "node": ">=11.0.0" @@ -8988,14 +8417,10 @@ }, "node_modules/secure-json-parse": { "version": "2.7.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-2.7.0.tgz", - "integrity": "sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==", "license": "BSD-3-Clause" }, "node_modules/semver": { "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -9006,8 +8431,6 @@ }, "node_modules/sentence-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-3.0.4.tgz", - "integrity": "sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==", "license": "MIT", "dependencies": { "no-case": "^3.0.4", @@ -9017,8 +8440,6 @@ }, "node_modules/sequin": { "version": "0.1.1", - "resolved": "https://registry.npmjs.org/sequin/-/sequin-0.1.1.tgz", - "integrity": "sha512-hJWMZRwP75ocoBM+1/YaCsvS0j5MTPeBHJkS2/wruehl9xwtX30HlDF1Gt6UZ8HHHY8SJa2/IL+jo+JJCd59rA==", "license": "MIT", "engines": { "node": ">=0.4.0" @@ -9066,8 +8487,6 @@ }, "node_modules/setimmediate": { "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==", "license": "MIT" }, "node_modules/shebang-command": { @@ -9179,8 +8598,6 @@ }, "node_modules/snake-case": { "version": "3.0.4", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-3.0.4.tgz", - "integrity": "sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==", "license": "MIT", "dependencies": { "dot-case": "^3.0.4", @@ -9213,8 +8630,6 @@ }, "node_modules/sonic-boom": { "version": "4.2.1", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-4.2.1.tgz", - "integrity": "sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==", "license": "MIT", "dependencies": { "atomic-sleep": "^1.0.0" @@ -9237,8 +8652,6 @@ }, "node_modules/source-map-support": { "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9248,8 +8661,6 @@ }, "node_modules/split2": { "version": "4.2.0", - "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", - "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", "license": "ISC", "engines": { "node": ">= 10.x" @@ -9292,8 +8703,6 @@ }, "node_modules/streamx": { "version": "2.27.0", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.27.0.tgz", - "integrity": "sha512-WZ189TKnHoAokYHvwzaAQMpd55cgUmFIcJFzBSgGcb886jau5DL+XdDhTWV4ps3FLvk+OORp0dLRTPsLZ21CSA==", "license": "MIT", "dependencies": { "events-universal": "^1.0.0", @@ -9310,8 +8719,6 @@ }, "node_modules/string-length": { "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9324,8 +8731,6 @@ }, "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==", "license": "MIT", "dependencies": { "eastasianwidth": "^0.2.0", @@ -9342,8 +8747,6 @@ "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -9356,14 +8759,10 @@ }, "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==", "license": "MIT" }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -9374,8 +8773,6 @@ }, "node_modules/string-width/node_modules/strip-ansi": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -9495,8 +8892,6 @@ "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==", "license": "MIT", "dependencies": { "ansi-regex": "^5.0.1" @@ -9507,8 +8902,6 @@ }, "node_modules/strip-bom": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "devOptional": true, "license": "MIT", "engines": { @@ -9517,8 +8910,6 @@ }, "node_modules/strip-final-newline": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "devOptional": true, "license": "MIT", "engines": { @@ -9567,8 +8958,6 @@ }, "node_modules/synckit": { "version": "0.11.12", - "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.12.tgz", - "integrity": "sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==", "devOptional": true, "license": "MIT", "dependencies": { @@ -9583,8 +8972,6 @@ }, "node_modules/tar-stream": { "version": "3.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.2.0.tgz", - "integrity": "sha512-ojzvCvVaNp6aOTFmG7jaRD0meowIAuPc3cMMhSgKiVWws1GyHbGd/xvnyuRKcKlMpt3qvxx6r0hreCNITP9hIg==", "license": "MIT", "dependencies": { "b4a": "^1.6.4", @@ -9595,8 +8982,6 @@ }, "node_modules/teex": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", "license": "MIT", "dependencies": { "streamx": "^2.12.5" @@ -9656,8 +9041,6 @@ }, "node_modules/text-decoder": { "version": "1.2.7", - "resolved": "https://registry.npmjs.org/text-decoder/-/text-decoder-1.2.7.tgz", - "integrity": "sha512-vlLytXkeP4xvEq2otHeJfSQIRyWxo/oZGEbXrtEEF9Hnmrdly59sUbzZ/QgyWuLYHctCHxFF4tRQZNQ9k60ExQ==", "license": "Apache-2.0", "dependencies": { "b4a": "^1.6.4" @@ -9669,8 +9052,6 @@ }, "node_modules/thingies": { "version": "2.6.0", - "resolved": "https://registry.npmjs.org/thingies/-/thingies-2.6.0.tgz", - "integrity": "sha512-rMHRjmlFLM1R96UYPvpmnc3LYtdFrT33JIB7L9hetGue1qAPfn1N2LJeEjxUSidu1Iku+haLZXDuEXUHNGO/lg==", "license": "MIT", "engines": { "node": ">=10.18" @@ -9685,8 +9066,6 @@ }, "node_modules/thread-stream": { "version": "3.1.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-3.1.0.tgz", - "integrity": "sha512-OqyPZ9u96VohAyMfJykzmivOrY2wfMSf3C5TtFJVgN+Hm6aj+voFhlK+kZEIv2FBh1X6Xp3DlnCOfEQ3B2J86A==", "license": "MIT", "dependencies": { "real-require": "^0.2.0" @@ -9694,8 +9073,6 @@ }, "node_modules/tinyglobby": { "version": "0.2.17", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", - "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "license": "MIT", "dependencies": { "fdir": "^6.5.0", @@ -9710,8 +9087,6 @@ }, "node_modules/tinyglobby/node_modules/fdir": { "version": "6.5.0", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", - "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "license": "MIT", "engines": { "node": ">=12.0.0" @@ -9727,8 +9102,6 @@ }, "node_modules/tinyglobby/node_modules/picomatch": { "version": "4.0.5", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", - "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "license": "MIT", "engines": { "node": ">=12" @@ -9739,8 +9112,6 @@ }, "node_modules/tldts": { "version": "7.0.27", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.27.tgz", - "integrity": "sha512-I4FZcVFcqCRuT0ph6dCDpPuO4Xgzvh+spkcTr1gK7peIvxWauoloVO0vuy1FQnijT63ss6AsHB6+OIM4aXHbPg==", "license": "MIT", "dependencies": { "tldts-core": "^7.0.27" @@ -9751,8 +9122,6 @@ }, "node_modules/tldts-core": { "version": "7.0.27", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.27.tgz", - "integrity": "sha512-YQ7uPjgWUibIK6DW5lrKujGwUKhLevU4hcGbP5O6TcIUb+oTjJYJVWPS4nZsIHrEEEG6myk/oqAJUEQmpZrHsg==", "license": "MIT" }, "node_modules/tmpl": { @@ -9762,8 +9131,6 @@ }, "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==", "license": "MIT", "dependencies": { "is-number": "^7.0.0" @@ -9774,8 +9141,6 @@ }, "node_modules/tough-cookie": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.1.tgz", - "integrity": "sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==", "license": "BSD-3-Clause", "dependencies": { "tldts": "^7.0.5" @@ -9786,14 +9151,10 @@ }, "node_modules/tr46": { "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", "license": "MIT" }, "node_modules/tree-dump": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/tree-dump/-/tree-dump-1.1.0.tgz", - "integrity": "sha512-rMuvhU4MCDbcbnleZTFezWsaZXRFemSqAM+7jPnzUl1fo9w3YEKOxAeui0fz3OI4EU4hf23iyA7uQRVko+UaBA==", "license": "Apache-2.0", "engines": { "node": ">=10.0" @@ -9808,8 +9169,6 @@ }, "node_modules/ts-api-utils": { "version": "2.5.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", - "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "license": "MIT", "engines": { "node": ">=18.12" @@ -9820,8 +9179,6 @@ }, "node_modules/ts-jest": { "version": "29.4.11", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.4.11.tgz", - "integrity": "sha512-IrFl7l9AuB/qrNw5quqvAv/hmKMb8dhWOH4jQOGo0Oq8tCeo1O86/iTFG1FaRimgUkF13l4PcepO8ATFT6Ns4g==", "dev": true, "license": "MIT", "dependencies": { @@ -9884,8 +9241,6 @@ }, "node_modules/ts-retry-promise": { "version": "0.8.1", - "resolved": "https://registry.npmjs.org/ts-retry-promise/-/ts-retry-promise-0.8.1.tgz", - "integrity": "sha512-+AHPUmAhr5bSRRK5CurE9kNH8gZlEHnCgusZ0zy2bjfatUBDX0h6vGQjiT0YrGwSDwRZmU+bapeX6mj55FOPvg==", "license": "MIT", "engines": { "node": ">=6" @@ -9924,8 +9279,6 @@ }, "node_modules/tunnel-agent": { "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", "license": "Apache-2.0", "dependencies": { "safe-buffer": "^5.0.1" @@ -9946,8 +9299,6 @@ }, "node_modules/type-detect": { "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", "devOptional": true, "license": "MIT", "engines": { @@ -9956,8 +9307,6 @@ }, "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==", "devOptional": true, "license": "(MIT OR CC0-1.0)", "engines": { @@ -10046,8 +9395,6 @@ }, "node_modules/typescript-eslint": { "version": "8.65.0", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.65.0.tgz", - "integrity": "sha512-/ggrHAwyjENDusvyxbuqxAC2dTnZg/Z8F+fgQtYIz+L6n/9HfSlEZcFGV/NsMNa6CkGk0xUjUAFwC0vHOflvIA==", "license": "MIT", "dependencies": { "@typescript-eslint/eslint-plugin": "8.65.0", @@ -10069,8 +9416,6 @@ }, "node_modules/uglify-js": { "version": "3.19.3", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.19.3.tgz", - "integrity": "sha512-v3Xu+yuwBXisp6QYTcH4UbH+xYJXqnq2m/LtQVWKWzYc1iehYnLixoQDN9FH6/j9/oybfd6W9Ghwkl8+UMKTKQ==", "dev": true, "license": "BSD-2-Clause", "optional": true, @@ -10103,8 +9448,6 @@ }, "node_modules/universalify": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", - "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true, "license": "MIT", "engines": { @@ -10113,8 +9456,6 @@ }, "node_modules/unrs-resolver": { "version": "1.12.2", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", - "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", "devOptional": true, "hasInstallScript": true, "license": "MIT", @@ -10151,8 +9492,6 @@ }, "node_modules/unzipper": { "version": "0.12.5", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.12.5.tgz", - "integrity": "sha512-tXYOi9R57Uj/2Z25SOs5RRSzq886MBQj2gY8dPL+xl/kv6s6SvByoKfAtvfVeEuhntWDgjd2o9p2lb4TVPAz0A==", "dev": true, "license": "MIT", "dependencies": { @@ -10193,8 +9532,6 @@ }, "node_modules/upper-case": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-2.0.2.tgz", - "integrity": "sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==", "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -10202,8 +9539,6 @@ }, "node_modules/upper-case-first": { "version": "2.0.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-2.0.2.tgz", - "integrity": "sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==", "license": "MIT", "dependencies": { "tslib": "^2.0.3" @@ -10222,8 +9557,6 @@ }, "node_modules/v8-to-istanbul": { "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", "devOptional": true, "license": "ISC", "dependencies": { @@ -10252,14 +9585,10 @@ }, "node_modules/webidl-conversions": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", "license": "BSD-2-Clause" }, "node_modules/websocket-driver": { "version": "0.7.5", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.5.tgz", - "integrity": "sha512-ZL2+3c7kMBdIRCMz6l8jQMHyGVxj+UL+xVk74Ombiciboca8rHa15L86B19E5oh1pL9Ii/uj54gtsIrZGMo6zA==", "license": "Apache-2.0", "dependencies": { "http-parser-js": ">=0.5.1", @@ -10272,8 +9601,6 @@ }, "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==", "license": "Apache-2.0", "engines": { "node": ">=0.8.0" @@ -10281,8 +9608,6 @@ }, "node_modules/whatwg-url": { "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", "license": "MIT", "dependencies": { "tr46": "~0.0.3", @@ -10388,15 +9713,11 @@ }, "node_modules/wordwrap": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", "dev": true, "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "ansi-styles": "^6.1.0", @@ -10413,8 +9734,6 @@ "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==", "license": "MIT", "dependencies": { "ansi-styles": "^4.0.0", @@ -10430,14 +9749,10 @@ }, "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==", "license": "MIT" }, "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==", "license": "MIT", "dependencies": { "emoji-regex": "^8.0.0", @@ -10450,8 +9765,6 @@ }, "node_modules/wrap-ansi/node_modules/ansi-regex": { "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "license": "MIT", "engines": { "node": ">=12" @@ -10462,8 +9775,6 @@ }, "node_modules/wrap-ansi/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==", "license": "MIT", "engines": { "node": ">=12" @@ -10474,8 +9785,6 @@ }, "node_modules/wrap-ansi/node_modules/strip-ansi": { "version": "7.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz", - "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==", "license": "MIT", "dependencies": { "ansi-regex": "^6.2.2" @@ -10505,8 +9814,6 @@ }, "node_modules/xml-naming": { "version": "0.1.0", - "resolved": "https://registry.npmjs.org/xml-naming/-/xml-naming-0.1.0.tgz", - "integrity": "sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==", "funding": [ { "type": "github", @@ -10520,8 +9827,6 @@ }, "node_modules/xml2js": { "version": "0.6.2", - "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.6.2.tgz", - "integrity": "sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA==", "license": "MIT", "dependencies": { "sax": ">=0.6.0", @@ -10533,8 +9838,6 @@ }, "node_modules/xml2js/node_modules/xmlbuilder": { "version": "11.0.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz", - "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==", "license": "MIT", "engines": { "node": ">=4.0" @@ -10549,14 +9852,10 @@ }, "node_modules/xmlcreate": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", - "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", "license": "Apache-2.0" }, "node_modules/y18n": { "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", "devOptional": true, "license": "ISC", "engines": { @@ -10569,8 +9868,6 @@ }, "node_modules/yargs": { "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "devOptional": true, "license": "MIT", "dependencies": { @@ -10596,15 +9893,11 @@ }, "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==", "devOptional": true, "license": "MIT" }, "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==", "devOptional": true, "license": "MIT", "dependencies": { @@ -10628,8 +9921,6 @@ }, "node_modules/zip-stream": { "version": "6.0.1", - "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-6.0.1.tgz", - "integrity": "sha512-zK7YHHz4ZXpW89AHXUPbQVGKI7uvkd3hzusTdotCg1UxyaVtg0zFJSTfW/Dq5f7OBBVnq6cZIaC8Ti4hb6dtCA==", "license": "MIT", "dependencies": { "archiver-utils": "^5.0.0", @@ -10642,8 +9933,6 @@ }, "node_modules/zip-stream/node_modules/readable-stream": { "version": "4.7.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.7.0.tgz", - "integrity": "sha512-oIGGmcpTLwPga8Bn6/Z75SVaH1z5dUut2ibSyAMVhmUggWpmDn2dapB0n7f8nwaSiRtepAsfJyfXIO5DCVAODg==", "license": "MIT", "dependencies": { "abort-controller": "^3.0.0", @@ -10658,8 +9947,6 @@ }, "node_modules/zip-stream/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==", "funding": [ { "type": "github", @@ -10678,8 +9965,6 @@ }, "node_modules/zip-stream/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==", "license": "MIT", "dependencies": { "safe-buffer": "~5.2.0" @@ -10704,10 +9989,10 @@ }, "packages/code-analyzer-apexguru-engine": { "name": "@salesforce/code-analyzer-apexguru-engine", - "version": "0.42.0", + "version": "0.43.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@salesforce/core": "^8.31.2", "archiver": "^7.0.1", "form-data": "^4.0.6" @@ -10730,8 +10015,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -10754,8 +10037,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -10767,8 +10048,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -10778,8 +10057,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -10838,8 +10115,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/eslint-scope": { "version": "8.4.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", - "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -10855,8 +10130,6 @@ }, "packages/code-analyzer-apexguru-engine/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": { @@ -10868,8 +10141,6 @@ }, "packages/code-analyzer-apexguru-engine/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": { @@ -10886,8 +10157,6 @@ }, "packages/code-analyzer-apexguru-engine/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": { @@ -10896,8 +10165,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/file-entry-cache": { "version": "8.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", - "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", "dev": true, "license": "MIT", "dependencies": { @@ -10909,8 +10176,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/flat-cache": { "version": "4.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", - "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", "dev": true, "license": "MIT", "dependencies": { @@ -10923,8 +10188,6 @@ }, "packages/code-analyzer-apexguru-engine/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", "engines": { @@ -10936,8 +10199,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -10946,8 +10207,6 @@ }, "packages/code-analyzer-apexguru-engine/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -10959,10 +10218,10 @@ }, "packages/code-analyzer-core": { "name": "@salesforce/code-analyzer-core", - "version": "0.52.0", + "version": "0.53.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0", "csv-stringify": "^6.8.1", "isbinaryfile": "^5.0.7", @@ -10990,8 +10249,6 @@ }, "packages/code-analyzer-core/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -11014,8 +10271,6 @@ }, "packages/code-analyzer-core/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -11027,8 +10282,6 @@ }, "packages/code-analyzer-core/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -11038,8 +10291,6 @@ }, "packages/code-analyzer-core/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -11113,8 +10364,6 @@ }, "packages/code-analyzer-core/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": { @@ -11126,8 +10375,6 @@ }, "packages/code-analyzer-core/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": { @@ -11175,8 +10422,6 @@ }, "packages/code-analyzer-core/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", "engines": { @@ -11188,8 +10433,6 @@ }, "packages/code-analyzer-core/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -11198,8 +10441,6 @@ }, "packages/code-analyzer-core/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -11211,7 +10452,7 @@ }, "packages/code-analyzer-engine-api": { "name": "@salesforce/code-analyzer-engine-api", - "version": "0.41.0", + "version": "0.42.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { "@types/node": "^20.0.0", @@ -11233,8 +10474,6 @@ }, "packages/code-analyzer-engine-api/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -11257,15 +10496,11 @@ }, "packages/code-analyzer-engine-api/node_modules/@eslint/eslintrc/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" }, "packages/code-analyzer-engine-api/node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -11275,8 +10510,6 @@ }, "packages/code-analyzer-engine-api/node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -11288,8 +10521,6 @@ }, "packages/code-analyzer-engine-api/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -11301,8 +10532,6 @@ }, "packages/code-analyzer-engine-api/node_modules/balanced-match": { "version": "4.0.4", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", - "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", "license": "MIT", "engines": { "node": "18 || 20 || >=22" @@ -11310,8 +10539,6 @@ }, "packages/code-analyzer-engine-api/node_modules/brace-expansion": { "version": "5.0.5", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz", - "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==", "license": "MIT", "dependencies": { "balanced-match": "^4.0.2" @@ -11322,8 +10549,6 @@ }, "packages/code-analyzer-engine-api/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -11397,8 +10622,6 @@ }, "packages/code-analyzer-engine-api/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": { @@ -11410,15 +10633,11 @@ }, "packages/code-analyzer-engine-api/node_modules/eslint/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" }, "packages/code-analyzer-engine-api/node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "dev": true, "license": "MIT", "dependencies": { @@ -11428,8 +10647,6 @@ }, "packages/code-analyzer-engine-api/node_modules/eslint/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -11441,8 +10658,6 @@ }, "packages/code-analyzer-engine-api/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": { @@ -11490,8 +10705,6 @@ }, "packages/code-analyzer-engine-api/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", "engines": { @@ -11503,8 +10716,6 @@ }, "packages/code-analyzer-engine-api/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -11513,8 +10724,6 @@ }, "packages/code-analyzer-engine-api/node_modules/minimatch": { "version": "10.2.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", - "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "license": "BlueOak-1.0.0", "dependencies": { "brace-expansion": "^5.0.5" @@ -11528,7 +10737,7 @@ }, "packages/code-analyzer-eslint-engine": { "name": "@salesforce/code-analyzer-eslint-engine", - "version": "0.46.0", + "version": "0.47.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { "@babel/preset-react": "^7.29.7", @@ -11536,8 +10745,8 @@ "@lwc/eslint-plugin-lwc": "^3.5.0", "@lwc/eslint-plugin-lwc-platform": "^6.3.0", "@salesforce-ux/eslint-plugin-slds": "^1.2.1", - "@salesforce/code-analyzer-engine-api": "0.41.0", - "@salesforce/code-analyzer-eslint8-engine": "0.18.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", + "@salesforce/code-analyzer-eslint8-engine": "0.19.0-SNAPSHOT", "@salesforce/eslint-config-lwc": "^4.1.2", "@salesforce/eslint-plugin-lightning": "^2.0.0", "@types/node": "^20.0.0", @@ -11628,8 +10837,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "license": "MIT", "dependencies": { "ajv": "^6.14.0", @@ -11651,8 +10858,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -11661,8 +10866,6 @@ }, "packages/code-analyzer-eslint-engine/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==", "license": "MIT", "engines": { "node": ">=18" @@ -11673,8 +10876,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/@eslint/eslintrc/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -11685,8 +10886,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11697,8 +10896,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/@lwc/eslint-plugin-lwc": { "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@lwc/eslint-plugin-lwc/-/eslint-plugin-lwc-3.5.0.tgz", - "integrity": "sha512-Xq4i0ZWhBp1ZbGXqv8KEUqAOzo07BCD3yFD/EdOPafMjpXkeH5RpCFn09+sXVe1vdqtm47JwX+OUDXOMWfIsQg==", "license": "MIT", "dependencies": { "fast-xml-parser": "^5.3.6", @@ -11791,8 +10988,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", @@ -11864,8 +11059,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/eslint/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==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -11884,8 +11077,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/eslint/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -11896,8 +11087,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/espree": { "version": "10.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz", - "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==", "license": "BSD-2-Clause", "dependencies": { "acorn": "^8.15.0", @@ -11913,8 +11102,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/espree/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==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -11932,8 +11119,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/fast-xml-parser": { "version": "5.9.3", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-5.9.3.tgz", - "integrity": "sha512-brCNCeScma/kqa54J4PIDriSSSLssRkuYaUCpvHJulGc3HGI/xxKUCTDcYkAdqJsyb//ydpbxecjC3hB9+tb/g==", "funding": [ { "type": "github", @@ -11976,8 +11161,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -11985,8 +11168,6 @@ }, "packages/code-analyzer-eslint-engine/node_modules/strnum": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-2.4.1.tgz", - "integrity": "sha512-M9eUSMT2dCB2cTNPG7UYj6KuK7RJR2SN2+yCV/fTW3xzTCS6EaGZ5pSMgDIjB7r8zSfTGk+dvvn9rTjpVS9Mwg==", "funding": [ { "type": "github", @@ -12000,7 +11181,7 @@ }, "packages/code-analyzer-eslint8-engine": { "name": "@salesforce/code-analyzer-eslint8-engine", - "version": "0.18.0", + "version": "0.19.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { "@babel/core": "7.27.4", @@ -12008,7 +11189,7 @@ "@eslint/js": "8.57.1", "@lwc/eslint-plugin-lwc": "2.2.0", "@lwc/eslint-plugin-lwc-platform": "5.2.0", - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@salesforce/eslint-config-lwc": "3.7.2", "@salesforce/eslint-plugin-lightning": "1.0.1", "@types/node": "^20.0.0", @@ -12036,8 +11217,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@babel/core": { "version": "7.27.4", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.27.4.tgz", - "integrity": "sha512-bXYxrXFubeYdvB0NhD/NBB3Qi6aZeV20GOWVI47t2dkecCEoneR4NPVcb7abpXDEvejgrUfFtG6vG/zxAKmg+g==", "license": "MIT", "dependencies": { "@ampproject/remapping": "^2.2.0", @@ -12066,8 +11245,6 @@ }, "packages/code-analyzer-eslint8-engine/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==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12075,8 +11252,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@babel/eslint-parser": { "version": "7.27.5", - "resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.27.5.tgz", - "integrity": "sha512-HLkYQfRICudzcOtjGwkPvGc5nF1b4ljLZh1IRDj50lRZ718NAKVgQpIAUX8bfg6u/yuSKY3L7E0YzIV+OxrB8Q==", "license": "MIT", "dependencies": { "@nicolo-ribaudo/eslint-scope-5-internals": "5.1.1-v1", @@ -12093,8 +11268,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@babel/eslint-parser/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12180,8 +11353,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/eslint-plugin": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.30.1.tgz", - "integrity": "sha512-v+VWphxMjn+1t48/jO4t950D6KR8JaJuNXzi33Ve6P8sEmPr5k6CEXjdGwT6+LodVnEa91EQCtwjWNUCPweo+Q==", "license": "MIT", "dependencies": { "@eslint-community/regexpp": "^4.10.0", @@ -12209,8 +11380,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/type-utils": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.30.1.tgz", - "integrity": "sha512-64uBF76bfQiJyHgZISC7vcNz3adqQKIccVoKubyQcOnNcdJBvYOILV1v22Qhsw3tw3VQu5ll8ND6hycgAR5fEA==", "license": "MIT", "dependencies": { "@typescript-eslint/typescript-estree": "8.30.1", @@ -12232,8 +11401,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/eslint-plugin/node_modules/@typescript-eslint/utils": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz", - "integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -12255,8 +11422,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/parser": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.30.1.tgz", - "integrity": "sha512-H+vqmWwT5xoNrXqWs/fesmssOW70gxFlgcMlYcBaWNPIEWDgLa4W9nkSPmhuOgLnXq9QYgkZ31fhDyLhleCsAg==", "license": "MIT", "dependencies": { "@typescript-eslint/scope-manager": "8.30.1", @@ -12279,8 +11444,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/scope-manager": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.30.1.tgz", - "integrity": "sha512-+C0B6ChFXZkuaNDl73FJxRYT0G7ufVPOSQkqkpM/U198wUwUFOtgo1k/QzFh1KjpBitaK7R1tgjVz6o9HmsRPg==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.30.1", @@ -12296,8 +11459,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/types": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.30.1.tgz", - "integrity": "sha512-81KawPfkuulyWo5QdyG/LOKbspyyiW+p4vpn4bYO7DM/hZImlVnFwrpCTnmNMOt8CvLRr5ojI9nU1Ekpw4RcEw==", "license": "MIT", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -12309,8 +11470,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/typescript-estree": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.30.1.tgz", - "integrity": "sha512-kQQnxymiUy9tTb1F2uep9W6aBiYODgq5EMSk6Nxh4Z+BDUoYUSa029ISs5zTzKBFnexQEh71KqwjKnRz58lusQ==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.30.1", @@ -12335,8 +11494,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/visitor-keys": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.30.1.tgz", - "integrity": "sha512-aEhgas7aJ6vZnNFC7K4/vMGDGyOiqWcYZPpIWrTKuTAlsvDNKy2GFDqh9smL+iq069ZvR0YzEeq0B8NJlLzjFA==", "license": "MIT", "dependencies": { "@typescript-eslint/types": "8.30.1", @@ -12352,8 +11509,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/@typescript-eslint/visitor-keys/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==", "license": "Apache-2.0", "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -12364,8 +11519,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/brace-expansion": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz", - "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -12374,8 +11527,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/doctrine": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" @@ -12386,8 +11537,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/eslint-plugin-import": { "version": "2.30.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.30.0.tgz", - "integrity": "sha512-/mHNE9jINJfiD2EKkg1BKyPyUk4zdnT54YgbOgfjSakWT5oyX/qQLVNTkehyfpcMxZXMy1zyonZ2v7hZTX43Yw==", "license": "MIT", "dependencies": { "@rtsao/scc": "^1.1.0", @@ -12418,8 +11567,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/eslint-plugin-import/node_modules/debug": { "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "license": "MIT", "dependencies": { "ms": "^2.1.1" @@ -12427,8 +11574,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/eslint-plugin-import/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -12439,8 +11584,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/eslint-plugin-import/node_modules/semver": { "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -12471,8 +11614,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "license": "MIT", "engines": { "node": ">= 4" @@ -12480,8 +11621,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/typescript": { "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -12493,8 +11632,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/typescript-eslint": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.30.1.tgz", - "integrity": "sha512-D7lC0kcehVH7Mb26MRQi64LMyRJsj3dToJxM1+JVTl53DQSV5/7oUGWQLcKl1C1KnoVHxMMU2FNQMffr7F3Row==", "license": "MIT", "dependencies": { "@typescript-eslint/eslint-plugin": "8.30.1", @@ -12515,8 +11652,6 @@ }, "packages/code-analyzer-eslint8-engine/node_modules/typescript-eslint/node_modules/@typescript-eslint/utils": { "version": "8.30.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.30.1.tgz", - "integrity": "sha512-T/8q4R9En2tcEsWPQgB5BQ0XJVOtfARcUvOa8yJP3fh9M/mXraLxZrkCfGb6ChrO/V3W+Xbd04RacUEqk1CFEQ==", "license": "MIT", "dependencies": { "@eslint-community/eslint-utils": "^4.4.0", @@ -12538,10 +11673,10 @@ }, "packages/code-analyzer-flow-engine": { "name": "@salesforce/code-analyzer-flow-engine", - "version": "0.40.0", + "version": "0.41.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0", "@types/semver": "^7.7.1", "semver": "^7.8.5" @@ -12562,8 +11697,6 @@ }, "packages/code-analyzer-flow-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -12586,8 +11719,6 @@ }, "packages/code-analyzer-flow-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -12599,8 +11730,6 @@ }, "packages/code-analyzer-flow-engine/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -12610,8 +11739,6 @@ }, "packages/code-analyzer-flow-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -12685,8 +11812,6 @@ }, "packages/code-analyzer-flow-engine/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": { @@ -12698,8 +11823,6 @@ }, "packages/code-analyzer-flow-engine/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": { @@ -12747,8 +11870,6 @@ }, "packages/code-analyzer-flow-engine/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", "engines": { @@ -12760,8 +11881,6 @@ }, "packages/code-analyzer-flow-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -12770,8 +11889,6 @@ }, "packages/code-analyzer-flow-engine/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -12783,10 +11900,10 @@ }, "packages/code-analyzer-pmd-engine": { "name": "@salesforce/code-analyzer-pmd-engine", - "version": "0.45.0", + "version": "0.46.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0", "@types/semver": "^7.7.1", "semver": "^7.8.5" @@ -12807,8 +11924,6 @@ }, "packages/code-analyzer-pmd-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -12831,8 +11946,6 @@ }, "packages/code-analyzer-pmd-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -12844,8 +11957,6 @@ }, "packages/code-analyzer-pmd-engine/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -12855,8 +11966,6 @@ }, "packages/code-analyzer-pmd-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -12930,8 +12039,6 @@ }, "packages/code-analyzer-pmd-engine/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": { @@ -12943,8 +12050,6 @@ }, "packages/code-analyzer-pmd-engine/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": { @@ -12992,8 +12097,6 @@ }, "packages/code-analyzer-pmd-engine/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", "engines": { @@ -13005,8 +12108,6 @@ }, "packages/code-analyzer-pmd-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -13015,8 +12116,6 @@ }, "packages/code-analyzer-pmd-engine/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -13028,10 +12127,10 @@ }, "packages/code-analyzer-regex-engine": { "name": "@salesforce/code-analyzer-regex-engine", - "version": "0.39.0", + "version": "0.40.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0", "isbinaryfile": "^5.0.7", "p-limit": "^3.1.0" @@ -13052,8 +12151,6 @@ }, "packages/code-analyzer-regex-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -13076,8 +12173,6 @@ }, "packages/code-analyzer-regex-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -13089,8 +12184,6 @@ }, "packages/code-analyzer-regex-engine/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -13100,8 +12193,6 @@ }, "packages/code-analyzer-regex-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -13175,8 +12266,6 @@ }, "packages/code-analyzer-regex-engine/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": { @@ -13188,8 +12277,6 @@ }, "packages/code-analyzer-regex-engine/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": { @@ -13237,8 +12324,6 @@ }, "packages/code-analyzer-regex-engine/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", "engines": { @@ -13250,8 +12335,6 @@ }, "packages/code-analyzer-regex-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -13260,8 +12343,6 @@ }, "packages/code-analyzer-regex-engine/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -13273,10 +12354,10 @@ }, "packages/code-analyzer-retirejs-engine": { "name": "@salesforce/code-analyzer-retirejs-engine", - "version": "0.38.0", + "version": "0.39.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0", "isbinaryfile": "^5.0.7", "node-stream-zip": "^1.15.0", @@ -13298,8 +12379,6 @@ }, "packages/code-analyzer-retirejs-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -13322,8 +12401,6 @@ }, "packages/code-analyzer-retirejs-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -13335,8 +12412,6 @@ }, "packages/code-analyzer-retirejs-engine/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -13346,8 +12421,6 @@ }, "packages/code-analyzer-retirejs-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -13421,8 +12494,6 @@ }, "packages/code-analyzer-retirejs-engine/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": { @@ -13434,8 +12505,6 @@ }, "packages/code-analyzer-retirejs-engine/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": { @@ -13483,8 +12552,6 @@ }, "packages/code-analyzer-retirejs-engine/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", "engines": { @@ -13496,8 +12563,6 @@ }, "packages/code-analyzer-retirejs-engine/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -13506,8 +12571,6 @@ }, "packages/code-analyzer-retirejs-engine/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -13519,10 +12582,10 @@ }, "packages/code-analyzer-sfge-engine": { "name": "@salesforce/code-analyzer-sfge-engine", - "version": "0.24.0", + "version": "0.25.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0", "semver": "^7.8.5" }, @@ -13543,8 +12606,6 @@ }, "packages/code-analyzer-sfge-engine/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -13567,8 +12628,6 @@ }, "packages/code-analyzer-sfge-engine/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -13580,8 +12639,6 @@ }, "packages/code-analyzer-sfge-engine/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -13591,8 +12648,6 @@ }, "packages/code-analyzer-sfge-engine/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -13666,8 +12721,6 @@ }, "packages/code-analyzer-sfge-engine/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": { @@ -13679,8 +12732,6 @@ }, "packages/code-analyzer-sfge-engine/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": { @@ -13727,6 +12778,257 @@ } }, "packages/code-analyzer-sfge-engine/node_modules/globals": { + "version": "14.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "packages/code-analyzer-sfge-engine/node_modules/ignore": { + "version": "5.3.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, + "packages/code-analyzer-sfge-engine/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "packages/code-analyzer-uibundle-engine": { + "name": "@salesforce/code-analyzer-uibundle-engine", + "version": "0.1.0-SNAPSHOT", + "license": "BSD-3-Clause", + "dependencies": { + "@babel/parser": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@jridgewell/trace-mapping": "^0.3.31", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", + "@types/node": "^20.0.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.5", + "@types/babel__traverse": "^7.28.0", + "@types/jest": "^30.0.0", + "eslint": "^9.39.5", + "jest": "^30.4.2", + "rimraf": "^6.1.3", + "ts-jest": "^29.4.11", + "typescript": "^5.9.3", + "typescript-eslint": "^8.64.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/@eslint/eslintrc": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.14.0", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/@eslint/js": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/eslint": { + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@eslint-community/eslint-utils": "^4.8.0", + "@eslint-community/regexpp": "^4.12.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", + "@humanfs/node": "^0.16.6", + "@humanwhocodes/module-importer": "^1.0.1", + "@humanwhocodes/retry": "^0.4.2", + "@types/estree": "^1.0.6", + "ajv": "^6.14.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.6", + "debug": "^4.3.2", + "escape-string-regexp": "^4.0.0", + "eslint-scope": "^8.4.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", + "esquery": "^1.5.0", + "esutils": "^2.0.2", + "fast-deep-equal": "^3.1.3", + "file-entry-cache": "^8.0.0", + "find-up": "^5.0.0", + "glob-parent": "^6.0.2", + "ignore": "^5.2.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "lodash.merge": "^4.6.2", + "minimatch": "^3.1.5", + "natural-compare": "^1.4.0", + "optionator": "^0.9.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://eslint.org/donate" + }, + "peerDependencies": { + "jiti": "*" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + } + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/eslint-scope": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", + "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/code-analyzer-uibundle-engine/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.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/code-analyzer-uibundle-engine/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.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "packages/code-analyzer-uibundle-engine/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" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/file-entry-cache": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz", + "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "flat-cache": "^4.0.0" + }, + "engines": { + "node": ">=16.0.0" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/flat-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz", + "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==", + "dev": true, + "license": "MIT", + "dependencies": { + "flatted": "^3.2.9", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=16" + } + }, + "packages/code-analyzer-uibundle-engine/node_modules/globals": { "version": "14.0.0", "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", @@ -13739,7 +13041,7 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "packages/code-analyzer-sfge-engine/node_modules/ignore": { + "packages/code-analyzer-uibundle-engine/node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", @@ -13749,7 +13051,7 @@ "node": ">= 4" } }, - "packages/code-analyzer-sfge-engine/node_modules/minimatch": { + "packages/code-analyzer-uibundle-engine/node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", @@ -13767,7 +13069,7 @@ "version": "0.1.0-SNAPSHOT", "license": "BSD-3-Clause", "dependencies": { - "@salesforce/code-analyzer-engine-api": "0.41.0", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", "@types/node": "^20.0.0" }, "devDependencies": { @@ -13786,8 +13088,6 @@ }, "packages/ENGINE-TEMPLATE/node_modules/@eslint/eslintrc": { "version": "3.3.6", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", - "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { @@ -13810,8 +13110,6 @@ }, "packages/ENGINE-TEMPLATE/node_modules/@eslint/js": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", - "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -13823,8 +13121,6 @@ }, "packages/ENGINE-TEMPLATE/node_modules/brace-expansion": { "version": "1.1.16", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.16.tgz", - "integrity": "sha512-IDw48K2/2kRkg9LdJxurvq3lV3aBgq0REY89duEqFRthjlPdXHKMj7EnQOXVckxzgisinf3nHfrcE2FufFLXMw==", "dev": true, "license": "MIT", "dependencies": { @@ -13834,8 +13130,6 @@ }, "packages/ENGINE-TEMPLATE/node_modules/eslint": { "version": "9.39.5", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", - "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", "dependencies": { @@ -13909,8 +13203,6 @@ }, "packages/ENGINE-TEMPLATE/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": { @@ -13922,8 +13214,6 @@ }, "packages/ENGINE-TEMPLATE/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": { @@ -13971,8 +13261,6 @@ }, "packages/ENGINE-TEMPLATE/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", "engines": { @@ -13984,8 +13272,6 @@ }, "packages/ENGINE-TEMPLATE/node_modules/ignore": { "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", "dev": true, "license": "MIT", "engines": { @@ -13994,8 +13280,6 @@ }, "packages/ENGINE-TEMPLATE/node_modules/minimatch": { "version": "3.1.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", - "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { diff --git a/packages/code-analyzer-uibundle-engine/LICENSE b/packages/code-analyzer-uibundle-engine/LICENSE new file mode 100644 index 00000000..1307e4fe --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/LICENSE @@ -0,0 +1,14 @@ +BSD 3-Clause License + +Copyright (c) 2024, Salesforce.com, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +* Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/code-analyzer-uibundle-engine/eslint.config.mjs b/packages/code-analyzer-uibundle-engine/eslint.config.mjs new file mode 100644 index 00000000..44661709 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/eslint.config.mjs @@ -0,0 +1,16 @@ +import eslint from '@eslint/js'; +import tseslint from 'typescript-eslint'; + +export default tseslint.config( + eslint.configs.recommended, + ...tseslint.configs.recommended, + { + rules: { + "@typescript-eslint/no-unused-vars": ["error", { + "argsIgnorePattern": "^_", + "varsIgnorePattern": "^_", + "caughtErrorsIgnorePattern": "^_" + }] + } + } +); diff --git a/packages/code-analyzer-uibundle-engine/package.json b/packages/code-analyzer-uibundle-engine/package.json new file mode 100644 index 00000000..74cee030 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/package.json @@ -0,0 +1,69 @@ +{ + "name": "@salesforce/code-analyzer-uibundle-engine", + "description": "Plugin package that adds the 'uibundle' engine into Salesforce Code Analyzer. Validates UI Bundle build-output integrity — currently ships sourcemap-based verification of each shipped dist/ artifact against its declared sourcemap and the submitted src/ tree.", + "version": "0.1.0-SNAPSHOT", + "author": "The Salesforce Code Analyzer Team", + "license": "BSD-3-Clause", + "homepage": "https://developer.salesforce.com/docs/platform/salesforce-code-analyzer/overview", + "repository": { + "type": "git", + "url": "git+https://github.com/forcedotcom/code-analyzer-core.git", + "directory": "packages/code-analyzer-uibundle-engine" + }, + "main": "dist/index.js", + "types": "dist/index.d.ts", + "dependencies": { + "@babel/parser": "^7.25.0", + "@babel/traverse": "^7.25.0", + "@babel/types": "^7.25.0", + "@jridgewell/sourcemap-codec": "^1.5.5", + "@jridgewell/trace-mapping": "^0.3.31", + "@salesforce/code-analyzer-engine-api": "0.42.0-SNAPSHOT", + "@types/node": "^20.0.0" + }, + "devDependencies": { + "@eslint/js": "^9.39.5", + "@types/babel__traverse": "^7.28.0", + "@types/jest": "^30.0.0", + "eslint": "^9.39.5", + "jest": "^30.4.2", + "rimraf": "^6.1.3", + "ts-jest": "^29.4.11", + "typescript": "^5.9.3", + "typescript-eslint": "^8.64.0" + }, + "engines": { + "node": ">=20.0.0" + }, + "files": [ + "dist", + "LICENSE", + "package.json" + ], + "scripts": { + "build": "tsc --build tsconfig.build.json --verbose", + "test": "tsc --build tsconfig.json && jest --coverage", + "lint": "eslint src/**/*.ts", + "package": "npm pack", + "all": "npm run build && npm run lint && npm run test && npm run package", + "clean": "tsc --build tsconfig.build.json --clean", + "postclean": "rimraf dist && rimraf coverage && rimraf ./*.tgz && rimraf vulnerabilities", + "scrub": "npm run clean && rimraf node_modules", + "showcoverage": "open ./coverage/lcov-report/index.html" + }, + "jest": { + "preset": "ts-jest", + "testEnvironment": "node", + "testMatch": [ + "**/*.test.ts" + ], + "testPathIgnorePatterns": [ + "/node_modules/", + "/dist/" + ], + "collectCoverageFrom": [ + "src/**/*.ts", + "!src/index.ts" + ] + } +} diff --git a/packages/code-analyzer-uibundle-engine/src/engine.ts b/packages/code-analyzer-uibundle-engine/src/engine.ts new file mode 100644 index 00000000..041fa1ca --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/engine.ts @@ -0,0 +1,214 @@ +import path from "node:path"; +import * as fsp from "node:fs/promises"; +import { + Engine, + LogLevel, + type DescribeOptions, + type EngineRunResults, + type RuleDescription, + type RunOptions, + type Violation, +} from "@salesforce/code-analyzer-engine-api"; +import { RULES, RULE_NAMES } from "./rules"; +import { + COVERAGE_ANALYSIS_RULE, + validateCoverageAnalysis, +} from "./validators/coverage-analysis"; +import { + INVALID_SOURCE_REFERENCES_RULE, + validateInvalidSourceReferences, +} from "./validators/invalid-source-references"; +import { + MISSING_SOURCEMAP_RULE, + validateMissingSourcemaps, +} from "./validators/missing-sourcemap"; +import { PATH_LEAKAGE_RULE, validatePathLeakage } from "./validators/path-leakage"; +import { + SOURCE_CONTENT_VERIFICATION_RULE, + validateSourceContent, +} from "./validators/source-content-verification"; +import { + STRUCTURAL_COHERENCE_RULE, + validateStructuralCoherence, +} from "./validators/structural-coherence"; +import { + TOKEN_CONSISTENCY_RULE, + validateTokenConsistency, +} from "./validators/token-consistency"; +import { buildSourceIndex, type SourceIndex } from "./validators/sourcemap-io"; +import type { ValidatorFinding, ValidatorResult } from "./validators/types"; +import { VLQ_INTEGRITY_RULE, validateVlqIntegrity } from "./validators/vlq-integrity"; +import { getMessage } from "./messages"; + +interface BundleTarget { + distPath: string; + sourcePath: string | null; +} + +export class UIBundleEngine extends Engine { + static readonly NAME = "uibundle"; + + getName(): string { + return UIBundleEngine.NAME; + } + + async getEngineVersion(): Promise { + const pathToPackageJson: string = path.join(__dirname, '..', 'package.json'); + const packageJson: {version: string} = JSON.parse(await fsp.readFile(pathToPackageJson, 'utf-8')); + return packageJson.version; + } + + async describeRules(_describeOptions: DescribeOptions): Promise { + return [...RULES]; + } + + async runRules(ruleNames: string[], runOptions: RunOptions): Promise { + const selected: string[] = ruleNames.filter((name) => RULE_NAMES.has(name)); + if (selected.length === 0) return { violations: [] }; + + const targets: BundleTarget[] = await this.findBundleTargets(runOptions); + if (targets.length === 0) { + this.emitLogEvent(LogLevel.Info, getMessage('NoBundleTargetsFound', UIBundleEngine.NAME)); + return { violations: [] }; + } + + const violations: Violation[] = []; + for (const target of targets) { + await this.runOnTarget(target, selected, violations); + } + return { violations }; + } + + private async runOnTarget( + target: BundleTarget, + selected: string[], + violations: Violation[], + ): Promise { + const distOnlyDispatch: [string, () => Promise][] = [ + [MISSING_SOURCEMAP_RULE, () => validateMissingSourcemaps(target.distPath)], + [PATH_LEAKAGE_RULE, () => validatePathLeakage(target.distPath)], + [INVALID_SOURCE_REFERENCES_RULE, () => validateInvalidSourceReferences(target.distPath)], + [VLQ_INTEGRITY_RULE, () => validateVlqIntegrity(target.distPath)], + [COVERAGE_ANALYSIS_RULE, () => validateCoverageAnalysis(target.distPath)], + ]; + + for (const [ruleName, runValidator] of distOnlyDispatch) { + if (!selected.includes(ruleName)) continue; + const result: ValidatorResult = await runValidator(); + this.consumeResult(ruleName, target.distPath, result, violations); + } + + const sourceDispatch: [ + string, + (opts: { + sourcePath: string; + distPath: string; + sourceIndex?: SourceIndex; + }) => Promise, + ][] = [ + [SOURCE_CONTENT_VERIFICATION_RULE, validateSourceContent], + [STRUCTURAL_COHERENCE_RULE, validateStructuralCoherence], + [TOKEN_CONSISTENCY_RULE, validateTokenConsistency], + ]; + + const activeSourceRules = sourceDispatch.filter(([r]) => selected.includes(r)); + if (activeSourceRules.length === 0) return; + + if (!target.sourcePath) { + for (const [ruleName] of activeSourceRules) { + this.emitLogEvent( + LogLevel.Warn, + getMessage('SkippedNoSourceTree', UIBundleEngine.NAME, ruleName, target.distPath), + ); + } + return; + } + + const sourceIndex: SourceIndex = await buildSourceIndex(target.sourcePath); + + for (const [ruleName, runValidator] of activeSourceRules) { + const result: ValidatorResult = await runValidator({ + sourcePath: target.sourcePath, + distPath: target.distPath, + sourceIndex, + }); + this.consumeResult(ruleName, target.distPath, result, violations); + } + } + + private consumeResult( + ruleName: string, + distPath: string, + result: ValidatorResult, + violations: Violation[], + ): void { + if (result.skipped) { + this.emitLogEvent( + LogLevel.Warn, + getMessage('SkippedForTarget', UIBundleEngine.NAME, ruleName, distPath, result.skipped.reason), + ); + return; + } + for (const finding of result.findings) { + violations.push(toViolation(finding)); + } + } + + private async findBundleTargets(runOptions: RunOptions): Promise { + const targetedFiles: string[] = await runOptions.workspace.getTargetedFiles(); + + const bundleRoots: Set = new Set(); + for (const file of targetedFiles) { + const base = path.basename(file); + if (base === "ui-bundle.json" || base.endsWith(".uibundle-meta.xml")) { + bundleRoots.add(path.dirname(file)); + } + } + + for (const file of targetedFiles) { + const dist = findAncestorNamed(file, "dist"); + if (dist) bundleRoots.add(path.dirname(dist)); + } + + const targets: BundleTarget[] = []; + for (const bundleRoot of bundleRoots) { + const distPath = path.join(bundleRoot, "dist"); + if (!(await isDirectory(distPath))) continue; + + const srcPath = path.join(bundleRoot, "src"); + const sourcePath = (await isDirectory(srcPath)) ? srcPath : null; + + targets.push({ distPath, sourcePath }); + } + return targets; + } +} + +function toViolation(finding: ValidatorFinding): Violation { + // SFCA requires 1-based line/column; validators emit 1-based coordinates. + const startLine: number = Math.max(1, finding.startLine ?? 1); + const rawCol: number | undefined = finding.startColumn; + const startColumn: number = rawCol == null ? 1 : Math.max(1, rawCol); + return { + ruleName: finding.ruleName, + message: finding.message, + primaryLocationIndex: 0, + codeLocations: [{ file: finding.file, startLine, startColumn }], + }; +} + +async function isDirectory(p: string): Promise { + try { + const stat = await fsp.stat(p); + return stat.isDirectory(); + } catch { + return false; + } +} + +function findAncestorNamed(filePath: string, name: string): string | null { + const parts = filePath.split(path.sep); + const lastNameSegmentIdx = parts.lastIndexOf(name); + if (lastNameSegmentIdx <= 0) return null; + return parts.slice(0, lastNameSegmentIdx + 1).join(path.sep); +} diff --git a/packages/code-analyzer-uibundle-engine/src/index.ts b/packages/code-analyzer-uibundle-engine/src/index.ts new file mode 100644 index 00000000..4a212fae --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/index.ts @@ -0,0 +1,8 @@ +import { EnginePlugin } from "@salesforce/code-analyzer-engine-api"; +import { UIBundleEnginePlugin } from "./plugin"; + +function createEnginePlugin(): EnginePlugin { + return new UIBundleEnginePlugin(); +} + +export { createEnginePlugin, UIBundleEnginePlugin }; diff --git a/packages/code-analyzer-uibundle-engine/src/messages.ts b/packages/code-analyzer-uibundle-engine/src/messages.ts new file mode 100644 index 00000000..49bc2207 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/messages.ts @@ -0,0 +1,142 @@ +import {getMessageFromCatalog} from "@salesforce/code-analyzer-engine-api"; + +const MESSAGE_CATALOG : { [key: string]: string } = { + UnsupportedEngineName: + `The UIBundleEnginePlugin doesn't support an engine with name '%s'.`, + + NoBundleTargetsFound: + `[%s] No UI Bundle dist/ directories found. Run 'npm run build' in each UI Bundle before code analysis.`, + + SkippedForTarget: + `[%s] %s skipped for %s: %s`, + + SkippedNoSourceTree: + `[%s] Skipping %s for %s: could not locate a source directory sibling to dist/.`, + + MissingSourcemapRuleDescription: + `Every compiled .js file in the build output must have a corresponding sourcemap (co-located .js.map or //# sourceMappingURL). Missing sourcemaps prevent source-to-compiled verification during security review.`, + + PathLeakageRuleDescription: + `Sourcemap sources[] entries must be relative paths. Absolute paths leak developer environment details (usernames, filesystem layout) into shipped artifacts.`, + + InvalidSourceReferencesRuleDescription: + `Every file referenced by a sourcemap sources[] entry (that doesn't have inline sourcesContent) must exist on disk. Missing files indicate tampering or an incomplete submission.`, + + VlqIntegrityRuleDescription: + `Sourcemap "mappings" field must be valid Base64 VLQ and reference in-range source/name indices. Malformed mappings signal a fabricated or corrupted sourcemap.`, + + SourceContentVerificationRuleDescription: + `AST-based verification that the compiled JS actually traces back to the submitted source. Parses compiled output with @babel/parser, collects significant AST nodes, and checks each has a sourcemap mapping into a source file present on disk. Also enforces byte-equal sourcesContent, a virtual-source ratio cap, an AST type-mismatch threshold, and flags dangerous API patterns in unmapped regions.`, + + CoverageAnalysisRuleDescription: + `Character-level coverage analysis (informational). Flags per-line unmapped regions of 50+ chars and raises a cumulative finding when more than 2% of the compiled file (line-1 preamble discounted up to 150 chars) has no sourcemap coverage.`, + + StructuralCoherenceRuleDescription: + `Structural coherence checks on sourcemap tokens (informational). Flags out-of-bounds mappings, sample-based whitespace/comment-only mappings above 80%, and cross-file jump ratios above 50% on consecutive same-line tokens.`, + + TokenConsistencyRuleDescription: + `Token-type consistency checks on sampled sourcemap tokens (informational). Every 20th mapping is compared between compiled and source positions; verifies names[] entries exist near the claimed source position (±3 col tolerance); flags scores below 85% (warning) and below 70% (suspicious).`, + + MissingSourcemapForFile: + `No sourcemap found for %s. Expected a co-located .js.map or a //# sourceMappingURL comment.`, + + OrphanJsWithDangerousApi: + `Orphan JS file (no sourcemap) contains dangerous API pattern(s): %s. This looks like unmapped/injected code rather than a bundler runtime.`, + + PathLeakageFinding: + `Sourcemap references an absolute local path: "%s". Sources should be relative to protect developer environment details.`, + + SourceFileDoesNotExist: + `Sourcemap references a source file that doesn't exist on disk: "%s" (resolved to %s).`, + + SourcemapNotValidJson: + `Sourcemap is not valid JSON: %s`, + + SourcemapMissingMappings: + `Sourcemap is missing a string "mappings" field.`, + + SourcemapMissingSourcesArray: + `Sourcemap is missing a "sources" array.`, + + VlqDecodingFailed: + `Sourcemap "mappings" field failed VLQ decoding: %s`, + + SegmentSourceIndexOutOfRange: + `Sourcemap segment at line %d, segment %d references source index %d but sources length is %d.`, + + SegmentNameIndexOutOfRange: + `Sourcemap segment at line %d, segment %d references name index %d but names length is %d.`, + + SourceContentSourcemapNotJson: + `Sourcemap is not valid JSON: %s`, + + SourceContentSourcemapUnloadable: + `Sourcemap could not be loaded for AST verification: %s`, + + SourceContentReferencesUnknownSource: + `Sourcemap references source "%s" (normalized "%s") which is not present in the submitted source tree.`, + + SourceContentMissingInline: + `Sourcemap source "%s" is missing inline sourcesContent — required for byte-equal verification against the submitted source.`, + + SourceContentBytewiseMismatch: + `Sourcemap sourcesContent for "%s" differs from the submitted source file (byte-equal check).`, + + SourceContentExcessiveVirtualSources: + `Excessive virtual sources: %s%% of %d sources are virtual (webpack/vite/unknown). Threshold is %d%%; potential Layer-1 bypass attempt.`, + + SourceContentCompiledParseFailed: + `Compiled JS failed to parse for AST verification: %s`, + + SourceContentCoverageBelowThreshold: + `Sourcemap coverage %s%% is below threshold %d%% (%d/%d significant AST nodes mapped). Compiled JS may include code not present in submitted source.`, + + SourceContentUnmappedNode: + `Unmapped %s at %d:%d — "%s"`, + + SourceContentTypeMismatchRatio: + `AST type-mismatch ratio %s%% meets or exceeds %s%% threshold (%d/%d mapped nodes have incompatible source AST types). Mappings may be fabricated.`, + + SourceContentTypeMismatchDetail: + `Type mismatch: %s`, + + SourceContentDangerousUnmapped: + `Unmapped %s at %d:%d contains a dangerous API pattern: "%s"`, + + SourceContentOrphanSources: + `%d mapped AST node source(s) not present in the submitted source tree: %s`, + + CoverageUnmappedRegion: + `Unmapped region on line %d cols %d..%d (%d chars) — no sourcemap coverage.`, + + CoverageExcessiveCumulative: + `Excessive cumulative unmapped content: %s%% of %d chars are unmapped (line-1 preamble discounted). Threshold is %s%%.`, + + CoherenceBoundsSummary: + `%d sourcemap mapping(s) point out of bounds of the referenced source file.`, + + CoherenceBoundsDetail: + `Out-of-bounds: "%s" claimed line %d:%d but file has %d line(s).`, + + CoherenceWhitespaceSuspicious: + `%s%% of sampled mappings point to whitespace or comments (%d/%d). Threshold is %s%%; sourcemap tokens may be fabricated to satisfy coverage without pointing at real code.`, + + CoherenceCrossFileJumpsSuspicious: + `Cross-file jump ratio %s exceeds %s: majority of consecutive tokens on the same generated line jump between source files, which is unusual for real bundler output.`, + + TokenConsistencySuspicious: + `Token type consistency %s%% is below suspicious threshold %s%% (%d/%d sampled tokens agree between compiled and source positions). Sourcemap tokens appear fabricated.`, + + TokenConsistencyBelowWarning: + `Token type consistency %s%% is below expected threshold %s%% (%d/%d sampled tokens agree between compiled and source positions).`, + + TokenNameMismatchSummary: + `%d sourcemap name(s) don't exist at the claimed source position (±%d col tolerance).`, + + TokenNameMismatchDetail: + `Name mismatch: expected "%s" at %s:%d:%d, found "%s".` +}; + +export function getMessage(msgId: string, ...args: (string | number)[]): string { + return getMessageFromCatalog(MESSAGE_CATALOG, msgId, ...args); +} diff --git a/packages/code-analyzer-uibundle-engine/src/plugin.ts b/packages/code-analyzer-uibundle-engine/src/plugin.ts new file mode 100644 index 00000000..dfd6caf4 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/plugin.ts @@ -0,0 +1,20 @@ +import { + ConfigObject, + Engine, + EnginePluginV1, +} from "@salesforce/code-analyzer-engine-api"; +import { getMessage } from "./messages"; +import { UIBundleEngine } from "./engine"; + +export class UIBundleEnginePlugin extends EnginePluginV1 { + getAvailableEngineNames(): string[] { + return [UIBundleEngine.NAME]; + } + + async createEngine(engineName: string, _resolvedConfig: ConfigObject): Promise { + if (engineName !== UIBundleEngine.NAME) { + throw new Error(getMessage('UnsupportedEngineName', engineName)); + } + return new UIBundleEngine(); + } +} diff --git a/packages/code-analyzer-uibundle-engine/src/rules.ts b/packages/code-analyzer-uibundle-engine/src/rules.ts new file mode 100644 index 00000000..f6806132 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/rules.ts @@ -0,0 +1,86 @@ +import { + SeverityLevel, + type RuleDescription, +} from "@salesforce/code-analyzer-engine-api"; +import { getMessage } from "./messages"; + +const UIBUNDLE_INTEGRITY_TAG = "UIBundleIntegrity"; + +export const RULES: RuleDescription[] = [ + { + name: "missing-sourcemap", + severityLevel: SeverityLevel.High, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('MissingSourcemapRuleDescription'), + resourceUrls: [ + "https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map", + ], + }, + { + name: "path-leakage", + severityLevel: SeverityLevel.Moderate, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('PathLeakageRuleDescription'), + resourceUrls: [], + }, + { + name: "invalid-source-references", + severityLevel: SeverityLevel.High, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('InvalidSourceReferencesRuleDescription'), + resourceUrls: [], + }, + { + name: "vlq-integrity", + severityLevel: SeverityLevel.High, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('VlqIntegrityRuleDescription'), + resourceUrls: ["https://tc39.es/ecma426/#sec-mapping-groups"], + }, + { + name: "source-content-verification", + severityLevel: SeverityLevel.High, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('SourceContentVerificationRuleDescription'), + resourceUrls: ["https://tc39.es/source-map/"], + }, + { + name: "coverage-analysis", + severityLevel: SeverityLevel.Info, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('CoverageAnalysisRuleDescription'), + resourceUrls: [], + }, + { + name: "structural-coherence", + severityLevel: SeverityLevel.Info, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('StructuralCoherenceRuleDescription'), + resourceUrls: [], + }, + { + name: "token-consistency", + severityLevel: SeverityLevel.Info, + tags: [ + UIBUNDLE_INTEGRITY_TAG, + ], + description: getMessage('TokenConsistencyRuleDescription'), + resourceUrls: [], + }, +]; + +export const RULE_NAMES: Set = new Set(RULES.map((r) => r.name)); diff --git a/packages/code-analyzer-uibundle-engine/src/validators/classification.ts b/packages/code-analyzer-uibundle-engine/src/validators/classification.ts new file mode 100644 index 00000000..7afe5b01 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/classification.ts @@ -0,0 +1,88 @@ +export function toPosixPath(p: string): string { + return p.replace(/\\/g, "/"); +} + +export function normalizeLineEndings(s: string): string { + return s.replace(/\r\n?/g, "\n"); +} + +export function normalizeSourcePath(p: string): string { + let s = p; + while (s.startsWith("../")) s = s.slice(3); + while (s.startsWith("./")) s = s.slice(2); + while (s.startsWith("/")) s = s.slice(1); + if (s.startsWith("webpack:///")) s = s.slice("webpack:///".length); + else if (s.startsWith("webpack://")) s = s.slice("webpack://".length); + if (s.startsWith("/src/")) s = s.slice("/src/".length); + return s; +} + +export function isVirtualSource(p: string): boolean { + return ( + p.includes("\0") || + p.startsWith("webpack/") || + p.startsWith("<") || + p.includes("?") || + p.startsWith("__vite") || + p.startsWith("vite/") || + p === "unknown" + ); +} + +export function isDependency(p: string): boolean { + return p.startsWith("node_modules/") || p.includes("/node_modules/"); +} + +export function isAsset(p: string): boolean { + return ASSET_EXTENSIONS.some((ext) => p.endsWith(ext)); +} + +const ASSET_EXTENSIONS = [ + ".png", + ".jpg", + ".jpeg", + ".gif", + ".svg", + ".ico", + ".webp", + ".woff", + ".woff2", + ".ttf", + ".eot", + ".otf", + ".mp3", + ".mp4", + ".wav", + ".ogg", + ".webm", +]; + +export const DANGEROUS_API_PATTERNS: readonly string[] = Object.freeze([ + "document.cookie", + "localStorage", + "sessionStorage", + "XMLHttpRequest", + "navigator.sendBeacon", + "importScripts", + "ServiceWorker", + ["ev", "al", "("].join(""), + ["Fu", "nction", "("].join(""), + "crypto.subtle", +]); + +export const DANGEROUS_AST_EXTRA_PATTERNS: readonly string[] = Object.freeze([ + "fetch(", + '.createElement("script")', + ".createElement(`script`)", +]); + +export function containsDangerousApi(content: string): boolean { + return DANGEROUS_API_PATTERNS.some((p) => content.includes(p)); +} + +export function containsDangerousPattern(snippet: string): boolean { + return ( + DANGEROUS_API_PATTERNS.some((p) => snippet.includes(p)) || + DANGEROUS_AST_EXTRA_PATTERNS.some((p) => snippet.includes(p)) + ); +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/coverage-analysis.ts b/packages/code-analyzer-uibundle-engine/src/validators/coverage-analysis.ts new file mode 100644 index 00000000..f3d6a88a --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/coverage-analysis.ts @@ -0,0 +1,192 @@ +import { promises as fs } from "node:fs"; +import { TraceMap, eachMapping } from "@jridgewell/trace-mapping"; +import { walk } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const COVERAGE_ANALYSIS_RULE = "coverage-analysis"; + +const UNMAPPED_THRESHOLD = 50; +const EXCESSIVE_UNMAPPED_PCT = 2.0; +const LINE1_EXEMPT_CHARS = 150; + +interface UnmappedRegion { + line: number; + startCol: number; + endCol: number; + length: number; +} + +export async function validateCoverageAnalysis(distPath: string): Promise { + let distStat; + try { + distStat = await fs.stat(distPath); + } catch { + return { findings: [], skipped: { reason: `dist path not found: ${distPath}` } }; + } + if (!distStat.isDirectory()) { + return { findings: [], skipped: { reason: `dist path is not a directory: ${distPath}` } }; + } + + const findings: ValidatorFinding[] = []; + + await walk(distPath, async (jsPath) => { + if (!jsPath.endsWith(".js")) return; + const mapPath = `${jsPath}.map`; + let mapRaw: string; + try { + mapRaw = await fs.readFile(mapPath, "utf8"); + } catch { + return; + } + let tracer: TraceMap; + try { + tracer = new TraceMap(mapRaw); + } catch { + return; + } + let compiledJs: string; + try { + compiledJs = await fs.readFile(jsPath, "utf8"); + } catch { + return; + } + + const report = analyzeCoverage(tracer, compiledJs); + + for (const region of report.unmappedRegions) { + findings.push({ + ruleName: COVERAGE_ANALYSIS_RULE, + message: getMessage('CoverageUnmappedRegion', region.line, region.startCol, region.endCol, region.length), + file: jsPath, + startLine: region.line, + startColumn: region.startCol + 1, + }); + } + + if (report.excessiveUnmapped) { + findings.push({ + ruleName: COVERAGE_ANALYSIS_RULE, + message: getMessage('CoverageExcessiveCumulative', report.unmappedCountedPct.toFixed(2), report.totalChars, EXCESSIVE_UNMAPPED_PCT.toString()), + file: jsPath, + }); + } + }); + + return { findings }; +} + +export function analyzeCoverage( + tracer: TraceMap, + compiledJs: string, +): { + totalChars: number; + mappedChars: number; + coveragePct: number; + unmappedRegions: UnmappedRegion[]; + excessiveUnmapped: boolean; + unmappedCountedPct: number; +} { + const lines = compiledJs.split("\n"); + const lineCount = lines.length; + + const lineCols: number[][] = Array.from({ length: lineCount }, () => []); + eachMapping(tracer, (m) => { + const dstLine = m.generatedLine - 1; + if (dstLine >= 0 && dstLine < lineCount) { + lineCols[dstLine]!.push(m.generatedColumn); + } + }); + for (const cols of lineCols) { + cols.sort((a, b) => a - b); + let write = 0; + for (const col of cols) { + if (write === 0 || col !== cols[write - 1]) { + cols[write++] = col; + } + } + cols.length = write; + } + + let totalChars = 0; + let mappedChars = 0; + const unmappedRegions: UnmappedRegion[] = []; + + for (let i = 0; i < lineCount; i++) { + const lineText = lines[i]!; + const lineLen = lineText.length; + totalChars += lineLen; + if (lineLen === 0) continue; + + const cols = lineCols[i]!; + if (cols.length === 0) { + if (lineLen >= UNMAPPED_THRESHOLD) { + unmappedRegions.push({ line: i + 1, startCol: 0, endCol: lineLen, length: lineLen }); + } + continue; + } + + // Each mapping covers characters until the NEXT mapping — but only up to + // UNMAPPED_THRESHOLD chars, so a single mapping cannot silently credit an + // arbitrarily long minified tail. Gaps between consecutive mappings that + // exceed the threshold are recorded as unmapped regions. + let prevBoundary = 0; + for (let k = 0; k <= cols.length; k++) { + const boundary = k < cols.length ? cols[k]! : lineLen; + const gap = boundary - prevBoundary; + if (k === 0) { + // Leading gap: from column 0 to first mapping. + if (gap >= UNMAPPED_THRESHOLD) { + unmappedRegions.push({ + line: i + 1, + startCol: prevBoundary, + endCol: boundary, + length: gap, + }); + } + } else { + // Gap from previous mapping to this boundary (next mapping or EOL). + // The previous mapping covers up to UNMAPPED_THRESHOLD chars; anything + // past that is unmapped. + const covered = Math.min(gap, UNMAPPED_THRESHOLD); + mappedChars += covered; + const uncovered = gap - covered; + if (uncovered >= UNMAPPED_THRESHOLD) { + unmappedRegions.push({ + line: i + 1, + startCol: prevBoundary + covered, + endCol: boundary, + length: uncovered, + }); + } + } + prevBoundary = boundary; + } + } + + const coveragePct = totalChars > 0 ? (mappedChars / totalChars) * 100 : 100; + + let totalUnmappedCounted = 0; + for (const region of unmappedRegions) { + if (region.line === 1) { + if (region.endCol > LINE1_EXEMPT_CHARS) { + const countableStart = Math.max(region.startCol, LINE1_EXEMPT_CHARS); + totalUnmappedCounted += region.endCol - countableStart; + } + } else { + totalUnmappedCounted += region.length; + } + } + + const unmappedCountedPct = totalChars > 0 ? (totalUnmappedCounted / totalChars) * 100 : 0; + const excessiveUnmapped = unmappedCountedPct > EXCESSIVE_UNMAPPED_PCT; + + return { + totalChars, + mappedChars, + coveragePct, + unmappedRegions, + excessiveUnmapped, + unmappedCountedPct, + }; +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/invalid-source-references.ts b/packages/code-analyzer-uibundle-engine/src/validators/invalid-source-references.ts new file mode 100644 index 00000000..7c11d725 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/invalid-source-references.ts @@ -0,0 +1,61 @@ +import { promises as fs } from "node:fs"; +import * as path from "node:path"; +import { collectSourceMaps } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const INVALID_SOURCE_REFERENCES_RULE = "invalid-source-references"; + +const VIRTUAL_SCHEMES = /^(?:webpack|rollup|vite|esbuild|node):/; +const DATA_URL = /^data:/i; +const HTTP_URL = /^https?:\/\//i; + +export async function validateInvalidSourceReferences(distPath: string): Promise { + const { maps, parseErrors } = await collectSourceMaps(distPath); + const findings: ValidatorFinding[] = []; + + for (const { path: mapPath, message } of parseErrors) { + findings.push({ + ruleName: INVALID_SOURCE_REFERENCES_RULE, + message: getMessage('SourcemapNotValidJson', message), + file: mapPath, + }); + } + + for (const { path: mapPath, map } of maps) { + const mapDir = path.dirname(mapPath); + const contents = map.sourcesContent ?? []; + + for (let i = 0; i < map.sources.length; i++) { + const source = map.sources[i]; + if (!source) continue; + if (isVirtualOrRemote(source)) continue; + if (contents[i] != null) continue; + + const resolved = resolveSourcePath(source, map.sourceRoot ?? "", mapDir); + try { + await fs.access(resolved); + } catch { + findings.push({ + ruleName: INVALID_SOURCE_REFERENCES_RULE, + message: getMessage('SourceFileDoesNotExist', source, resolved), + file: mapPath, + startLine: 1, + startColumn: 1, + }); + } + } + } + return { findings }; +} + +function isVirtualOrRemote(source: string): boolean { + return VIRTUAL_SCHEMES.test(source) || DATA_URL.test(source) || HTTP_URL.test(source); +} + +function resolveSourcePath(source: string, sourceRoot: string, mapDir: string): string { + if (path.isAbsolute(source)) return source; + const withRoot = sourceRoot ? path.join(sourceRoot, source) : source; + if (path.isAbsolute(withRoot)) return withRoot; + return path.resolve(mapDir, withRoot); +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/missing-sourcemap.ts b/packages/code-analyzer-uibundle-engine/src/validators/missing-sourcemap.ts new file mode 100644 index 00000000..89aeee3c --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/missing-sourcemap.ts @@ -0,0 +1,87 @@ +import { promises as fs } from "node:fs"; +import * as path from "node:path"; +import { containsDangerousApi, DANGEROUS_API_PATTERNS } from "./classification"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const MISSING_SOURCEMAP_RULE = "missing-sourcemap"; + +export async function validateMissingSourcemaps(distPath: string): Promise { + let distStat: Awaited>; + try { + distStat = await fs.stat(distPath); + } catch { + return { findings: [], skipped: { reason: `dist path not found: ${distPath}` } }; + } + if (!distStat.isDirectory()) { + return { findings: [], skipped: { reason: `dist path is not a directory: ${distPath}` } }; + } + + const jsFiles = await collectJsFiles(distPath); + const findings: ValidatorFinding[] = []; + + for (const jsFile of jsFiles) { + if (await hasSourcemap(jsFile)) continue; + + findings.push({ + ruleName: MISSING_SOURCEMAP_RULE, + message: getMessage('MissingSourcemapForFile', path.relative(distPath, jsFile)), + file: jsFile, + startLine: 1, + startColumn: 1, + }); + + let content: string; + try { + content = await fs.readFile(jsFile, "utf8"); + } catch { + continue; + } + if (containsDangerousApi(content)) { + const hits = DANGEROUS_API_PATTERNS.filter((p) => content.includes(p)); + findings.push({ + ruleName: MISSING_SOURCEMAP_RULE, + message: getMessage('OrphanJsWithDangerousApi', hits.join(", ")), + file: jsFile, + startLine: 1, + startColumn: 1, + }); + } + } + + return { findings }; +} + +async function collectJsFiles(root: string): Promise { + const out: string[] = []; + async function walk(dir: string): Promise { + const entries = await fs.readdir(dir, { withFileTypes: true }); + for (const entry of entries) { + const full = path.join(dir, entry.name); + if (entry.isDirectory()) { + await walk(full); + } else if (entry.isFile() && entry.name.endsWith(".js")) { + out.push(full); + } + } + } + await walk(root); + return out; +} + +async function hasSourcemap(jsFile: string): Promise { + const colocated = `${jsFile}.map`; + try { + await fs.access(colocated); + return true; + } catch { + // fall through + } + + try { + const contents = await fs.readFile(jsFile, "utf8"); + return /^[/\s]*[#@]\s*sourceMappingURL\s*=/m.test(contents); + } catch { + return false; + } +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/path-leakage.ts b/packages/code-analyzer-uibundle-engine/src/validators/path-leakage.ts new file mode 100644 index 00000000..2656c525 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/path-leakage.ts @@ -0,0 +1,48 @@ +import { collectSourceMaps } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const PATH_LEAKAGE_RULE = "path-leakage"; + +const ABSOLUTE_UNIX_ROOT = /^\/(?:Users|home|root|app|build|opt|tmp|var)\//; +const ABSOLUTE_WIN_DRIVE = /^[A-Za-z]:[\\/]/; +const WIN_UNC = /^\\\\/; +const FILE_URL = /^file:\/\//i; + +export async function validatePathLeakage(distPath: string): Promise { + const { maps, parseErrors } = await collectSourceMaps(distPath); + const findings: ValidatorFinding[] = []; + + for (const { path: mapPath, message } of parseErrors) { + findings.push({ + ruleName: PATH_LEAKAGE_RULE, + message: getMessage('SourcemapNotValidJson', message), + file: mapPath, + }); + } + + for (const { path: mapPath, map } of maps) { + for (const source of map.sources) { + if (!source) continue; + if (isLeaking(source)) { + findings.push({ + ruleName: PATH_LEAKAGE_RULE, + message: getMessage('PathLeakageFinding', source), + file: mapPath, + startLine: 1, + startColumn: 1, + }); + } + } + } + return { findings }; +} + +function isLeaking(source: string): boolean { + return ( + ABSOLUTE_UNIX_ROOT.test(source) || + ABSOLUTE_WIN_DRIVE.test(source) || + WIN_UNC.test(source) || + FILE_URL.test(source) + ); +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/source-content-verification.ts b/packages/code-analyzer-uibundle-engine/src/validators/source-content-verification.ts new file mode 100644 index 00000000..ec801f2f --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/source-content-verification.ts @@ -0,0 +1,484 @@ +import { promises as fs } from "node:fs"; +import { parse, type ParserOptions } from "@babel/parser"; +import _traverse, { type NodePath } from "@babel/traverse"; +import type { Node } from "@babel/types"; +import { TraceMap, originalPositionFor } from "@jridgewell/trace-mapping"; +import { + containsDangerousPattern, + isAsset, + isDependency, + isVirtualSource, + normalizeLineEndings, + normalizeSourcePath, +} from "./classification"; +import { buildSourceIndex, walk, type SourceIndex } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +// ESM/CJS interop for @babel/traverse +const traverse = (_traverse as unknown as { default?: typeof _traverse }).default ?? _traverse; + +export const SOURCE_CONTENT_VERIFICATION_RULE = "source-content-verification"; + +const COVERAGE_THRESHOLD_LARGE = 95; +const COVERAGE_THRESHOLD_SMALL = 70; +const SMALL_FILE_NODE_COUNT = 500; +const TYPE_MISMATCH_THRESHOLD = 0.2; +const AST_MATCH_TOLERANCE_BYTES = 5; + +const VIRTUAL_SOURCE_RATIO_THRESHOLD_PCT = 20; + +const PARSER_OPTIONS: ParserOptions = { + sourceType: "unambiguous", + allowReturnOutsideFunction: true, + allowImportExportEverywhere: true, + errorRecovery: true, + plugins: ["jsx", "typescript", "decorators-legacy"], +}; + +const SIGNIFICANT_NODE_TYPES = new Set([ + "FunctionDeclaration", + "FunctionExpression", + "ArrowFunctionExpression", + "ClassDeclaration", + "ClassExpression", + "ClassMethod", + "ClassProperty", + "JSXElement", + "JSXFragment", + "CallExpression", + "NewExpression", + "MemberExpression", + "OptionalMemberExpression", + "AssignmentExpression", + "VariableDeclaration", + "ImportDeclaration", + "ExportNamedDeclaration", + "ExportDefaultDeclaration", + "ExportAllDeclaration", + "ReturnStatement", + "ThrowStatement", + "AwaitExpression", + "YieldExpression", +]); + +export function normalizeNodeType(t: string): string { + if ( + t === "ExportNamedDeclaration" || + t === "ExportDefaultDeclaration" || + t === "ExportAllDeclaration" + ) { + return "ExportDeclaration"; + } + return t; +} + +interface SignificantNode { + type: string; + line: number; + column: number; + byteOffset: number; + snippet: string; +} + +export interface SourceContentOptions { + sourcePath: string; + distPath: string; + sourceIndex?: SourceIndex; +} + +export async function validateSourceContent( + options: SourceContentOptions, +): Promise { + let sourceStat, distStat; + try { + sourceStat = await fs.stat(options.sourcePath); + } catch { + return { findings: [], skipped: { reason: `source path not found: ${options.sourcePath}` } }; + } + try { + distStat = await fs.stat(options.distPath); + } catch { + return { findings: [], skipped: { reason: `dist path not found: ${options.distPath}` } }; + } + if (!sourceStat.isDirectory() || !distStat.isDirectory()) { + return { findings: [], skipped: { reason: "source and dist must both be directories" } }; + } + + const sourceIndex = options.sourceIndex ?? await buildSourceIndex(options.sourcePath); + const findings: ValidatorFinding[] = []; + + await walk(options.distPath, async (jsPath) => { + if (!jsPath.endsWith(".js")) return; + const mapPath = `${jsPath}.map`; + let mapRaw: string; + try { + mapRaw = await fs.readFile(mapPath, "utf8"); + } catch { + return; + } + + let rawMap: RawSourceMap; + try { + rawMap = JSON.parse(mapRaw); + } catch (err) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentSourcemapNotJson', (err as Error).message), + file: mapPath, + }); + return; + } + + let tracer: TraceMap; + try { + tracer = new TraceMap(mapRaw); + } catch (err) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentSourcemapUnloadable', (err as Error).message), + file: mapPath, + }); + return; + } + + await runByteEqualAndRatioChecks(rawMap, mapPath, sourceIndex, findings); + + let compiledJs: string; + try { + compiledJs = await fs.readFile(jsPath, "utf8"); + } catch { + return; + } + await runAstChecks(jsPath, mapPath, compiledJs, tracer, sourceIndex, findings); + }); + + return { findings }; +} + +interface RawSourceMap { + version?: number; + sources?: (string | null)[]; + sourcesContent?: (string | null)[]; + sourceRoot?: string; +} + +async function runByteEqualAndRatioChecks( + map: RawSourceMap, + mapPath: string, + sourceIndex: SourceIndex, + findings: ValidatorFinding[], +): Promise { + const sources = map.sources ?? []; + if (sources.length === 0) return; + + let virtualCount = 0; + let total = 0; + + for (let i = 0; i < sources.length; i++) { + const raw = sources[i]; + if (raw == null) continue; + total++; + const normalized = normalizeSourcePath(raw); + + if (isVirtualSource(normalized)) { + virtualCount++; + continue; + } + if (isDependency(normalized) || isAsset(normalized)) { + continue; + } + + const submitted = sourceIndex.get(normalized); + const embedded = map.sourcesContent?.[i] ?? null; + + if (submitted == null) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentReferencesUnknownSource', raw, normalized), + file: mapPath, + }); + continue; + } + + if (embedded == null) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentMissingInline', normalized), + file: mapPath, + }); + continue; + } + + if (normalizeLineEndings(embedded).trim() !== normalizeLineEndings(submitted).trim()) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentBytewiseMismatch', normalized), + file: mapPath, + }); + } + } + + if (total > 0) { + const virtualPct = (virtualCount / total) * 100; + if (virtualPct > VIRTUAL_SOURCE_RATIO_THRESHOLD_PCT) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentExcessiveVirtualSources', virtualPct.toFixed(0), total, VIRTUAL_SOURCE_RATIO_THRESHOLD_PCT), + file: mapPath, + }); + } + } +} + +async function runAstChecks( + jsPath: string, + _mapPath: string, + compiledJs: string, + tracer: TraceMap, + sourceIndex: SourceIndex, + findings: ValidatorFinding[], +): Promise { + let significantNodes: SignificantNode[]; + try { + significantNodes = collectSignificantNodes(compiledJs); + } catch (err) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentCompiledParseFailed', (err as Error).message), + file: jsPath, + }); + return; + } + if (significantNodes.length === 0) return; + + const sourceAstCache = new Map(); + + let mappedCount = 0; + let typeMismatchCount = 0; + const unmapped: SignificantNode[] = []; + const typeMismatches: string[] = []; + const orphanSources = new Set(); + + for (const node of significantNodes) { + const orig = originalPositionFor(tracer, { line: node.line, column: node.column }); + if (orig.source == null || orig.line == null) { + unmapped.push(node); + continue; + } + mappedCount++; + + const normalized = normalizeSourcePath(orig.source); + + if (isVirtualSource(normalized) || isDependency(normalized) || isAsset(normalized)) continue; + + const submittedContent = sourceIndex.get(normalized); + if (submittedContent == null) { + orphanSources.add(normalized); + continue; + } + + const sourceAst = getSourceAst(normalized, submittedContent, sourceAstCache); + if (!sourceAst) continue; + const srcByteOffset = lineColToByteOffset(sourceAst.lineOffsets, orig.line, orig.column ?? 0); + const srcNode = findNodeAtOffset(sourceAst.nodes, srcByteOffset); + if (srcNode && !nodeTypesCompatible(node.type, srcNode.type)) { + typeMismatchCount++; + if (typeMismatches.length < 5) { + typeMismatches.push( + `${node.type} at ${node.line}:${node.column} → ${srcNode.type} at ${normalized}:${orig.line}:${orig.column ?? 0}`, + ); + } + } + } + + const total = significantNodes.length; + const coverage = (mappedCount / total) * 100; + const threshold = + total >= SMALL_FILE_NODE_COUNT ? COVERAGE_THRESHOLD_LARGE : COVERAGE_THRESHOLD_SMALL; + const typeMismatchRatio = mappedCount > 0 ? typeMismatchCount / mappedCount : 0; + + if (coverage < threshold) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentCoverageBelowThreshold', coverage.toFixed(1), threshold, mappedCount, total), + file: jsPath, + }); + for (const node of unmapped.slice(0, 5)) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentUnmappedNode', node.type, node.line, node.column, truncate(node.snippet, 80)), + file: jsPath, + startLine: node.line, + startColumn: node.column + 1, + }); + } + } + + if (typeMismatchRatio >= TYPE_MISMATCH_THRESHOLD) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentTypeMismatchRatio', (typeMismatchRatio * 100).toFixed(1), (TYPE_MISMATCH_THRESHOLD * 100).toString(), typeMismatchCount, mappedCount), + file: jsPath, + }); + for (const mm of typeMismatches) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentTypeMismatchDetail', mm), + file: jsPath, + }); + } + } + + const dangerousUnmapped = unmapped.filter( + (n) => n.line > 1 && containsDangerousPattern(n.snippet), + ); + for (const n of dangerousUnmapped.slice(0, 10)) { + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentDangerousUnmapped', n.type, n.line, n.column, truncate(n.snippet, 100)), + file: jsPath, + startLine: n.line, + startColumn: n.column + 1, + }); + } + + if (orphanSources.size > 0) { + const listed = [...orphanSources].slice(0, 5).join(", ") + (orphanSources.size > 5 ? ", …" : ""); + findings.push({ + ruleName: SOURCE_CONTENT_VERIFICATION_RULE, + message: getMessage('SourceContentOrphanSources', orphanSources.size, listed), + file: jsPath, + }); + } +} + +function collectSignificantNodes(code: string): SignificantNode[] { + const ast = parse(code, PARSER_OPTIONS); + const out: SignificantNode[] = []; + traverse(ast, { + enter(nodePath: NodePath) { + const node = nodePath.node; + if (!SIGNIFICANT_NODE_TYPES.has(node.type)) return; + if (!node.loc) return; + const start = node.loc.start; + const byteOffset = node.start ?? 0; + const snippet = extractSnippet(code, byteOffset, 60); + out.push({ + type: normalizeNodeType(node.type), + line: start.line, + column: start.column, + byteOffset, + snippet, + }); + }, + }); + return out; +} + +interface SourceAst { + nodes: SignificantNode[]; + lineOffsets: number[]; +} + +function getSourceAst( + normalized: string, + content: string, + cache: Map, +): SourceAst | null { + if (cache.has(normalized)) return cache.get(normalized) ?? null; + try { + const nodes = collectSignificantNodes(content); + const lineOffsets = buildLineOffsets(content); + const val: SourceAst = { nodes, lineOffsets }; + cache.set(normalized, val); + return val; + } catch { + cache.set(normalized, null); + return null; + } +} + +function buildLineOffsets(text: string): number[] { + const offsets: number[] = [0]; + for (let i = 0; i < text.length; i++) { + if (text.charCodeAt(i) === 10 /* \n */) offsets.push(i + 1); + } + return offsets; +} + +function lineColToByteOffset(lineOffsets: number[], line1: number, col0: number): number { + const line = Math.max(0, line1 - 1); + if (line < lineOffsets.length) return lineOffsets[line]! + col0; + return (lineOffsets[lineOffsets.length - 1] ?? 0) + col0; +} + +function findNodeAtOffset(nodes: SignificantNode[], byteOffset: number): SignificantNode | null { + const tol = AST_MATCH_TOLERANCE_BYTES; + // Nodes are produced by babel traversal in document order — byteOffset is non-decreasing. + // Binary-search the first node with byteOffset >= (target - tol), then linearly scan the + // tolerance window (at most a few nodes wide). + const lowerTarget = byteOffset - tol; + let lo = 0; + let hi = nodes.length; + while (lo < hi) { + const mid = (lo + hi) >>> 1; + if (nodes[mid]!.byteOffset < lowerTarget) lo = mid + 1; + else hi = mid; + } + let best: SignificantNode | null = null; + let bestDist = Number.POSITIVE_INFINITY; + for (let i = lo; i < nodes.length; i++) { + const n = nodes[i]!; + if (n.byteOffset > byteOffset + tol) break; + const dist = Math.abs(n.byteOffset - byteOffset); + if (dist < bestDist) { + bestDist = dist; + best = n; + } + } + return best; +} + +export function nodeTypesCompatible(generated: string, source: string): boolean { + if (generated === source) return true; + const funcs = new Set(["FunctionDeclaration", "FunctionExpression", "ArrowFunctionExpression"]); + if (funcs.has(generated) && funcs.has(source)) return true; + if ( + (generated === "CallExpression" || generated === "NewExpression") && + (source === "CallExpression" || source === "NewExpression") + ) + return true; + if ( + (generated === "AssignmentExpression" && source === "VariableDeclaration") || + (generated === "VariableDeclaration" && source === "AssignmentExpression") + ) + return true; + if ( + (generated === "MemberExpression" && source === "CallExpression") || + (generated === "CallExpression" && source === "MemberExpression") + ) + return true; + const declarations = new Set([ + "FunctionDeclaration", + "ClassDeclaration", + "VariableDeclaration", + "FunctionExpression", + "ArrowFunctionExpression", + ]); + if (generated === "ExportDeclaration" && declarations.has(source)) return true; + if (source === "ExportDeclaration" && declarations.has(generated)) return true; + return false; +} + +function extractSnippet(text: string, byteOffset: number, maxLen: number): string { + const start = byteOffset; + if (start >= text.length) return ""; + const end = Math.min(text.length, start + maxLen); + return text.slice(start, end).replace(/\n/g, " ").replace(/\r/g, ""); +} + +function truncate(s: string, n: number): string { + return s.length <= n ? s : s.slice(0, n) + "…"; +} + diff --git a/packages/code-analyzer-uibundle-engine/src/validators/sourcemap-io.ts b/packages/code-analyzer-uibundle-engine/src/validators/sourcemap-io.ts new file mode 100644 index 00000000..959fe64f --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/sourcemap-io.ts @@ -0,0 +1,94 @@ +import { promises as fs } from "node:fs"; +import * as path from "node:path"; +import { toPosixPath } from "./classification"; + +export type SourceIndex = Map; + +const INDEX_IGNORE_PREFIXES = ["node_modules", ".git", "dist"]; + +export async function buildSourceIndex(sourcePath: string): Promise { + const raw: SourceIndex = new Map(); + await walk(sourcePath, async (abs) => { + const rel = toPosixPath(path.relative(sourcePath, abs)); + if (INDEX_IGNORE_PREFIXES.some((prefix) => rel.startsWith(prefix))) return; + try { + const content = await fs.readFile(abs, "utf8"); + raw.set(rel, content); + } catch { + // skip + } + }); + const base = path.basename(sourcePath); + const expanded: SourceIndex = new Map(raw); + for (const [rel, content] of raw) { + expanded.set(`${base}/${rel}`, content); + } + return expanded; +} + +export interface RawSourceMap { + version: number; + file?: string; + sourceRoot?: string; + sources: (string | null)[]; + sourcesContent?: (string | null)[]; + names?: string[]; + mappings: string; +} + +export interface LoadedSourceMap { + path: string; + map: RawSourceMap; +} + +export interface SourceMapParseError { + path: string; + message: string; +} + +export interface CollectedSourceMaps { + maps: LoadedSourceMap[]; + parseErrors: SourceMapParseError[]; +} + +export async function collectSourceMaps(root: string): Promise { + const maps: LoadedSourceMap[] = []; + const parseErrors: SourceMapParseError[] = []; + await walk(root, async (file) => { + if (!file.endsWith(".js.map")) return; + let raw: string; + try { + raw = await fs.readFile(file, "utf8"); + } catch { + return; + } + let map: RawSourceMap; + try { + map = JSON.parse(raw) as RawSourceMap; + } catch (err) { + parseErrors.push({ path: file, message: (err as Error).message }); + return; + } + if (typeof map?.mappings === "string" && Array.isArray(map?.sources)) { + maps.push({ path: file, map }); + } + }); + return { maps, parseErrors }; +} + +export async function walk(root: string, visit: (file: string) => Promise): Promise { + let entries; + try { + entries = await fs.readdir(root, { withFileTypes: true }); + } catch { + return; + } + for (const entry of entries) { + const full = path.join(root, entry.name); + if (entry.isDirectory()) { + await walk(full, visit); + } else if (entry.isFile()) { + await visit(full); + } + } +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/structural-coherence.ts b/packages/code-analyzer-uibundle-engine/src/validators/structural-coherence.ts new file mode 100644 index 00000000..4c1feef1 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/structural-coherence.ts @@ -0,0 +1,239 @@ +import { promises as fs } from "node:fs"; +import { TraceMap, eachMapping, sourceContentFor } from "@jridgewell/trace-mapping"; +import { isAsset, isDependency, normalizeSourcePath } from "./classification"; +import { buildSourceIndex, walk, type SourceIndex } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const STRUCTURAL_COHERENCE_RULE = "structural-coherence"; + +const WHITESPACE_SAMPLE_INTERVAL = 10; +const WHITESPACE_SUSPICION_THRESHOLD = 0.8; +const JUMP_RATIO_WARN = 0.5; +const MAX_LISTED_BOUNDS = 10; + +interface BoundsViolation { + sourceFile: string; + claimedLine: number; + claimedCol: number; + actualLines: number; +} + +export interface StructuralCoherenceOptions { + sourcePath: string; + distPath: string; + sourceIndex?: SourceIndex; +} + +export async function validateStructuralCoherence( + options: StructuralCoherenceOptions, +): Promise { + let sourceStat, distStat; + try { + sourceStat = await fs.stat(options.sourcePath); + } catch { + return { findings: [], skipped: { reason: `source path not found: ${options.sourcePath}` } }; + } + try { + distStat = await fs.stat(options.distPath); + } catch { + return { findings: [], skipped: { reason: `dist path not found: ${options.distPath}` } }; + } + if (!sourceStat.isDirectory() || !distStat.isDirectory()) { + return { findings: [], skipped: { reason: "source and dist must both be directories" } }; + } + + const sourceIndex = options.sourceIndex ?? await buildSourceIndex(options.sourcePath); + const findings: ValidatorFinding[] = []; + + await walk(options.distPath, async (jsPath) => { + if (!jsPath.endsWith(".js")) return; + const mapPath = `${jsPath}.map`; + let mapRaw: string; + try { + mapRaw = await fs.readFile(mapPath, "utf8"); + } catch { + return; + } + let tracer: TraceMap; + try { + tracer = new TraceMap(mapRaw); + } catch { + return; + } + + const report = analyzeCoherence(tracer, sourceIndex); + + if (report.totalMappingsChecked === 0) return; + + if (report.boundsViolations.length > 0) { + findings.push({ + ruleName: STRUCTURAL_COHERENCE_RULE, + message: getMessage('CoherenceBoundsSummary', report.boundsViolations.length), + file: mapPath, + }); + for (const v of report.boundsViolations.slice(0, MAX_LISTED_BOUNDS)) { + findings.push({ + ruleName: STRUCTURAL_COHERENCE_RULE, + message: getMessage('CoherenceBoundsDetail', v.sourceFile, v.claimedLine + 1, v.claimedCol + 1, v.actualLines), + file: mapPath, + }); + } + } + + if (report.whitespaceSampleCount > 0) { + const wsRatio = report.whitespaceOnlyMappings / report.whitespaceSampleCount; + if (wsRatio > WHITESPACE_SUSPICION_THRESHOLD) { + findings.push({ + ruleName: STRUCTURAL_COHERENCE_RULE, + message: getMessage('CoherenceWhitespaceSuspicious', (wsRatio * 100).toFixed(1), report.whitespaceOnlyMappings, report.whitespaceSampleCount, (WHITESPACE_SUSPICION_THRESHOLD * 100).toString()), + file: mapPath, + }); + } + } + + if (report.suspiciousJumpRatio > JUMP_RATIO_WARN) { + findings.push({ + ruleName: STRUCTURAL_COHERENCE_RULE, + message: getMessage('CoherenceCrossFileJumpsSuspicious', report.suspiciousJumpRatio.toFixed(2), JUMP_RATIO_WARN.toString()), + file: mapPath, + }); + } + }); + + return { findings }; +} + +export function analyzeCoherence( + tracer: TraceMap, + sourceContents: Map, +): { + totalMappingsChecked: number; + boundsViolations: BoundsViolation[]; + whitespaceOnlyMappings: number; + whitespaceSampleCount: number; + suspiciousJumpRatio: number; +} { + const submittedLines = new Map(); + for (const [key, content] of sourceContents) { + submittedLines.set(key, content.split("\n")); + } + + const embeddedLines = new Map(); + + let totalMappingsChecked = 0; + const boundsViolations: BoundsViolation[] = []; + let whitespaceOnlyMappings = 0; + let whitespaceSampleCount = 0; + + let prevSource: string | null = null; + let prevDstLine: number | null = null; + let consecutivePairs = 0; + let crossFileJumps = 0; + let sampleIndex = 0; + + eachMapping(tracer, (m) => { + if (m.source == null || m.originalLine == null || m.originalColumn == null) return; + const srcRaw = m.source; + const normalized = normalizeSourcePath(srcRaw); + + if (isAsset(normalized) || isDependency(normalized)) return; + + const srcLine = m.originalLine - 1; + const srcCol = m.originalColumn; + const dstLine = m.generatedLine - 1; + + let lines = submittedLines.get(normalized); + if (!lines) { + lines = embeddedLines.get(srcRaw); + if (!lines) { + try { + const contents = sourceContentFor(tracer, srcRaw); + if (contents != null) { + lines = contents.split("\n"); + embeddedLines.set(srcRaw, lines); + } + } catch { + // skip + } + } + if (!lines) return; + } + + totalMappingsChecked++; + + const actualLines = lines.length; + if (srcLine >= actualLines) { + boundsViolations.push({ + sourceFile: normalized, + claimedLine: srcLine, + claimedCol: srcCol, + actualLines, + }); + } else { + const lineLen = lines[srcLine]!.length; + if (srcCol > lineLen) { + boundsViolations.push({ + sourceFile: normalized, + claimedLine: srcLine, + claimedCol: srcCol, + actualLines, + }); + } + } + + if (sampleIndex % WHITESPACE_SAMPLE_INTERVAL === 0 && srcLine < actualLines) { + whitespaceSampleCount++; + if (pointsToWhitespaceOrCommentInLines(lines, srcLine, srcCol)) { + whitespaceOnlyMappings++; + } + } + sampleIndex++; + + if (prevDstLine !== null && dstLine === prevDstLine) { + if (prevSource !== null) { + consecutivePairs++; + if (prevSource !== srcRaw) crossFileJumps++; + } + } + prevSource = srcRaw; + prevDstLine = dstLine; + }); + + const suspiciousJumpRatio = consecutivePairs > 0 ? crossFileJumps / consecutivePairs : 0; + + return { + totalMappingsChecked, + boundsViolations, + whitespaceOnlyMappings, + whitespaceSampleCount, + suspiciousJumpRatio, + }; +} + +export function pointsToWhitespaceOrComment(source: string, line0: number, col0: number): boolean { + return pointsToWhitespaceOrCommentInLines(source.split("\n"), line0, col0); +} + +function pointsToWhitespaceOrCommentInLines(lines: string[], line0: number, col0: number): boolean { + if (line0 >= lines.length) return false; + const lineText = lines[line0]!; + if (col0 >= lineText.length) return true; + + const fromCol = lineText.slice(col0); + const trimmed = fromCol.replace(/^[\s]+/, ""); + if (trimmed.length === 0) return true; + if (trimmed.startsWith("//") || trimmed.startsWith("/*") || trimmed.startsWith("*")) return true; + + const lineTrimmed = lineText.trim(); + if ( + lineTrimmed.startsWith("//") || + lineTrimmed.startsWith("/*") || + lineTrimmed.startsWith("*") || + lineTrimmed.endsWith("*/") + ) + return true; + + return false; +} + diff --git a/packages/code-analyzer-uibundle-engine/src/validators/token-consistency.ts b/packages/code-analyzer-uibundle-engine/src/validators/token-consistency.ts new file mode 100644 index 00000000..9b029648 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/token-consistency.ts @@ -0,0 +1,262 @@ +import { promises as fs } from "node:fs"; +import { TraceMap, eachMapping, sourceContentFor } from "@jridgewell/trace-mapping"; +import { isAsset, isDependency, isVirtualSource, normalizeSourcePath } from "./classification"; +import { buildSourceIndex, walk, type SourceIndex } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const TOKEN_CONSISTENCY_RULE = "token-consistency"; + +const SAMPLE_INTERVAL = 20; +const NAME_WINDOW_TOLERANCE = 3; +const VERDICT_SUSPICIOUS = 0.7; +const VERDICT_WARNING = 0.85; +const MAX_LISTED_MISMATCHES = 10; + +export type TokenCategory = + | "StringLiteral" + | "NumericLiteral" + | "Identifier" + | "Punctuation" + | "Other"; + +interface NameMismatch { + expectedName: string; + sourceFile: string; + line: number; + col: number; + foundText: string; +} + +export interface TokenConsistencyOptions { + sourcePath: string; + distPath: string; + sourceIndex?: SourceIndex; +} + +export async function validateTokenConsistency( + options: TokenConsistencyOptions, +): Promise { + let sourceStat, distStat; + try { + sourceStat = await fs.stat(options.sourcePath); + } catch { + return { findings: [], skipped: { reason: `source path not found: ${options.sourcePath}` } }; + } + try { + distStat = await fs.stat(options.distPath); + } catch { + return { findings: [], skipped: { reason: `dist path not found: ${options.distPath}` } }; + } + if (!sourceStat.isDirectory() || !distStat.isDirectory()) { + return { findings: [], skipped: { reason: "source and dist must both be directories" } }; + } + + const sourceIndex = options.sourceIndex ?? await buildSourceIndex(options.sourcePath); + const findings: ValidatorFinding[] = []; + + await walk(options.distPath, async (jsPath) => { + if (!jsPath.endsWith(".js")) return; + const mapPath = `${jsPath}.map`; + let mapRaw: string; + try { + mapRaw = await fs.readFile(mapPath, "utf8"); + } catch { + return; + } + let tracer: TraceMap; + try { + tracer = new TraceMap(mapRaw); + } catch { + return; + } + let compiledJs: string; + try { + compiledJs = await fs.readFile(jsPath, "utf8"); + } catch { + return; + } + + const report = analyzeTokenConsistency(tracer, compiledJs, sourceIndex); + if (report.totalSampled === 0) return; + + if (report.consistencyScore < VERDICT_SUSPICIOUS) { + findings.push({ + ruleName: TOKEN_CONSISTENCY_RULE, + message: getMessage('TokenConsistencySuspicious', (report.consistencyScore * 100).toFixed(1), (VERDICT_SUSPICIOUS * 100).toString(), report.consistent, report.totalSampled), + file: mapPath, + }); + } else if (report.consistencyScore < VERDICT_WARNING) { + findings.push({ + ruleName: TOKEN_CONSISTENCY_RULE, + message: getMessage('TokenConsistencyBelowWarning', (report.consistencyScore * 100).toFixed(1), (VERDICT_WARNING * 100).toString(), report.consistent, report.totalSampled), + file: mapPath, + }); + } + + if (report.nameMismatches.length > 0) { + findings.push({ + ruleName: TOKEN_CONSISTENCY_RULE, + message: getMessage('TokenNameMismatchSummary', report.nameMismatches.length, NAME_WINDOW_TOLERANCE), + file: mapPath, + }); + for (const m of report.nameMismatches.slice(0, MAX_LISTED_MISMATCHES)) { + findings.push({ + ruleName: TOKEN_CONSISTENCY_RULE, + message: getMessage('TokenNameMismatchDetail', m.expectedName, m.sourceFile, m.line + 1, m.col + 1, m.foundText), + file: mapPath, + }); + } + } + }); + + return { findings }; +} + +export function analyzeTokenConsistency( + tracer: TraceMap, + compiledJs: string, + sourceContents: Map, +): { + totalSampled: number; + consistent: number; + inconsistent: number; + nameMismatches: NameMismatch[]; + consistencyScore: number; +} { + const compiledLines = compiledJs.split("\n"); + const linesCache = new Map(); + for (const [key, content] of sourceContents) { + linesCache.set(key, content.split("\n")); + } + const embeddedLinesCache = new Map(); + + let totalSampled = 0; + let consistent = 0; + let inconsistent = 0; + const nameMismatches: NameMismatch[] = []; + + let idx = -1; + eachMapping(tracer, (m) => { + idx++; + if (idx % SAMPLE_INTERVAL !== 0) return; + if (m.source == null || m.originalLine == null || m.originalColumn == null) return; + + const srcRaw = m.source; + const normalized = normalizeSourcePath(srcRaw); + + if (isDependency(normalized) || isAsset(normalized) || isVirtualSource(normalized)) return; + + let sourceLines = linesCache.get(normalized) ?? null; + if (sourceLines == null) { + if (embeddedLinesCache.has(srcRaw)) { + sourceLines = embeddedLinesCache.get(srcRaw) ?? null; + } else { + try { + const c = sourceContentFor(tracer, srcRaw); + const split = c != null ? c.split("\n") : null; + embeddedLinesCache.set(srcRaw, split); + sourceLines = split; + } catch { + embeddedLinesCache.set(srcRaw, null); + } + } + } + if (sourceLines == null) return; + + totalSampled++; + + const srcLine = m.originalLine - 1; + const srcCol = m.originalColumn; + const dstLine = m.generatedLine - 1; + const dstCol = m.generatedColumn; + + if (m.name != null) { + const [found, foundText] = nameExistsNearInLines(sourceLines, srcLine, srcCol, m.name); + if (!found) { + nameMismatches.push({ + expectedName: m.name, + sourceFile: normalized, + line: srcLine, + col: srcCol, + foundText, + }); + } + } + + const genCat = classifyTokenAtInLines(compiledLines, dstLine, dstCol); + const srcCat = classifyTokenAtInLines(sourceLines, srcLine, srcCol); + if (categoriesAreConsistent(genCat, srcCat)) { + consistent++; + } else { + inconsistent++; + } + }); + + const consistencyScore = totalSampled > 0 ? consistent / totalSampled : 1.0; + + return { totalSampled, consistent, inconsistent, nameMismatches, consistencyScore }; +} + +export function classifyTokenAt(text: string, line0: number, col0: number): TokenCategory { + return classifyTokenAtInLines(text.split("\n"), line0, col0); +} + +function classifyTokenAtInLines(lines: string[], line0: number, col0: number): TokenCategory { + if (line0 >= lines.length) return "Other"; + const lineText = lines[line0]!; + if (col0 >= lineText.length) return "Other"; + const ch = lineText.charAt(col0); + if (ch === '"' || ch === "'" || ch === "`") return "StringLiteral"; + if (ch >= "0" && ch <= "9") return "NumericLiteral"; + if (/[A-Za-z_$]/.test(ch)) return "Identifier"; + if (/\s/.test(ch)) return "Other"; + return "Punctuation"; +} + +function categoriesAreConsistent(gen: TokenCategory, src: TokenCategory): boolean { + if (gen === src) return true; + if (gen === "Other" || src === "Other") return true; + if ( + (gen === "NumericLiteral" && src === "Identifier") || + (gen === "Identifier" && src === "NumericLiteral") + ) + return true; + return false; +} + +function nameExistsNearInLines( + lines: string[], + line0: number, + col0: number, + expected: string, +): [boolean, string] { + if (line0 >= lines.length) return [false, ""]; + const lineText = lines[line0]!; + + for (let offset = 0; offset <= NAME_WINDOW_TOLERANCE; offset++) { + for (const dir of [1, -1]) { + const checkCol = offset === 0 ? col0 : col0 + offset * dir; + if (checkCol < 0) continue; + const word = extractWordAt(lineText, checkCol, expected.length + 5); + if (word === expected) return [true, word]; + if (offset === 0) break; + } + } + + const found = extractWordAt(lineText, col0, expected.length + 10); + return [false, found]; +} + +function extractWordAt(line: string, col: number, maxLen: number): string { + if (col >= line.length) return ""; + let out = ""; + const end = Math.min(line.length, col + maxLen); + for (let i = col; i < end; i++) { + const c = line.charAt(i); + if (/[A-Za-z0-9_$]/.test(c)) out += c; + else break; + } + return out; +} + diff --git a/packages/code-analyzer-uibundle-engine/src/validators/types.ts b/packages/code-analyzer-uibundle-engine/src/validators/types.ts new file mode 100644 index 00000000..d099f903 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/types.ts @@ -0,0 +1,14 @@ +export interface ValidatorFinding { + ruleName: string; + message: string; + file: string; + startLine?: number; + startColumn?: number; +} + +export interface ValidatorResult { + findings: ValidatorFinding[]; + skipped?: { + reason: string; + }; +} diff --git a/packages/code-analyzer-uibundle-engine/src/validators/vlq-integrity.ts b/packages/code-analyzer-uibundle-engine/src/validators/vlq-integrity.ts new file mode 100644 index 00000000..87147f32 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/src/validators/vlq-integrity.ts @@ -0,0 +1,102 @@ +import { promises as fs } from "node:fs"; +import { decode } from "@jridgewell/sourcemap-codec"; +import { walk } from "./sourcemap-io"; +import { getMessage } from "../messages"; +import type { ValidatorFinding, ValidatorResult } from "./types"; + +export const VLQ_INTEGRITY_RULE = "vlq-integrity"; + +interface RawMap { + version?: number; + sources?: unknown; + mappings?: unknown; + names?: unknown; +} + +export async function validateVlqIntegrity(distPath: string): Promise { + const findings: ValidatorFinding[] = []; + + await walk(distPath, async (file) => { + if (!file.endsWith(".js.map")) return; + + let raw: string; + try { + raw = await fs.readFile(file, "utf8"); + } catch { + return; + } + + let parsed: RawMap; + try { + parsed = JSON.parse(raw) as RawMap; + } catch (err) { + findings.push({ + ruleName: VLQ_INTEGRITY_RULE, + message: getMessage('SourcemapNotValidJson', (err as Error).message), + file, + }); + return; + } + + if (typeof parsed.mappings !== "string") { + findings.push({ + ruleName: VLQ_INTEGRITY_RULE, + message: getMessage('SourcemapMissingMappings'), + file, + }); + return; + } + if (!Array.isArray(parsed.sources)) { + findings.push({ + ruleName: VLQ_INTEGRITY_RULE, + message: getMessage('SourcemapMissingSourcesArray'), + file, + }); + return; + } + + let decoded: number[][][]; + try { + decoded = decode(parsed.mappings); + } catch (err) { + findings.push({ + ruleName: VLQ_INTEGRITY_RULE, + message: getMessage('VlqDecodingFailed', (err as Error).message), + file, + }); + return; + } + + const sourcesLen = (parsed.sources as unknown[]).length; + const namesLen = Array.isArray(parsed.names) ? (parsed.names as unknown[]).length : 0; + + for (let lineIdx = 0; lineIdx < decoded.length; lineIdx++) { + const segments = decoded[lineIdx]!; + for (let segIdx = 0; segIdx < segments.length; segIdx++) { + const seg = segments[segIdx]!; + if (seg.length >= 4) { + const srcIdx = seg[1]!; + if (srcIdx < 0 || srcIdx >= sourcesLen) { + findings.push({ + ruleName: VLQ_INTEGRITY_RULE, + message: getMessage('SegmentSourceIndexOutOfRange', lineIdx + 1, segIdx + 1, srcIdx, sourcesLen), + file, + }); + } + } + if (seg.length === 5) { + const nameIdx = seg[4]!; + if (nameIdx < 0 || nameIdx >= namesLen) { + findings.push({ + ruleName: VLQ_INTEGRITY_RULE, + message: getMessage('SegmentNameIndexOutOfRange', lineIdx + 1, segIdx + 1, nameIdx, namesLen), + file, + }); + } + } + } + } + }); + + return { findings }; +} diff --git a/packages/code-analyzer-uibundle-engine/test/engine.test.ts b/packages/code-analyzer-uibundle-engine/test/engine.test.ts new file mode 100644 index 00000000..d6bbdfd6 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/test/engine.test.ts @@ -0,0 +1,219 @@ +import { + EngineRunResults, + RuleDescription, + Workspace, +} from "@salesforce/code-analyzer-engine-api"; +import * as fs from "node:fs"; +import * as path from "node:path"; +import { UIBundleEngine } from "../src/engine"; +import { + changeWorkingDirectoryToPackageRoot, + createDescribeOptions, + createRunOptions, + installTmpDirCleanup, + makeTmpDir, + writeFile, +} from "./test-helpers"; + +changeWorkingDirectoryToPackageRoot(); +installTmpDirCleanup(); + +const TEST_DATA_FOLDER: string = path.join(__dirname, 'test-data'); +const GOLDFILE = 'uibundle-engine-goldfile.json'; + +describe('UIBundleEngine Tests', () => { + let expectedRules: RuleDescription[]; + + beforeAll(async () => { + const raw = await fs.promises.readFile(path.join(TEST_DATA_FOLDER, GOLDFILE), 'utf-8'); + expectedRules = JSON.parse(raw) as RuleDescription[]; + }); + + describe('getName', () => { + it('When getName is called, then the engine name is returned', () => { + const engine = new UIBundleEngine(); + expect(engine.getName()).toEqual('uibundle'); + }); + }); + + describe('getEngineVersion', () => { + it('Outputs something resembling a semantic version', async () => { + const engine = new UIBundleEngine(); + const version = await engine.getEngineVersion(); + expect(version).toMatch(/\d+\.\d+\.\d+.*/); + }); + }); + + describe('describeRules', () => { + it('When describeRules is called, then all rules are returned', async () => { + const engine = new UIBundleEngine(); + const rules = await engine.describeRules(createDescribeOptions()); + expect(rules).toEqual(expectedRules); + }); + }); + + describe('runRules', () => { + it('When zero rule names are provided, then zero violations are returned', async () => { + const engine = new UIBundleEngine(); + const results: EngineRunResults = await engine.runRules( + [], + createRunOptions(new Workspace('id', [TEST_DATA_FOLDER])), + ); + expect(results.violations).toHaveLength(0); + }); + + it('When no bundle targets are found in the workspace, then zero violations are returned', async () => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + writeFile(tmp, 'README.md', '# not a bundle'); + const results: EngineRunResults = await engine.runRules( + ['missing-sourcemap'], + createRunOptions(new Workspace('id', [tmp])), + ); + expect(results.violations).toHaveLength(0); + }); + + it('missing-sourcemap: raises a violation when a compiled .js has no adjacent .js.map and no //# sourceMappingURL', async () => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + writeFile(tmp, 'ui-bundle.json', '{}'); + writeFile(tmp, 'dist/main.js', 'console.log("hello");\n'); + const results: EngineRunResults = await engine.runRules( + ['missing-sourcemap'], + createRunOptions(new Workspace('id', [tmp])), + ); + expect(results.violations.length).toBeGreaterThan(0); + const v = results.violations[0]!; + expect(v.ruleName).toEqual('missing-sourcemap'); + expect(v.codeLocations[0]!.file).toContain(path.join('dist', 'main.js')); + expect(v.codeLocations[0]!.startLine).toBeGreaterThanOrEqual(1); + expect(v.codeLocations[0]!.startColumn).toBeGreaterThanOrEqual(1); + }); + + it('missing-sourcemap: no violation when a co-located .js.map exists', async () => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + writeFile(tmp, 'ui-bundle.json', '{}'); + writeFile(tmp, 'dist/main.js', 'console.log("hello");\n//# sourceMappingURL=main.js.map\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: '', + })); + const results: EngineRunResults = await engine.runRules( + ['missing-sourcemap'], + createRunOptions(new Workspace('id', [tmp])), + ); + expect(results.violations).toHaveLength(0); + }); + + const perRuleViolationCases: Array<{ desc: string; rule: string; mapJson: unknown }> = [ + { + desc: 'path-leakage: absolute unix home path in sources[]', + rule: 'path-leakage', + mapJson: { + version: 3, + sources: ['/Users/attacker/src/main.js'], + names: [], + mappings: '', + }, + }, + { + desc: 'vlq-integrity: sourcemap JSON has no "mappings" field', + rule: 'vlq-integrity', + mapJson: { + version: 3, + sources: ['../src/main.js'], + names: [], + }, + }, + { + desc: 'vlq-integrity: segment source index out of range', + rule: 'vlq-integrity', + mapJson: { + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: 'AICA', + }, + }, + { + desc: 'invalid-source-references: sources[] entry does not exist on disk', + rule: 'invalid-source-references', + mapJson: { + version: 3, + sources: ['../src/missing.js'], + names: [], + mappings: '', + }, + }, + ]; + + it.each(perRuleViolationCases)('$desc', async ({ rule, mapJson }) => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + writeFile(tmp, 'ui-bundle.json', '{}'); + writeFile(tmp, 'dist/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify(mapJson)); + const results: EngineRunResults = await engine.runRules( + [rule], + createRunOptions(new Workspace('id', [tmp])), + ); + const matched = results.violations.filter(v => v.ruleName === rule); + expect(matched.length).toBeGreaterThan(0); + }); + + it('bundle target detection: workspace containing files under dist/ still triggers rule execution', async () => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + // No ui-bundle.json here — the engine should fall back to detecting bundles from any dist/ ancestor. + writeFile(tmp, 'my-bundle/dist/main.js', 'console.log("hi");\n'); + const results: EngineRunResults = await engine.runRules( + ['missing-sourcemap'], + createRunOptions(new Workspace('id', [tmp])), + ); + expect(results.violations.length).toBeGreaterThan(0); + expect(results.violations[0]!.ruleName).toEqual('missing-sourcemap'); + }); + + it('emits SFCA 1-based startColumn for whole-file findings across missing-sourcemap, path-leakage, invalid-source-references and coverage-analysis', async () => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + writeFile(tmp, 'ui-bundle.json', '{}'); + writeFile(tmp, 'dist/orphan.js', 'document.cookie = "x=1";\n'); + writeFile(tmp, 'dist/main.js', 'a'.repeat(200) + '\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['/Users/attacker/src/main.js', '../src/missing.js'], + names: [], + mappings: '', + })); + + const results: EngineRunResults = await engine.runRules( + ['missing-sourcemap', 'path-leakage', 'invalid-source-references', 'coverage-analysis'], + createRunOptions(new Workspace('id', [tmp])), + ); + + const byRule = new Map(); + for (const v of results.violations) { + byRule.set(v.ruleName, (byRule.get(v.ruleName) ?? 0) + 1); + expect(v.codeLocations[0]!.startLine).toBeGreaterThanOrEqual(1); + expect(v.codeLocations[0]!.startColumn).toBeGreaterThanOrEqual(1); + } + expect(byRule.get('missing-sourcemap')).toBeGreaterThan(0); + expect(byRule.get('path-leakage')).toBeGreaterThan(0); + expect(byRule.get('invalid-source-references')).toBeGreaterThan(0); + + const wholeFile = results.violations.filter(v => + v.ruleName === 'missing-sourcemap' || + v.ruleName === 'path-leakage' || + v.ruleName === 'invalid-source-references' + ); + expect(wholeFile.length).toBeGreaterThan(0); + for (const v of wholeFile) { + expect(v.codeLocations[0]!.startColumn).toEqual(1); + } + }); + }); +}); diff --git a/packages/code-analyzer-uibundle-engine/test/plugin.test.ts b/packages/code-analyzer-uibundle-engine/test/plugin.test.ts new file mode 100644 index 00000000..27e283be --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/test/plugin.test.ts @@ -0,0 +1,31 @@ +import { EnginePluginV1 } from "@salesforce/code-analyzer-engine-api"; +import { UIBundleEnginePlugin } from "../src"; +import { UIBundleEngine } from "../src/engine"; +import { getMessage } from "../src/messages"; + +describe('Tests for the UIBundleEnginePlugin', () => { + let plugin: EnginePluginV1; + const engineName = 'uibundle'; + beforeAll(() => { + plugin = new UIBundleEnginePlugin(); + }); + + describe('getAvailableEngineNames', () => { + it(`When the getAvailableEngineNames method is called then '${engineName}' is returned`, () => { + expect(plugin.getAvailableEngineNames()).toEqual([engineName]); + }); + }); + + describe('createEngine', () => { + it(`When createEngine is called with an invalid name then an error is thrown`, async () => { + await expect(plugin.createEngine('error_engine', {})).rejects.toThrow( + getMessage('UnsupportedEngineName', 'error_engine')); + }); + + it(`When createEngine is passed '${engineName}', then the UIBundleEngine is returned`, async () => { + const engine = await plugin.createEngine(engineName, {}); + expect(engine).toBeInstanceOf(UIBundleEngine); + expect(engine.getName()).toEqual(engineName); + }); + }); +}); diff --git a/packages/code-analyzer-uibundle-engine/test/test-data/uibundle-engine-goldfile.json b/packages/code-analyzer-uibundle-engine/test/test-data/uibundle-engine-goldfile.json new file mode 100644 index 00000000..8f610be6 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/test/test-data/uibundle-engine-goldfile.json @@ -0,0 +1,80 @@ +[ + { + "name": "missing-sourcemap", + "severityLevel": 2, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Every compiled .js file in the build output must have a corresponding sourcemap (co-located .js.map or //# sourceMappingURL). Missing sourcemaps prevent source-to-compiled verification during security review.", + "resourceUrls": [ + "https://developer.mozilla.org/en-US/docs/Tools/Debugger/How_to/Use_a_source_map" + ] + }, + { + "name": "path-leakage", + "severityLevel": 3, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Sourcemap sources[] entries must be relative paths. Absolute paths leak developer environment details (usernames, filesystem layout) into shipped artifacts.", + "resourceUrls": [] + }, + { + "name": "invalid-source-references", + "severityLevel": 2, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Every file referenced by a sourcemap sources[] entry (that doesn't have inline sourcesContent) must exist on disk. Missing files indicate tampering or an incomplete submission.", + "resourceUrls": [] + }, + { + "name": "vlq-integrity", + "severityLevel": 2, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Sourcemap \"mappings\" field must be valid Base64 VLQ and reference in-range source/name indices. Malformed mappings signal a fabricated or corrupted sourcemap.", + "resourceUrls": [ + "https://tc39.es/ecma426/#sec-mapping-groups" + ] + }, + { + "name": "source-content-verification", + "severityLevel": 2, + "tags": [ + "UIBundleIntegrity" + ], + "description": "AST-based verification that the compiled JS actually traces back to the submitted source. Parses compiled output with @babel/parser, collects significant AST nodes, and checks each has a sourcemap mapping into a source file present on disk. Also enforces byte-equal sourcesContent, a virtual-source ratio cap, an AST type-mismatch threshold, and flags dangerous API patterns in unmapped regions.", + "resourceUrls": [ + "https://tc39.es/source-map/" + ] + }, + { + "name": "coverage-analysis", + "severityLevel": 5, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Character-level coverage analysis (informational). Flags per-line unmapped regions of 50+ chars and raises a cumulative finding when more than 2% of the compiled file (line-1 preamble discounted up to 150 chars) has no sourcemap coverage.", + "resourceUrls": [] + }, + { + "name": "structural-coherence", + "severityLevel": 5, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Structural coherence checks on sourcemap tokens (informational). Flags out-of-bounds mappings, sample-based whitespace/comment-only mappings above 80%, and cross-file jump ratios above 50% on consecutive same-line tokens.", + "resourceUrls": [] + }, + { + "name": "token-consistency", + "severityLevel": 5, + "tags": [ + "UIBundleIntegrity" + ], + "description": "Token-type consistency checks on sampled sourcemap tokens (informational). Every 20th mapping is compared between compiled and source positions; verifies names[] entries exist near the claimed source position (±3 col tolerance); flags scores below 85% (warning) and below 70% (suspicious).", + "resourceUrls": [] + } +] diff --git a/packages/code-analyzer-uibundle-engine/test/test-helpers.ts b/packages/code-analyzer-uibundle-engine/test/test-helpers.ts new file mode 100644 index 00000000..c6628777 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/test/test-helpers.ts @@ -0,0 +1,63 @@ +import { DescribeOptions, RunOptions, Workspace } from "@salesforce/code-analyzer-engine-api"; +import * as fs from "node:fs"; +import * as os from "node:os"; +import * as path from "node:path"; +import * as process from "node:process"; + +export function changeWorkingDirectoryToPackageRoot() { + let original_working_directory: string; + beforeAll(() => { + // We change the directory so that any relative-path lookups (e.g. getEngineVersion + // reading ../package.json) resolve consistently regardless of where jest is invoked. + // Using the package root — not the test directory — is also needed for IDE coverage. + original_working_directory = process.cwd(); + process.chdir(path.resolve(__dirname, '..')); + }); + afterAll(() => { + process.chdir(original_working_directory); + }); +} + +export function createDescribeOptions(workspace?: Workspace): DescribeOptions { + return { + logFolder: os.tmpdir(), + workspace: workspace, + workingFolder: fs.mkdtempSync(path.join(os.tmpdir(), 'tmp-')) + }; +} + +export function createRunOptions(workspace: Workspace): RunOptions { + return { + logFolder: os.tmpdir(), + workspace: workspace, + workingFolder: fs.mkdtempSync(path.join(os.tmpdir(), 'tmp-')) + }; +} + +const _createdTmpDirs: string[] = []; + +export function makeTmpDir(prefix = 'uibundle-engine-'): string { + const dir = fs.mkdtempSync(path.join(os.tmpdir(), prefix)); + _createdTmpDirs.push(dir); + return dir; +} + +export function installTmpDirCleanup(): void { + afterEach(() => { + while (_createdTmpDirs.length > 0) { + const dir = _createdTmpDirs.pop()!; + try { + fs.rmSync(dir, { recursive: true, force: true }); + } catch { + // Best-effort cleanup — a stray tmp dir is not worth failing a test. + } + } + }); +} + +export function writeFile(root: string, relPath: string, contents: string): string { + const abs = path.join(root, relPath); + fs.mkdirSync(path.dirname(abs), { recursive: true }); + fs.writeFileSync(abs, contents, 'utf8'); + return abs; +} diff --git a/packages/code-analyzer-uibundle-engine/test/validators-integration.test.ts b/packages/code-analyzer-uibundle-engine/test/validators-integration.test.ts new file mode 100644 index 00000000..8345548c --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/test/validators-integration.test.ts @@ -0,0 +1,666 @@ +import { encode, type SourceMapSegment } from "@jridgewell/sourcemap-codec"; +import { TraceMap } from "@jridgewell/trace-mapping"; +import * as path from "node:path"; +import { analyzeCoverage, validateCoverageAnalysis } from "../src/validators/coverage-analysis"; +import { validateInvalidSourceReferences } from "../src/validators/invalid-source-references"; +import { validateMissingSourcemaps } from "../src/validators/missing-sourcemap"; +import { validatePathLeakage } from "../src/validators/path-leakage"; +import { + validateSourceContent, + nodeTypesCompatible, + normalizeNodeType, +} from "../src/validators/source-content-verification"; +import { + analyzeCoherence, + validateStructuralCoherence, +} from "../src/validators/structural-coherence"; +import { + analyzeTokenConsistency, + validateTokenConsistency, +} from "../src/validators/token-consistency"; +import { validateVlqIntegrity } from "../src/validators/vlq-integrity"; +import { changeWorkingDirectoryToPackageRoot, installTmpDirCleanup, makeTmpDir, writeFile } from "./test-helpers"; + +changeWorkingDirectoryToPackageRoot(); +installTmpDirCleanup(); + +describe('missing-sourcemap dangerous-API orphan JS branch', () => { + it('emits an extra finding when an orphan JS contains a dangerous API pattern', async () => { + const tmp = makeTmpDir(); + // No colocated .map and no //# sourceMappingURL comment — orphan JS. + writeFile(tmp, 'dist/leaky.js', 'document.cookie = "x=1"; localStorage.setItem("a","b");\n'); + + const res = await validateMissingSourcemaps(path.join(tmp, 'dist')); + expect(res.findings.length).toBeGreaterThanOrEqual(2); + const messages = res.findings.map(f => f.message).join('|'); + expect(messages).toMatch(/document\.cookie|localStorage/); + }); + + it('skips when distPath is a file rather than a directory', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist.js', 'x'); + const res = await validateMissingSourcemaps(path.join(tmp, 'dist.js')); + expect(res.skipped).toBeDefined(); + }); +}); + +describe('coverage-analysis file-walker', () => { + it('emits an unmapped-region finding and cumulative-budget finding', async () => { + const tmp = makeTmpDir(); + // A very long line with no mappings triggers both the per-line unmapped-region + // finding and the cumulative-budget finding (line 1 has ~200 chars, >150 exempt). + const longLine = 'a'.repeat(200) + '\n'; + writeFile(tmp, 'dist/main.js', longLine); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: '', // no mappings at all + })); + + const res = await validateCoverageAnalysis(path.join(tmp, 'dist')); + const messages = res.findings.map(f => f.message).join(' | '); + expect(res.findings.length).toBeGreaterThan(0); + expect(messages.length).toBeGreaterThan(0); + // Region starts at 0-based col 0 in the analyzer → validator emits 1-based col 1. + const region = res.findings.find(f => f.startColumn !== undefined); + expect(region!.startColumn).toEqual(1); + }); + + it('skipped when distPath is a file rather than a directory', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'x.js', 'x'); + const res = await validateCoverageAnalysis(path.join(tmp, 'x.js')); + expect(res.skipped).toBeDefined(); + }); + + it('analyzeCoverage emits an unmapped region on partial coverage after threshold', () => { + // A line with a first mapping at column 60 (>= UNMAPPED_THRESHOLD=50) yields one region. + const tracer = new TraceMap({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encode([[[60, 0, 0, 0]]]), + }); + const compiled = ' '.repeat(60) + 'x = 1;\n'; + const report = analyzeCoverage(tracer, compiled); + expect(report.unmappedRegions.length).toBe(1); + expect(report.unmappedRegions[0]!.startCol).toBe(0); + }); +}); + +describe('vlq-integrity file-walker', () => { + it('emits a finding when JSON is not parseable', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', 'not valid json'); + const res = await validateVlqIntegrity(path.join(tmp, 'dist')); + expect(res.findings.length).toBeGreaterThan(0); + expect(res.findings[0]!.message).toMatch(/JSON|parse/i); + }); + + it('emits a finding when sources[] is missing', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + names: [], + mappings: '', + })); + const res = await validateVlqIntegrity(path.join(tmp, 'dist')); + expect(res.findings.length).toBeGreaterThan(0); + }); + + it('emits a finding when a name index is out of range', async () => { + // Segment "AICAC" decodes to [0,1,1,0,1] — name index 1, but names[] has length 1. + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['a', 'b'], + names: ['a'], + mappings: 'AICAC', + })); + const res = await validateVlqIntegrity(path.join(tmp, 'dist')); + const nameOob = res.findings.filter(f => /name/i.test(f.message)); + expect(nameOob.length).toBeGreaterThan(0); + }); + + it('emits a SourcemapNotValidJson finding when a .js.map is not valid JSON', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', '{ not: valid json'); + const res = await validateVlqIntegrity(path.join(tmp, 'dist')); + const jsonErr = res.findings.filter(f => /not valid json/i.test(f.message)); + expect(jsonErr.length).toBeGreaterThan(0); + }); +}); + +describe('path-leakage', () => { + it('flags windows drive letter and file:// URL', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['C:\\Users\\attacker\\main.js', 'file:///home/attacker/main.js'], + names: [], + mappings: '', + })); + const res = await validatePathLeakage(path.join(tmp, 'dist')); + expect(res.findings.length).toBe(2); + }); + + it('does not flag virtual or relative sources', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js', 'webpack:///./src/foo.js', 'src/x.js'], + names: [], + mappings: '', + })); + const res = await validatePathLeakage(path.join(tmp, 'dist')); + expect(res.findings.length).toBe(0); + }); +}); + +describe('invalid-source-references', () => { + it('skips a source when sourcesContent[i] is populated', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/missing.js'], + sourcesContent: ['/* content — declares self-contained */'], + names: [], + mappings: '', + })); + const res = await validateInvalidSourceReferences(path.join(tmp, 'dist')); + expect(res.findings.length).toBe(0); + }); + + it('skips virtual and remote sources', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: [ + 'webpack:internal://foo', + 'data:application/json;base64,e30=', + 'https://cdn.example/foo.js', + ], + names: [], + mappings: '', + })); + const res = await validateInvalidSourceReferences(path.join(tmp, 'dist')); + expect(res.findings.length).toBe(0); + }); + + it('resolves against sourceRoot when provided', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sourceRoot: '../src', + sources: ['does-not-exist.js'], + names: [], + mappings: '', + })); + const res = await validateInvalidSourceReferences(path.join(tmp, 'dist')); + expect(res.findings.length).toBe(1); + }); +}); + +describe('structural-coherence file-walker', () => { + it('emits a bounds-violation finding via the validator', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'let x = 1;\n'); + writeFile(tmp, 'dist/main.js', 'let x = 1;\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encode([[[0, 0, 99, 0]]]), // line 99 doesn't exist + })); + const res = await validateStructuralCoherence({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const bounds = res.findings.filter(f => /out|bound/i.test(f.message)); + expect(bounds.length).toBeGreaterThan(0); + }); + + it('skipped when sourcePath is a file', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src.js', 'x'); + writeFile(tmp, 'dist/main.js', 'x'); + const res = await validateStructuralCoherence({ + sourcePath: path.join(tmp, 'src.js'), + distPath: path.join(tmp, 'dist'), + }); + expect(res.skipped).toBeDefined(); + }); + + it('analyzeCoherence flags out-of-bounds column and consumes embedded sourcesContent', () => { + // No matching submitted source in the index → falls through to sourceContentFor. + const tracer = new TraceMap({ + version: 3, + sources: ['virtual.js'], + sourcesContent: ['let x = 1;\n'], + names: [], + mappings: encode([[[0, 0, 0, 999]]]), // column 999 way past line length + }); + const report = analyzeCoherence(tracer, new Map()); + expect(report.boundsViolations.length).toBeGreaterThan(0); + }); +}); + +describe('token-consistency file-walker', () => { + it('emits a suspicious finding when compiled and source token categories disagree', async () => { + const tmp = makeTmpDir(); + // Compiled has a string literal (`"a"`) where the map points into a source identifier — mismatch. + writeFile(tmp, 'src/main.js', 'foo\n'); + writeFile(tmp, 'dist/main.js', '"a"\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + })); + const res = await validateTokenConsistency({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + // Either suspicious or warning finding depending on rounding — assert something surfaced. + expect(res.findings.length).toBeGreaterThan(0); + }); + + it('skipped when distPath is a file rather than a directory', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'x'); + writeFile(tmp, 'dist.js', 'x'); + const res = await validateTokenConsistency({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist.js'), + }); + expect(res.skipped).toBeDefined(); + }); + + it('quietly skips a .js.map that TraceMap cannot load', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js.map', 'not valid json'); + const res = await validateTokenConsistency({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + expect(res.skipped).toBeUndefined(); + expect(res.findings).toEqual([]); + }); + + it('analyzeTokenConsistency emits a name mismatch when names[] entry is absent from source', () => { + const tracer = new TraceMap({ + version: 3, + sources: ['../src/main.js'], + names: ['expectedName'], + // one mapping at gen(0,0) → src(0,0), name index 0 + mappings: encode([[[0, 0, 0, 0, 0]]]), + }); + const compiled = 'x'; + const src = new Map([['src/main.js', 'y']]); + const report = analyzeTokenConsistency(tracer, compiled, src); + expect(report.nameMismatches.length).toBe(1); + expect(report.nameMismatches[0]!.expectedName).toEqual('expectedName'); + }); + + it('analyzeTokenConsistency accepts embedded sourcesContent when index misses the source', () => { + const tracer = new TraceMap({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: ['foo'], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + }); + const report = analyzeTokenConsistency(tracer, 'foo', new Map()); + expect(report.totalSampled).toBe(1); + expect(report.consistencyScore).toBe(1); + }); +}); + +describe('source-content-verification', () => { + it('emits a bytewise-mismatch finding when submitted and embedded diverge', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'export const x = 1;\n'); + writeFile(tmp, 'dist/main.js', 'export const x = 1;\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: ['export const x = 999999;\n'], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const bm = res.findings.filter(f => /byte|mismatch/i.test(f.message)); + expect(bm.length).toBeGreaterThan(0); + }); + + it('flags missing inline content when sourcesContent[i] is null', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'export const x = 1;\n'); + writeFile(tmp, 'dist/main.js', 'export const x = 1;\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: [null], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const missingInline = res.findings.filter(f => /inline|missing/i.test(f.message)); + expect(missingInline.length).toBeGreaterThan(0); + }); + + it('flags a virtual-source ratio above threshold', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js', 'x\n'); + // 6 of 6 sources virtual → 100% > 20% threshold. + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: [ + 'webpack/runtime/a', + 'webpack/runtime/b', + 'webpack/runtime/c', + 'webpack/runtime/d', + 'webpack/runtime/e', + 'webpack/runtime/f', + ], + sourcesContent: [null, null, null, null, null, null], + names: [], + mappings: '', + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const excessive = res.findings.filter(f => /virtual/i.test(f.message)); + expect(excessive.length).toBeGreaterThan(0); + }); + + it('flags an unknown-source when normalized path is not in the index', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/other.js', 'y\n'); + writeFile(tmp, 'dist/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/nowhere.js'], + sourcesContent: [null], + names: [], + mappings: '', + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const unknown = res.findings.filter(f => /unknown|references/i.test(f.message)); + expect(unknown.length).toBeGreaterThan(0); + }); + + it('surfaces a parse-fail finding when the sourcemap JSON is invalid', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js.map', 'not-json'); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + expect(res.findings.length).toBeGreaterThan(0); + }); + + it('skipped when sourcePath is missing', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'dist/main.js', 'x\n'); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'nowhere'), + distPath: path.join(tmp, 'dist'), + }); + expect(res.skipped).toBeDefined(); + }); + + it('emits a coverage-below-threshold finding when significant nodes are largely unmapped', async () => { + const tmp = makeTmpDir(); + // Multiple significant nodes in compiled, but sourcemap has zero mappings → 0% coverage. + const src = 'const x = 1;\nconst y = 2;\nfunction z() { return 1; }\n'; + const compiled = 'const x = 1;\nconst y = 2;\nfunction z() { return 1; }\n'; + writeFile(tmp, 'src/main.js', src); + writeFile(tmp, 'dist/main.js', compiled); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: [src], + names: [], + mappings: '', // no mappings at all + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const coverage = res.findings.filter(f => /coverage/i.test(f.message)); + expect(coverage.length).toBeGreaterThan(0); + }); + + it('flags dangerous-unmapped snippets that appear past line 1', async () => { + const tmp = makeTmpDir(); + // Compiled has a fetch(...) on line 2 that maps to nothing. + writeFile(tmp, 'src/main.js', 'const x = 1;\n'); + writeFile(tmp, 'dist/main.js', 'const x = 1;\nfetch("https://x");\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: ['const x = 1;\n'], + names: [], + mappings: '', + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const dangerous = res.findings.filter(f => /dangerous|unmapped/i.test(f.message)); + expect(dangerous.length).toBeGreaterThan(0); + }); + + it('surfaces a compiled-parse-failed finding when the JS cannot be parsed', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'x\n'); + // Deliberately unparseable JS. + writeFile(tmp, 'dist/main.js', 'const;;; = ((\n'); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: '', + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + // The parse failure path may or may not fire depending on Babel's error-recovery; + // at minimum, a coverage-below-threshold finding should surface. + expect(res.findings.length).toBeGreaterThan(0); + }); + + it('nodeTypesCompatible accepts equivalent pairs and rejects unrelated ones', () => { + expect(nodeTypesCompatible('CallExpression', 'CallExpression')).toBe(true); + expect(nodeTypesCompatible('FunctionDeclaration', 'ArrowFunctionExpression')).toBe(true); + expect(nodeTypesCompatible('CallExpression', 'NewExpression')).toBe(true); + expect(nodeTypesCompatible('AssignmentExpression', 'VariableDeclaration')).toBe(true); + expect(nodeTypesCompatible('VariableDeclaration', 'AssignmentExpression')).toBe(true); + expect(nodeTypesCompatible('MemberExpression', 'CallExpression')).toBe(true); + expect(nodeTypesCompatible('CallExpression', 'MemberExpression')).toBe(true); + expect(nodeTypesCompatible('ExportDeclaration', 'FunctionDeclaration')).toBe(true); + expect(nodeTypesCompatible('VariableDeclaration', 'ExportDeclaration')).toBe(true); + expect(nodeTypesCompatible('CallExpression', 'ClassDeclaration')).toBe(false); + expect(nodeTypesCompatible('ReturnStatement', 'ThrowStatement')).toBe(false); + }); + + it('normalizeNodeType collapses export forms to ExportDeclaration', () => { + expect(normalizeNodeType('ExportNamedDeclaration')).toBe('ExportDeclaration'); + expect(normalizeNodeType('ExportDefaultDeclaration')).toBe('ExportDeclaration'); + expect(normalizeNodeType('ExportAllDeclaration')).toBe('ExportDeclaration'); + expect(normalizeNodeType('CallExpression')).toBe('CallExpression'); + }); + + it('exercises the AST-node-lookup path with a mapped bundle so type-compat matrix is walked', async () => { + const tmp = makeTmpDir(); + // Source and compiled have identical shape; a single mapping at (0,0) sends + // AST search to a byte-offset in the source content — walking nodeTypesCompatible(). + const shared = 'export function foo() { return 1; }\n'; + writeFile(tmp, 'src/main.js', shared); + writeFile(tmp, 'dist/main.js', shared); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: [shared], + names: [], + // A mapping every few columns so multiple significant nodes land in source AST. + mappings: encode([[ + [0, 0, 0, 0], + [7, 0, 0, 7], + [16, 0, 0, 16], + [22, 0, 0, 22], + ]]), + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + // Source and compiled are identical → the byte-equal check must not fire. + // If the AST-compat matrix regressed and started emitting spurious mismatches + // on identical content, this assertion will catch it. + const byteMismatches = res.findings.filter((f) => /byte|mismatch/i.test(f.message)); + expect(byteMismatches).toEqual([]); + }); + + it('does not raise orphan findings when mapped AST nodes resolve to virtual/dependency/asset sources', async () => { + const tmp = makeTmpDir(); + const shared = 'export function foo() { return 1; }\n'; + writeFile(tmp, 'src/main.js', shared); + writeFile(tmp, 'dist/main.js', shared); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + // Three sources: one virtual (webpack/runtime prefix), one dependency (node_modules/), + // one asset (.png). None exist on disk; all should be skipped by runAstChecks. + sources: [ + '../webpack/runtime/foo', + '../node_modules/lib/index.js', + '../assets/sprite.png', + ], + sourcesContent: [null, null, null], + names: [], + mappings: encode([[ + [0, 0, 0, 0], + [7, 1, 0, 0], + [16, 2, 0, 0], + ]]), + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const orphanFindings = res.findings.filter((f) => /AST node source\(s\) not present/i.test(f.message)); + expect(orphanFindings).toEqual([]); + const unknownRefs = res.findings.filter((f) => /Sourcemap references source .* is not present/i.test(f.message)); + expect(unknownRefs).toEqual([]); + }); + + it('surfaces a sourcemap-unloadable finding when the map JSON parses but TraceMap rejects it', async () => { + const tmp = makeTmpDir(); + writeFile(tmp, 'src/main.js', 'x\n'); + writeFile(tmp, 'dist/main.js', 'x\n'); + // Missing "sources" field → TraceMap throws. + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + names: [], + mappings: '', + })); + const res = await validateSourceContent({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const unloadable = res.findings.filter((f) => /could not be loaded|unloadable/i.test(f.message)); + expect(unloadable.length).toBeGreaterThan(0); + }); +}); + +describe('structural-coherence branch coverage', () => { + it('emits a whitespace-heavy finding when >80% of sampled mappings land on whitespace', async () => { + const tmp = makeTmpDir(); + // 12 mappings, first sampled every 10 (0, 10) both land into whitespace-only source lines. + // Source is all whitespace, compiled is short — TraceMap will map each into the same source col 0. + const emptySrc = ' \n \n \n \n \n \n'; + const compiled = 'a\n'; + writeFile(tmp, 'src/main.js', emptySrc); + writeFile(tmp, 'dist/main.js', compiled); + // Build a chain of 15 mappings on generated line 1. + const segs: SourceMapSegment[] = []; + for (let i = 0; i < 15; i++) segs.push([i, 0, 0, 0]); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: [emptySrc], + names: [], + mappings: encode([segs]), + })); + const res = await validateStructuralCoherence({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const whitespaceFindings = res.findings.filter((f) => /whitespace|comment/i.test(f.message)); + expect(whitespaceFindings.length).toBeGreaterThan(0); + }); + + it('emits a cross-file-jump finding when consecutive tokens flip between sources', async () => { + const tmp = makeTmpDir(); + const srcA = 'aaaaa\n'; + const srcB = 'bbbbb\n'; + writeFile(tmp, 'src/a.js', srcA); + writeFile(tmp, 'src/b.js', srcB); + writeFile(tmp, 'dist/main.js', 'x'.repeat(10) + '\n'); + // 10 mappings on generated line 1 alternating between src[0] and src[1]. + const segs: SourceMapSegment[] = []; + // Segments are relative-encoded; use absolute values via a chain of alternating source-index deltas. + // encode() re-encodes properly. + let genCol = 0; + for (let i = 0; i < 10; i++) { + segs.push([genCol, i % 2, 0, 0]); + genCol += 1; + } + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/a.js', '../src/b.js'], + sourcesContent: [srcA, srcB], + names: [], + mappings: encode([segs]), + })); + const res = await validateStructuralCoherence({ + sourcePath: path.join(tmp, 'src'), + distPath: path.join(tmp, 'dist'), + }); + const jumpFindings = res.findings.filter((f) => /cross-file jump|jump ratio/i.test(f.message)); + expect(jumpFindings.length).toBeGreaterThan(0); + }); +}); + +describe('walk() ENOENT tolerance', () => { + it('validateVlqIntegrity on missing dist returns findings=[]', async () => { + const missing = path.join(makeTmpDir(), 'nope'); + const res = await validateVlqIntegrity(missing); + expect(res.findings).toEqual([]); + }); + + it('validateCoverageAnalysis on missing dist returns skipped', async () => { + const missing = path.join(makeTmpDir(), 'nope'); + const res = await validateCoverageAnalysis(missing); + expect(res.skipped).toBeDefined(); + }); +}); + diff --git a/packages/code-analyzer-uibundle-engine/test/validators.test.ts b/packages/code-analyzer-uibundle-engine/test/validators.test.ts new file mode 100644 index 00000000..224a1659 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/test/validators.test.ts @@ -0,0 +1,264 @@ +import { encode, type SourceMapSegment } from "@jridgewell/sourcemap-codec"; +import { TraceMap, type SourceMapInput } from "@jridgewell/trace-mapping"; +import { EngineRunResults, Workspace } from "@salesforce/code-analyzer-engine-api"; +import * as path from "node:path"; +import { UIBundleEngine } from "../src/engine"; +import { + containsDangerousApi, + containsDangerousPattern, + isAsset, + isDependency, + isVirtualSource, + normalizeSourcePath, +} from "../src/validators/classification"; +import { analyzeCoverage } from "../src/validators/coverage-analysis"; +import { validateInvalidSourceReferences } from "../src/validators/invalid-source-references"; +import { validateMissingSourcemaps } from "../src/validators/missing-sourcemap"; +import { validatePathLeakage } from "../src/validators/path-leakage"; +import { validateSourceContent } from "../src/validators/source-content-verification"; +import { + analyzeCoherence, + pointsToWhitespaceOrComment, + validateStructuralCoherence, +} from "../src/validators/structural-coherence"; +import { + analyzeTokenConsistency, + classifyTokenAt, + validateTokenConsistency, +} from "../src/validators/token-consistency"; +import { validateVlqIntegrity } from "../src/validators/vlq-integrity"; +import { changeWorkingDirectoryToPackageRoot, createRunOptions, installTmpDirCleanup, makeTmpDir, writeFile } from "./test-helpers"; + +changeWorkingDirectoryToPackageRoot(); +installTmpDirCleanup(); + +describe('classification', () => { + it('normalizes leading dot-slash and dot-dot segments and bundler URL schemes', () => { + expect(normalizeSourcePath('./src/foo.js')).toEqual('src/foo.js'); + expect(normalizeSourcePath('../src/foo.js')).toEqual('src/foo.js'); + expect(normalizeSourcePath('/src/foo.js')).toEqual('src/foo.js'); + expect(normalizeSourcePath('webpack:///src/foo.js')).toEqual('src/foo.js'); + expect(normalizeSourcePath('webpack://src/foo.js')).toEqual('src/foo.js'); + }); + + it('identifies virtual, dependency, and asset sources', () => { + // The virtual predicate hits on bundler-runtime prefixes and query-string embellishments. + expect(isVirtualSource('webpack/runtime/hasOwnProperty')).toEqual(true); + expect(isVirtualSource('vite/dist/client/env.mjs')).toEqual(true); + expect(isVirtualSource('src/x.js?vue&type=script')).toEqual(true); + expect(isVirtualSource('src/x.js')).toEqual(false); + expect(isDependency('node_modules/foo/index.js')).toEqual(true); + expect(isDependency('packages/pkg/node_modules/foo/index.js')).toEqual(true); + expect(isDependency('src/x.js')).toEqual(false); + expect(isAsset('logo.png')).toEqual(true); + expect(isAsset('src/x.ts')).toEqual(false); + }); + + it('flags dangerous API patterns in code and dangerous-only extras', () => { + // Detects known API-scan strings (e.g. eval/Function tokens are stored split at rest). + expect(containsDangerousApi('document.cookie = "x=1"')).toEqual(true); + expect(containsDangerousApi('localStorage.setItem("a", "b")')).toEqual(true); + expect(containsDangerousApi('const a = 1;')).toEqual(false); + + // AST-extra patterns catch bundler-safe helpers plus the base set. + expect(containsDangerousPattern('fetch("https://x")')).toEqual(true); + expect(containsDangerousPattern('doc.createElement("script")')).toEqual(true); + expect(containsDangerousPattern('normal function foo() {}')).toEqual(false); + }); +}); + +describe('analyzeCoverage', () => { + function makeTraceMapWithCoverage(mappings: SourceMapSegment[][]): TraceMap { + const encoded = encode(mappings); + return new TraceMap({ + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encoded, + } as SourceMapInput); + } + + it('flags a long fully-unmapped line as an unmapped region', () => { + const tracer = makeTraceMapWithCoverage([[]]); + const compiled = 'a'.repeat(60) + '\n'; + const report = analyzeCoverage(tracer, compiled); + expect(report.unmappedRegions.length).toBeGreaterThan(0); + expect(report.unmappedRegions[0]!.length).toBeGreaterThanOrEqual(50); + }); + + it('does not flag a short line', () => { + const tracer = makeTraceMapWithCoverage([[]]); + const compiled = 'short\n'; + const report = analyzeCoverage(tracer, compiled); + expect(report.unmappedRegions).toHaveLength(0); + }); + + it('exempts up to 150 chars on line 1 when computing excessive-unmapped budget', () => { + // line 1 is fully unmapped but only 100 chars — should NOT count toward budget. + const tracer = makeTraceMapWithCoverage([[]]); + const compiled = 'a'.repeat(100) + '\n'; + const report = analyzeCoverage(tracer, compiled); + expect(report.excessiveUnmapped).toEqual(false); + }); + + it('does not over-credit a minified line with a single mapping at column 0', () => { + // A single mapping cannot silently credit the whole line — anything past the + // per-mapping reach must be flagged unmapped and reduce mappedChars. + const tracer = makeTraceMapWithCoverage([[[0, 0, 0, 0]]]); + const lineLen = 5000; + const compiled = 'a'.repeat(lineLen); + const report = analyzeCoverage(tracer, compiled); + expect(report.coveragePct).toBeLessThan(50); + expect(report.unmappedRegions.length).toBeGreaterThan(0); + }); +}); + +describe('pointsToWhitespaceOrComment', () => { + it('detects whitespace-only after column', () => { + // Points into a run of trailing whitespace with no non-whitespace after it. + expect(pointsToWhitespaceOrComment('let x = 1; ', 0, 11)).toEqual(true); + }); + it('detects line comment prefix', () => { + expect(pointsToWhitespaceOrComment('// hello', 0, 0)).toEqual(true); + }); + it('detects block comment prefix', () => { + expect(pointsToWhitespaceOrComment('/* hello */', 0, 0)).toEqual(true); + }); + it('returns false on a real identifier', () => { + expect(pointsToWhitespaceOrComment('let x = 1;', 0, 4)).toEqual(false); + }); +}); + +describe('classifyTokenAt', () => { + it('recognizes strings, numbers, identifiers, and punctuation', () => { + expect(classifyTokenAt('"a"', 0, 0)).toEqual('StringLiteral'); + expect(classifyTokenAt("'a'", 0, 0)).toEqual('StringLiteral'); + expect(classifyTokenAt('`a`', 0, 0)).toEqual('StringLiteral'); + expect(classifyTokenAt('42', 0, 0)).toEqual('NumericLiteral'); + expect(classifyTokenAt('foo', 0, 0)).toEqual('Identifier'); + expect(classifyTokenAt('{', 0, 0)).toEqual('Punctuation'); + expect(classifyTokenAt(' ', 0, 0)).toEqual('Other'); + expect(classifyTokenAt('', 0, 0)).toEqual('Other'); + expect(classifyTokenAt('abc', 5, 0)).toEqual('Other'); + }); +}); + +describe('analyzeCoherence', () => { + it('reports zero bounds violations for an in-range mapping', () => { + // Mapping [[[0,0,0,0]]] → generated line 1 col 0 → src 0 line 0 col 0 + const mapJson = { + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + }; + const tracer = new TraceMap(mapJson as SourceMapInput); + const src = new Map([['src/main.js', 'let x = 1;\nlet y = 2;\n']]); + const report = analyzeCoherence(tracer, src); + expect(report.totalMappingsChecked).toEqual(1); + expect(report.boundsViolations).toHaveLength(0); + }); + + it('reports a bounds violation when the mapping claims a line past EOF', () => { + // Segment [0,0,99,0] → src file line index 99 which does not exist. + const mapJson = { + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encode([[[0, 0, 99, 0]]]), + }; + const tracer = new TraceMap(mapJson as SourceMapInput); + const src = new Map([['src/main.js', 'let x = 1;\n']]); + const report = analyzeCoherence(tracer, src); + expect(report.boundsViolations.length).toBeGreaterThan(0); + }); +}); + +describe('analyzeTokenConsistency', () => { + it('returns a perfect score when compiled and source tokens agree', () => { + // Both sides point to identifiers. + const mapJson = { + version: 3, + sources: ['../src/main.js'], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + }; + const tracer = new TraceMap(mapJson as SourceMapInput); + const compiled = 'foo'; + const src = new Map([['src/main.js', 'foo']]); + const report = analyzeTokenConsistency(tracer, compiled, src); + expect(report.totalSampled).toEqual(1); + expect(report.consistencyScore).toEqual(1); + }); +}); + +describe('End-to-end validator dispatch (all rules together)', () => { + it('dispatches all 8 rules against a fully-populated bundle without crashing', async () => { + const engine = new UIBundleEngine(); + const tmp = makeTmpDir(); + writeFile(tmp, 'ui-bundle.json', '{}'); + + const src = 'export const answer = 42;\n'; + const compiled = 'export const answer = 42;\n//# sourceMappingURL=main.js.map\n'; + writeFile(tmp, 'src/main.js', src); + writeFile(tmp, 'dist/main.js', compiled); + writeFile(tmp, 'dist/main.js.map', JSON.stringify({ + version: 3, + sources: ['../src/main.js'], + sourcesContent: [src], + names: [], + mappings: encode([[[0, 0, 0, 0]]]), + })); + + const results: EngineRunResults = await engine.runRules( + [ + 'missing-sourcemap', + 'path-leakage', + 'invalid-source-references', + 'vlq-integrity', + 'source-content-verification', + 'coverage-analysis', + 'structural-coherence', + 'token-consistency', + ], + createRunOptions(new Workspace('id', [tmp])), + ); + // Every violation should carry 1-based coordinates and be one of the 8 rule names. + for (const v of results.violations) { + expect([ + 'missing-sourcemap', + 'path-leakage', + 'invalid-source-references', + 'vlq-integrity', + 'source-content-verification', + 'coverage-analysis', + 'structural-coherence', + 'token-consistency', + ]).toContain(v.ruleName); + expect(v.codeLocations[0]!.startLine).toBeGreaterThanOrEqual(1); + expect(v.codeLocations[0]!.startColumn).toBeGreaterThanOrEqual(1); + } + }); + + it('validators handle missing input paths gracefully', async () => { + const missing = path.join(makeTmpDir(), 'does-not-exist'); + + // Dist-only walkers silently return an empty result set for missing dirs. + const missingRef = await validateInvalidSourceReferences(missing); + expect(missingRef.findings).toEqual([]); + const missingLeak = await validatePathLeakage(missing); + expect(missingLeak.findings).toEqual([]); + const missingVlq = await validateVlqIntegrity(missing); + expect(missingVlq.findings).toEqual([]); + + // Explicit-stat validators emit a `skipped` reason instead. + const missingMap = await validateMissingSourcemaps(missing); + expect(missingMap.skipped).toBeDefined(); + const missingCoverage = await validateSourceContent({ sourcePath: missing, distPath: missing }); + expect(missingCoverage.skipped).toBeDefined(); + const missingCoh = await validateStructuralCoherence({ sourcePath: missing, distPath: missing }); + expect(missingCoh.skipped).toBeDefined(); + const missingTok = await validateTokenConsistency({ sourcePath: missing, distPath: missing }); + expect(missingTok.skipped).toBeDefined(); + }); +}); diff --git a/packages/code-analyzer-uibundle-engine/tsconfig.build.json b/packages/code-analyzer-uibundle-engine/tsconfig.build.json new file mode 100644 index 00000000..69d7a287 --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/tsconfig.build.json @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "composite": true, + "outDir": "./dist", + "rootDir": "./src" + }, + "include": [ + "./src" + ], + "references": [ + { + "path": "../code-analyzer-engine-api/tsconfig.build.json" + } + ] +} diff --git a/packages/code-analyzer-uibundle-engine/tsconfig.json b/packages/code-analyzer-uibundle-engine/tsconfig.json new file mode 100644 index 00000000..111c54ac --- /dev/null +++ b/packages/code-analyzer-uibundle-engine/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.build.json", + "compilerOptions": { + "rootDir": ".", + "noEmit": true + }, + "include": [ + "./src", + "./test" + ] + }