From 07a0f665ab65de0414a225f8ec74fc094eb2aa19 Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Thu, 16 Jul 2026 10:41:06 +0200 Subject: [PATCH 1/6] fix-package --- .github/workflows/test.yml | 3 + package-lock.json | 912 +++++++++++++++++- package.json | 4 + suites/newssite/news-nuxt/package.json | 1 + suites/react-stockcharts/package.json | 1 + .../jquery-complex/package.json | 1 + .../architecture-examples/jquery/package.json | 1 + .../lit-complex/package.json | 1 + .../architecture-examples/lit/package.json | 1 + tests/setup-node.mjs | 18 + 10 files changed, 933 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 1ba59d5b7..a835ce600 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -26,6 +26,9 @@ jobs: - name: Install Node Packages run: npm ci + - name: Run package.json linter + run: npm run lint:pkg + - name: Run linters run: npm run format diff --git a/package-lock.json b/package-lock.json index e2f72f5ec..9cdf09502 100644 --- a/package-lock.json +++ b/package-lock.json @@ -30,6 +30,9 @@ "lws-log": "^3.0.0", "lws-static": "^3.1.1", "mocha": "^10.2.0", + "normalize-package-data": "^8.0.0", + "npm-package-json-lint": "^10.4.1", + "npm-package-json-lint-config-default": "^9.0.1", "prettier": "^2.8.3", "prettier-plugin-tailwindcss": "^0.4.1", "selenium-webdriver": "^4.44.0", @@ -104,7 +107,6 @@ "integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/code-frame": "^7.29.7", "@babel/generator": "^7.29.7", @@ -1026,6 +1028,20 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/semver": { "version": "7.7.1", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.7.1.tgz", @@ -1094,7 +1110,6 @@ "integrity": "sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA==", "dev": true, "license": "BSD-2-Clause", - "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "5.62.0", "@typescript-eslint/types": "5.62.0", @@ -1316,7 +1331,6 @@ "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -1351,6 +1365,16 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": ">=5.0.0" + } + }, "node_modules/ansi-colors": { "version": "4.1.3", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", @@ -1604,6 +1628,16 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/async": { "version": "2.6.4", "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", @@ -2111,7 +2145,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.10.12", "caniuse-lite": "^1.0.30001782", @@ -2256,6 +2289,34 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "license": "MIT", + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/camelcase-keys/node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/can-symlink": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/can-symlink/-/can-symlink-1.0.0.tgz", @@ -2674,6 +2735,33 @@ "dev": true, "license": "MIT" }, + "node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "license": "MIT", + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/create-mixin": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/create-mixin/-/create-mixin-3.0.0.tgz", @@ -2821,6 +2909,43 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/decamelize-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", + "dev": true, + "license": "MIT", + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decamelize-keys/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", @@ -3151,6 +3276,16 @@ "dev": true, "license": "ISC" }, + "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==", + "dev": true, + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, "node_modules/es-abstract": { "version": "1.24.2", "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", @@ -3369,7 +3504,6 @@ "deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -4355,6 +4489,16 @@ "dev": true, "license": "MIT" }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/has-bigints": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.1.0.tgz", @@ -4528,6 +4672,29 @@ "dev": true, "license": "MIT" }, + "node_modules/hosted-git-info": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-9.0.3.tgz", + "integrity": "sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^11.1.0" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "11.5.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.5.2.tgz", + "integrity": "sha512-4pfM1Ff0x50o0tQwb5ucw/RzNyD0/YJME6IVcStalZuMWxdt3sR3huStTtxz4PUmvZfRguvDejasvQ2kifR11g==", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": "20 || >=22" + } + }, "node_modules/http-assert": { "version": "1.5.0", "resolved": "https://registry.npmjs.org/http-assert/-/http-assert-1.5.0.tgz", @@ -4634,6 +4801,16 @@ "node": ">=0.8.19" } }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -4686,6 +4863,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", + "dev": true, + "license": "MIT" + }, "node_modules/is-async-function": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-async-function/-/is-async-function-2.1.1.tgz", @@ -5297,6 +5481,13 @@ "dev": true, "license": "MIT" }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true, + "license": "MIT" + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -5324,6 +5515,13 @@ "node": ">=6" } }, + "node_modules/jsonc-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz", + "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==", + "dev": true, + "license": "MIT" + }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", @@ -5453,6 +5651,16 @@ "json-buffer": "3.0.1" } }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/koa": { "version": "2.16.4", "resolved": "https://registry.npmjs.org/koa/-/koa-2.16.4.tgz", @@ -5593,6 +5801,13 @@ "isobject": "^2.0.0" } }, + "node_modules/lines-and-columns": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", + "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", + "dev": true, + "license": "MIT" + }, "node_modules/load-module": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/load-module/-/load-module-5.0.0.tgz", @@ -5987,6 +6202,19 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/matcher-collection": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-1.1.2.tgz", @@ -6024,6 +6252,118 @@ "node": ">= 0.6" } }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize": "^1.2.0", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true, + "license": "ISC" + }, "node_modules/merge-trees": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-trees/-/merge-trees-2.0.0.tgz", @@ -6092,6 +6432,16 @@ "node": ">=6" } }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, "node_modules/minimatch": { "version": "3.1.5", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", @@ -6115,6 +6465,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "license": "MIT", + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/minipass": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz", @@ -6390,6 +6765,34 @@ "node": ">=18" } }, + "node_modules/normalize-package-data": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-8.0.0.tgz", + "integrity": "sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^9.0.0", + "semver": "^7.3.5", + "validate-npm-package-license": "^3.0.4" + }, + "engines": { + "node": "^20.17.0 || >=22.9.0" + } + }, + "node_modules/normalize-package-data/node_modules/semver": { + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -6400,9 +6803,214 @@ "node": ">=0.10.0" } }, - "node_modules/nth-check": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", + "node_modules/npm-package-json-lint": { + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/npm-package-json-lint/-/npm-package-json-lint-10.4.1.tgz", + "integrity": "sha512-9PAwX8gIewSPf/PDR6yv8wifeq0UAPaSjUMU36lpCTPu8SvQ23/1NRAkcYQld5CgzoVWqGP2mEfM5oyEwu4ubw==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "6.14.0", + "ajv-errors": "1.0.1", + "chalk": "4.1.2", + "cosmiconfig": "8.3.6", + "debug": "4.4.3", + "globby": "11.1.0", + "ignore": "5.3.2", + "jsonc-parser": "3.3.1", + "meow": "9.0.0", + "minimatch": "10.2.5", + "semver": "7.8.4", + "strip-json-comments": "3.1.1", + "type-fest": "5.7.0", + "validate-npm-package-name": "6.0.0" + }, + "bin": { + "npmPkgJsonLint": "dist/cli.js" + }, + "engines": { + "node": ">=22.0.0", + "npm": ">=10.0.0" + } + }, + "node_modules/npm-package-json-lint-config-default": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/npm-package-json-lint-config-default/-/npm-package-json-lint-config-default-9.0.1.tgz", + "integrity": "sha512-IJ/k8rnOt38B7F5pbJpulgWzgWuFTC40U/jwyXtoG1HnKHSiDJO7Pjgn8l6xVSDgJn8CBC/aGvkZmutxCtwO6w==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=22.0.0", + "npm": ">=10.0.0" + }, + "peerDependencies": { + "npm-package-json-lint": "^10.0.0" + } + }, + "node_modules/npm-package-json-lint/node_modules/ajv": { + "version": "6.14.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz", + "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/npm-package-json-lint/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/npm-package-json-lint/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==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/npm-package-json-lint/node_modules/brace-expansion": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.7.tgz", + "integrity": "sha512-7oFy703dxfY3/NLxC1fh2SUCQ0H9rmAY+5EpDVfXjUTTs+HEwR2nYaqLv+GWcTsumwxPfiz6CzCNkwXwBUwqCA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^4.0.2" + }, + "engines": { + "node": "18 || 20 || >=22" + } + }, + "node_modules/npm-package-json-lint/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/npm-package-json-lint/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/npm-package-json-lint/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, + "license": "MIT" + }, + "node_modules/npm-package-json-lint/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/minimatch": { + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", + "dev": true, + "license": "BlueOak-1.0.0", + "dependencies": { + "brace-expansion": "^5.0.5" + }, + "engines": { + "node": "18 || 20 || >=22" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/npm-package-json-lint/node_modules/semver": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.4.tgz", + "integrity": "sha512-rUCObTnP32Q08R2uuIrt7r9PlEonuTmtuXYcW6s5kjdlj3xbnwe+21yXptAUYcMAABLkYYTtnmzb3w3EDZfueA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/npm-package-json-lint/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-package-json-lint/node_modules/type-fest": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-5.7.0.tgz", + "integrity": "sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "dependencies": { + "tagged-tag": "^1.0.0" + }, + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/nth-check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz", "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==", "dev": true, "license": "BSD-2-Clause", @@ -6772,6 +7380,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/package-json-from-dist": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", @@ -6799,6 +7417,25 @@ "node": ">=6" } }, + "node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/parse-static-imports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/parse-static-imports/-/parse-static-imports-1.1.0.tgz", @@ -6984,7 +7621,6 @@ "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "license": "MIT", - "peer": true, "bin": { "prettier": "bin-prettier.js" }, @@ -7149,6 +7785,16 @@ ], "license": "MIT" }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/quick-temp": { "version": "0.1.9", "resolved": "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.9.tgz", @@ -7242,6 +7888,146 @@ "dev": true, "license": "MIT" }, + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "license": "MIT", + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "license": "MIT", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, + "node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, + "node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/read-pkg/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=8" + } + }, "node_modules/readable-stream": { "version": "3.6.2", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", @@ -7270,6 +8056,20 @@ "node": ">=8.10.0" } }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "license": "MIT", + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/reduce-flatten": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/reduce-flatten/-/reduce-flatten-2.0.0.tgz", @@ -8013,6 +8813,42 @@ "dev": true, "license": "MIT" }, + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", + "dev": true, + "license": "CC-BY-3.0" + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.23.tgz", + "integrity": "sha512-CWLcCCH7VLu13TgOH+r8p1O/Znwhqv/dbb6lqWy67G+pT1kHmeD/+V36AVb/vq8QMIQwVShJ6Ssl5FPh0fuSdw==", + "dev": true, + "license": "CC0-1.0" + }, "node_modules/sprintf-js": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", @@ -8276,6 +9112,19 @@ "node": ">=8" } }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8388,6 +9237,19 @@ "node": ">=8" } }, + "node_modules/tagged-tag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tagged-tag/-/tagged-tag-1.0.0.tgz", + "integrity": "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8490,6 +9352,16 @@ "matcher-collection": "^1.0.0" } }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/tslib": { "version": "2.8.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", @@ -8664,7 +9536,6 @@ "integrity": "sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==", "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8781,6 +9652,27 @@ "dev": true, "license": "MIT" }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-6.0.0.tgz", + "integrity": "sha512-d7KLgL1LD3U3fgnvWEY1cQXoO/q6EQ1BSz48Sa149V/5zVTAbgmZIpyI8TRi6U9/JNyeYLlTKsEMPtLC27RFUg==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^18.17.0 || >=20.5.0" + } + }, "node_modules/validate-peer-dependencies": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/validate-peer-dependencies/-/validate-peer-dependencies-1.2.0.tgz", diff --git a/package.json b/package.json index a6745b4fa..177709893 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "dev": "node tests/server.mjs", "lint:check": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\"", "lint:fix": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\" --fix", + "lint:pkg": "npm-package-json-lint \"**/package.json\" --ignore-pattern \"**/node_modules/**\"", "pretty:check": "prettier --check ./", "pretty:fix": "prettier --write ./", "format": "node tests/format.mjs", @@ -55,6 +56,9 @@ "lws-log": "^3.0.0", "lws-static": "^3.1.1", "mocha": "^10.2.0", + "normalize-package-data": "^8.0.0", + "npm-package-json-lint": "^10.4.1", + "npm-package-json-lint-config-default": "^9.0.1", "prettier": "^2.8.3", "prettier-plugin-tailwindcss": "^0.4.1", "selenium-webdriver": "^4.44.0", diff --git a/suites/newssite/news-nuxt/package.json b/suites/newssite/news-nuxt/package.json index 85df82795..2a6807cd2 100644 --- a/suites/newssite/news-nuxt/package.json +++ b/suites/newssite/news-nuxt/package.json @@ -1,5 +1,6 @@ { "name": "nuxt-app", + "version": "1.0.0", "private": true, "scripts": { "build": "node scripts/build.mjs", diff --git a/suites/react-stockcharts/package.json b/suites/react-stockcharts/package.json index 9b7540b65..e611a3c23 100644 --- a/suites/react-stockcharts/package.json +++ b/suites/react-stockcharts/package.json @@ -1,5 +1,6 @@ { "name": "react-stockcharts-bench", + "version": "1.0.0", "private": true, "scripts": { "start": "react-scripts start", diff --git a/suites/todomvc/architecture-examples/jquery-complex/package.json b/suites/todomvc/architecture-examples/jquery-complex/package.json index d635cde0d..c8e2638d3 100644 --- a/suites/todomvc/architecture-examples/jquery-complex/package.json +++ b/suites/todomvc/architecture-examples/jquery-complex/package.json @@ -1,5 +1,6 @@ { "name": "todomvc-jquery-complex", + "version": "1.0.0", "private": true, "scripts": { "build": "node scripts/build.mjs", diff --git a/suites/todomvc/architecture-examples/jquery/package.json b/suites/todomvc/architecture-examples/jquery/package.json index 910d0e360..6da33b0fc 100644 --- a/suites/todomvc/architecture-examples/jquery/package.json +++ b/suites/todomvc/architecture-examples/jquery/package.json @@ -1,5 +1,6 @@ { "name": "todomvc-jquery", + "version": "1.0.0", "private": true, "scripts": { "dev": "http-server . -p 7001 -c-1 --cors", diff --git a/suites/todomvc/architecture-examples/lit-complex/package.json b/suites/todomvc/architecture-examples/lit-complex/package.json index 23768a674..14c2dd7dc 100644 --- a/suites/todomvc/architecture-examples/lit-complex/package.json +++ b/suites/todomvc/architecture-examples/lit-complex/package.json @@ -1,5 +1,6 @@ { "name": "lit-complex", + "version": "1.0.0", "private": true, "engines": { "node": ">=24.0.0", diff --git a/suites/todomvc/architecture-examples/lit/package.json b/suites/todomvc/architecture-examples/lit/package.json index 7c90c90b7..e22922394 100644 --- a/suites/todomvc/architecture-examples/lit/package.json +++ b/suites/todomvc/architecture-examples/lit/package.json @@ -1,5 +1,6 @@ { "name": "todomvc-lit", + "version": "1.0.0", "private": true, "type": "module", "engines": { diff --git a/tests/setup-node.mjs b/tests/setup-node.mjs index 35dae8cbf..ea8082cf7 100644 --- a/tests/setup-node.mjs +++ b/tests/setup-node.mjs @@ -1,8 +1,26 @@ import expect from "expect.js"; import sinon from "sinon"; +import { execSync } from "node:child_process"; +import path from "node:path"; +import { fileURLToPath } from "node:url"; + +const __filename = fileURLToPath(import.meta.url); +const __dirname = path.dirname(__filename); +export const ROOT_DIR = path.resolve(__dirname, "../"); + +export function sh(command, options = {}) { + return execSync(command, { + cwd: ROOT_DIR, + encoding: "utf-8", + stdio: ["ignore", "pipe", "ignore"], + ...options, + }); +} globalThis.expect = expect; globalThis.sinon = sinon; +globalThis.sh = sh; +globalThis.ROOT_DIR = ROOT_DIR; export const mochaHooks = { afterEach() { From b718c72372bf8e1da2dc7a4b673ee9004c9a5eb6 Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Thu, 16 Jul 2026 10:44:38 +0200 Subject: [PATCH 2/6] add --- .npmpackagejsonlintrc.json | 3 + tests/unittests/metric.mjs | 139 +++++++++++++++++++++++++++++++ tests/unittests/package-json.mjs | 71 ++++++++++++++++ tests/unittests/translations.mjs | 72 ++++++++++++++++ 4 files changed, 285 insertions(+) create mode 100644 .npmpackagejsonlintrc.json create mode 100644 tests/unittests/metric.mjs create mode 100644 tests/unittests/package-json.mjs create mode 100644 tests/unittests/translations.mjs diff --git a/.npmpackagejsonlintrc.json b/.npmpackagejsonlintrc.json new file mode 100644 index 000000000..800e07b4f --- /dev/null +++ b/.npmpackagejsonlintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "npm-package-json-lint-config-default" +} diff --git a/tests/unittests/metric.mjs b/tests/unittests/metric.mjs new file mode 100644 index 000000000..637e35079 --- /dev/null +++ b/tests/unittests/metric.mjs @@ -0,0 +1,139 @@ +import expect from "expect.js"; +import { Metric, MILLISECONDS_PER_MINUTE } from "../../resources/metric.mjs"; + +describe("Metric (Data Trees & Serialization)", () => { + describe("constructor & property enumeration", () => { + it("should initialize with required string name and default 'ms' unit", () => { + const metric = new Metric("test-metric"); + expect(metric.name).to.be("test-metric"); + expect(metric.unit).to.be("ms"); + expect(metric.description).to.be(""); + expect(metric.values).to.eql([]); + expect(metric.mean).to.be(0); + expect(metric.delta).to.be(0); + expect(metric.percentDelta).to.be(0); + }); + + it("should accept custom unit strings", () => { + const metric = new Metric("score-metric", "score"); + expect(metric.unit).to.be("score"); + }); + + it("should throw an Error if name is not a string", () => { + expect(() => new Metric(123)).to.throwError(/Invalid metric\.name=123, expected string/); + expect(() => new Metric()).to.throwError(/Invalid metric\.name=undefined, expected string/); + }); + + it("should define geomean, parent, and children as non-enumerable properties to prevent JSON.stringify circular reference crashes", () => { + const root = new Metric("Root"); + const child = new Metric("Root-Child"); + root.addChild(child); + + expect(root.geomean).to.be(0); + expect(root.children).to.contain(child); + expect(child.parent).to.be(root); + + const enumeratedKeys = Object.keys(root); + expect(enumeratedKeys).not.to.contain("geomean"); + expect(enumeratedKeys).not.to.contain("parent"); + expect(enumeratedKeys).not.to.contain("children"); + + expect(() => JSON.stringify(root)).not.to.throwError(); + const serialized = JSON.parse(JSON.stringify(root)); + expect(serialized.name).to.be("Root"); + expect(serialized.geomean).to.be(undefined); + expect(serialized.parent).to.be(undefined); + expect(serialized.children).to.be(undefined); + }); + }); + + describe("shortName", () => { + it("should return the full name when no parent is set", () => { + const metric = new Metric("Suite-Test"); + expect(metric.shortName).to.be("Suite-Test"); + }); + + it("should strip the parent name prefix when parent is set", () => { + const parent = new Metric("Suite"); + const child = new Metric("Suite-Test"); + parent.addChild(child); + expect(child.shortName).to.be("Test"); + }); + }); + + describe("valueString & deltaString", () => { + it("should format mean and unit when delta or percentDelta is zero", () => { + const metric = new Metric("Test"); + metric.mean = 10.5; + metric.delta = 0; + metric.percentDelta = 0; + expect(metric.valueString).to.be("10.50 ms"); + expect(metric.deltaString).to.be(""); + }); + + it("should format mean, delta, percentDelta, and unit when confidence intervals are computed", () => { + const metric = new Metric("Test"); + metric.mean = 100.0; + metric.delta = 2.5; + metric.percentDelta = 2.5; + expect(metric.deltaString).to.be("2.50 (2.5%)"); + expect(metric.valueString).to.be("100.00 ± 2.50 (2.5%) ms"); + }); + }); + + describe("add() & addChild()", () => { + it("should add valid numeric values and update length", () => { + const metric = new Metric("Test"); + metric.add(15); + metric.add(25); + expect(metric.values).to.eql([15, 25]); + expect(metric.length).to.be(2); + }); + + it("should throw when adding non-numeric values", () => { + const metric = new Metric("Test"); + expect(() => metric.add("not a number")).to.throwError(/Adding invalid value=not a number to metric=Test/); + }); + + it("should throw when re-adding a metric that already has a parent", () => { + const parent1 = new Metric("Parent1"); + const parent2 = new Metric("Parent2"); + const child = new Metric("Child"); + parent1.addChild(child); + expect(() => parent2.addChild(child)).to.throwError(/Cannot re-add sub metric/); + }); + }); + + describe("computeAggregatedMetrics()", () => { + it("should correctly compute sum, min, max, mean, and geomean for numeric samples", () => { + const metric = new Metric("Test"); + metric.add(10); + metric.add(20); + metric.add(30); + metric.computeAggregatedMetrics(); + + expect(metric.sum).to.be(60); + expect(metric.min).to.be(10); + expect(metric.max).to.be(30); + expect(metric.mean).to.be(20); + // Geomean of (10, 20, 30) = (6000)^(1/3) ~ 18.1712 + expect(metric.geomean).to.be.within(18.17, 18.18); + expect(metric.delta).to.be.a("number"); + expect(metric.percentDelta).to.be.a("number"); + }); + + it("should handle single sample without confidence intervals", () => { + const metric = new Metric("Single"); + metric.add(42); + metric.computeAggregatedMetrics(); + + expect(metric.sum).to.be(42); + expect(metric.min).to.be(42); + expect(metric.max).to.be(42); + expect(metric.mean).to.be(42); + expect(metric.geomean).to.be(42); + expect(metric.delta).to.be(0); + expect(metric.percentDelta).to.be(0); + }); + }); +}); diff --git a/tests/unittests/package-json.mjs b/tests/unittests/package-json.mjs new file mode 100644 index 000000000..f0c359f9b --- /dev/null +++ b/tests/unittests/package-json.mjs @@ -0,0 +1,71 @@ +import expect from "expect.js"; +import fs from "node:fs/promises"; +import path from "node:path"; +import normalize from "normalize-package-data"; +import { sh, ROOT_DIR } from "../setup-node.mjs"; + +function getCheckedInPackageJsonFiles() { + const output = sh('git ls-files -- ":**/*package.json" "package.json"'); + const files = output + .trim() + .split("\n") + .filter(Boolean) + .map((relativePath) => path.resolve(ROOT_DIR, relativePath)); + return files.sort(); +} + +function assertPkg(relPath, condition, message) { + if (!condition) { + throw new Error(`[${relPath}] ${message}`); + } +} + +describe("package.json validation", () => { + let packages = []; + + before(async () => { + const packageFiles = getCheckedInPackageJsonFiles(); + expect(packageFiles).to.be.an("array"); + expect(packageFiles.length).to.be.greaterThan(0, "Should find at least one checked-in package.json file"); + + packages = await Promise.all( + packageFiles.map(async (file) => { + const relPath = path.relative(ROOT_DIR, file); + const content = await fs.readFile(file, "utf-8"); + let pkg = null; + let parseError = null; + try { + pkg = JSON.parse(content); + } catch (e) { + parseError = e.message; + } + return { file, relPath, content, pkg, parseError }; + }) + ); + }); + + it("should contain valid JSON syntax for all checked-in package.json files", () => { + for (const { relPath, parseError } of packages) { + assertPkg(relPath, parseError === null, `Failed to parse JSON: ${parseError}`); + } + }); + + it("should pass normalize-package-data schema validation when present", () => { + for (const { relPath, pkg } of packages) { + if (!pkg) continue; + const clone = structuredClone(pkg); + let normalizeError = null; + try { + normalize(clone, true); + } catch (e) { + normalizeError = e.message; + } + assertPkg(relPath, normalizeError === null, `normalize-package-data error: ${normalizeError}`); + + if (clone.warnings && clone.warnings.length > 0) { + const criticalWarnings = clone.warnings.filter((w) => !w.includes("No repository field") && !w.includes("No README data") && !w.includes("No license field")); + assertPkg(relPath, criticalWarnings.length === 0, `normalize-package-data warnings: ${criticalWarnings.join("; ")}`); + } + } + }); +}); diff --git a/tests/unittests/translations.mjs b/tests/unittests/translations.mjs new file mode 100644 index 000000000..a535d52bf --- /dev/null +++ b/tests/unittests/translations.mjs @@ -0,0 +1,72 @@ +import expect from "expect.js"; +import { todos, defaultTodoText, defaultLanguage, getTodoText } from "../../resources/shared/translations.mjs"; + +describe("Translations & Localization (`resources/shared/translations.mjs`)", () => { + const supportedLanguages = ["en", "zh-cn", "ja", "es", "de", "ru", "emoji"]; + + describe("todos dictionary integrity", () => { + it("should contain all supported language keys", () => { + expect(typeof todos).to.be("object"); + expect(todos).not.to.be(null); + for (const lang of supportedLanguages) { + expect(todos).to.have.property(lang); + expect(Array.isArray(todos[lang])).to.be(true, `Expected array for language ${lang}`); + } + }); + + it("should have identical dictionary lengths across all supported languages (1-to-1 symmetry)", () => { + const baseLength = todos.en.length; + expect(baseLength).to.be.greaterThan(0); + + for (const lang of supportedLanguages) { + expect(todos[lang].length).to.be(baseLength, `Expected language '${lang}' to have exactly ${baseLength} translations, found ${todos[lang].length}`); + } + }); + + it("should contain only valid non-empty strings in all dictionaries", () => { + for (const lang of supportedLanguages) { + for (let i = 0; i < todos[lang].length; i++) { + const text = todos[lang][i]; + expect(text).to.be.a("string", `Expected string at index ${i} for language '${lang}'`); + expect(text.trim().length).to.be.greaterThan(0, `Found empty string at index ${i} for language '${lang}'`); + } + } + }); + }); + + describe("defaultTodoText dictionary", () => { + it("should provide default text strings for all supported languages", () => { + expect(typeof defaultTodoText).to.be("object"); + for (const lang of supportedLanguages) { + expect(defaultTodoText).to.have.property(lang); + expect(defaultTodoText[lang]).to.be.a("string"); + expect(defaultTodoText[lang].trim().length).to.be.greaterThan(0); + } + }); + }); + + describe("defaultLanguage", () => { + it("should export 'en' as defaultLanguage", () => { + expect(defaultLanguage).to.be("en"); + }); + }); + + describe("getTodoText() helper", () => { + it("should return exact todo item when index is within bounds", () => { + expect(getTodoText("en", 0)).to.be(todos.en[0]); + expect(getTodoText("ja", 5)).to.be(todos.ja[5]); + expect(getTodoText("de", 10)).to.be(todos.de[10]); + }); + + it("should wrap index modulo dictionary length when index exceeds length", () => { + const len = todos.en.length; + expect(getTodoText("en", len)).to.be(todos.en[0]); + expect(getTodoText("en", len + 3)).to.be(todos.en[3]); + expect(getTodoText("es", len * 2 + 7)).to.be(todos.es[7]); + }); + + it("should fall back to 'en' when lang parameter is not passed or undefined", () => { + expect(getTodoText(undefined, 2)).to.be(todos.en[2]); + }); + }); +}); From 5054b99c58acb11248ba0d630f5617a157527a23 Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Thu, 16 Jul 2026 10:49:48 +0200 Subject: [PATCH 3/6] format --- tests/unittests/package-json.mjs | 11 ++++++----- tests/unittests/translations.mjs | 4 ++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/tests/unittests/package-json.mjs b/tests/unittests/package-json.mjs index f0c359f9b..b72abb6cd 100644 --- a/tests/unittests/package-json.mjs +++ b/tests/unittests/package-json.mjs @@ -15,9 +15,9 @@ function getCheckedInPackageJsonFiles() { } function assertPkg(relPath, condition, message) { - if (!condition) { + if (!condition) throw new Error(`[${relPath}] ${message}`); - } + } describe("package.json validation", () => { @@ -45,14 +45,15 @@ describe("package.json validation", () => { }); it("should contain valid JSON syntax for all checked-in package.json files", () => { - for (const { relPath, parseError } of packages) { + for (const { relPath, parseError } of packages) assertPkg(relPath, parseError === null, `Failed to parse JSON: ${parseError}`); - } + }); it("should pass normalize-package-data schema validation when present", () => { for (const { relPath, pkg } of packages) { - if (!pkg) continue; + if (!pkg) + continue; const clone = structuredClone(pkg); let normalizeError = null; try { diff --git a/tests/unittests/translations.mjs b/tests/unittests/translations.mjs index a535d52bf..0aa31c073 100644 --- a/tests/unittests/translations.mjs +++ b/tests/unittests/translations.mjs @@ -18,9 +18,9 @@ describe("Translations & Localization (`resources/shared/translations.mjs`)", () const baseLength = todos.en.length; expect(baseLength).to.be.greaterThan(0); - for (const lang of supportedLanguages) { + for (const lang of supportedLanguages) expect(todos[lang].length).to.be(baseLength, `Expected language '${lang}' to have exactly ${baseLength} translations, found ${todos[lang].length}`); - } + }); it("should contain only valid non-empty strings in all dictionaries", () => { From 405710b27aa3375e95315cbae059d80d83d34382 Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Thu, 16 Jul 2026 10:56:08 +0200 Subject: [PATCH 4/6] fx --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 177709893..5a4f6a0cf 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "dev": "node tests/server.mjs", "lint:check": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\"", "lint:fix": "eslint \"**/*.{js,mjs,jsx,ts,tsx}\" --fix", - "lint:pkg": "npm-package-json-lint \"**/package.json\" --ignore-pattern \"**/node_modules/**\"", + "lint:pkg": "npmPkgJsonLint \"**/package.json\" --ignore-pattern \"**/node_modules/**\"", "pretty:check": "prettier --check ./", "pretty:fix": "prettier --write ./", "format": "node tests/format.mjs", From 0014c2a1c6549fad6f17503ed55747434a76cbfe Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Thu, 16 Jul 2026 11:30:14 +0200 Subject: [PATCH 5/6] formatting --- tests/unittests/metric.mjs | 2 +- tests/unittests/package-json.mjs | 2 -- tests/unittests/translations.mjs | 1 - 3 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/unittests/metric.mjs b/tests/unittests/metric.mjs index 637e35079..a2c1fd7c0 100644 --- a/tests/unittests/metric.mjs +++ b/tests/unittests/metric.mjs @@ -1,5 +1,5 @@ import expect from "expect.js"; -import { Metric, MILLISECONDS_PER_MINUTE } from "../../resources/metric.mjs"; +import { Metric } from "../../resources/metric.mjs"; describe("Metric (Data Trees & Serialization)", () => { describe("constructor & property enumeration", () => { diff --git a/tests/unittests/package-json.mjs b/tests/unittests/package-json.mjs index b72abb6cd..927c63f18 100644 --- a/tests/unittests/package-json.mjs +++ b/tests/unittests/package-json.mjs @@ -17,7 +17,6 @@ function getCheckedInPackageJsonFiles() { function assertPkg(relPath, condition, message) { if (!condition) throw new Error(`[${relPath}] ${message}`); - } describe("package.json validation", () => { @@ -47,7 +46,6 @@ describe("package.json validation", () => { it("should contain valid JSON syntax for all checked-in package.json files", () => { for (const { relPath, parseError } of packages) assertPkg(relPath, parseError === null, `Failed to parse JSON: ${parseError}`); - }); it("should pass normalize-package-data schema validation when present", () => { diff --git a/tests/unittests/translations.mjs b/tests/unittests/translations.mjs index 0aa31c073..ca3d16e7a 100644 --- a/tests/unittests/translations.mjs +++ b/tests/unittests/translations.mjs @@ -20,7 +20,6 @@ describe("Translations & Localization (`resources/shared/translations.mjs`)", () for (const lang of supportedLanguages) expect(todos[lang].length).to.be(baseLength, `Expected language '${lang}' to have exactly ${baseLength} translations, found ${todos[lang].length}`); - }); it("should contain only valid non-empty strings in all dictionaries", () => { From 35823c6dc5c5dd4a6865a9ccaadb409e27bc776d Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Thu, 16 Jul 2026 11:36:38 +0200 Subject: [PATCH 6/6] fx --- tests/unittests/package-json.mjs | 70 -------------------------------- 1 file changed, 70 deletions(-) delete mode 100644 tests/unittests/package-json.mjs diff --git a/tests/unittests/package-json.mjs b/tests/unittests/package-json.mjs deleted file mode 100644 index 927c63f18..000000000 --- a/tests/unittests/package-json.mjs +++ /dev/null @@ -1,70 +0,0 @@ -import expect from "expect.js"; -import fs from "node:fs/promises"; -import path from "node:path"; -import normalize from "normalize-package-data"; -import { sh, ROOT_DIR } from "../setup-node.mjs"; - -function getCheckedInPackageJsonFiles() { - const output = sh('git ls-files -- ":**/*package.json" "package.json"'); - const files = output - .trim() - .split("\n") - .filter(Boolean) - .map((relativePath) => path.resolve(ROOT_DIR, relativePath)); - return files.sort(); -} - -function assertPkg(relPath, condition, message) { - if (!condition) - throw new Error(`[${relPath}] ${message}`); -} - -describe("package.json validation", () => { - let packages = []; - - before(async () => { - const packageFiles = getCheckedInPackageJsonFiles(); - expect(packageFiles).to.be.an("array"); - expect(packageFiles.length).to.be.greaterThan(0, "Should find at least one checked-in package.json file"); - - packages = await Promise.all( - packageFiles.map(async (file) => { - const relPath = path.relative(ROOT_DIR, file); - const content = await fs.readFile(file, "utf-8"); - let pkg = null; - let parseError = null; - try { - pkg = JSON.parse(content); - } catch (e) { - parseError = e.message; - } - return { file, relPath, content, pkg, parseError }; - }) - ); - }); - - it("should contain valid JSON syntax for all checked-in package.json files", () => { - for (const { relPath, parseError } of packages) - assertPkg(relPath, parseError === null, `Failed to parse JSON: ${parseError}`); - }); - - it("should pass normalize-package-data schema validation when present", () => { - for (const { relPath, pkg } of packages) { - if (!pkg) - continue; - const clone = structuredClone(pkg); - let normalizeError = null; - try { - normalize(clone, true); - } catch (e) { - normalizeError = e.message; - } - assertPkg(relPath, normalizeError === null, `normalize-package-data error: ${normalizeError}`); - - if (clone.warnings && clone.warnings.length > 0) { - const criticalWarnings = clone.warnings.filter((w) => !w.includes("No repository field") && !w.includes("No README data") && !w.includes("No license field")); - assertPkg(relPath, criticalWarnings.length === 0, `normalize-package-data warnings: ${criticalWarnings.join("; ")}`); - } - } - }); -});