From 91eb41bbe8e4ad5c6ff02be42efeadca4e66fe78 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Thu, 9 Jul 2026 14:49:01 -0400 Subject: [PATCH 1/5] Modernize Node support and unit tests --- .github/workflows/publish-npm.yaml | 6 - .github/workflows/publish-vscode.yaml | 6 - .github/workflows/setup/action.yaml | 10 +- .github/workflows/test-pr.yaml | 14 +- .nvmrc | 2 +- AGENTS.md | 27 +- MIGRATING.md | 17 + README.md | 2 + package-lock.json | 2097 ++++++++++++++--- package.json | 29 +- packages/quicktype-core/package.json | 17 +- .../quicktype-core/src/input/io/$fetch.ts | 11 - .../quicktype-core/src/input/io/NodeIO.ts | 10 +- packages/quicktype-graphql-input/package.json | 9 +- .../quicktype-typescript-input/package.json | 9 +- packages/quicktype-vscode/package.json | 8 +- src/GraphQLIntrospection.ts | 12 +- test/check-clean-import.ts | 42 - test/check-java-acronym-names.ts | 105 - test/check-no-node-imports.ts | 76 - test/check-url-input.ts | 141 -- test/fixtures/javascript-prop-types/main.js | 26 +- .../javascript-prop-types/package-lock.json | 413 +--- .../javascript-prop-types/package.json | 2 +- test/test.ts | 43 +- test/tsconfig.json | 4 +- test/unit/core-package.test.ts | 53 + test/unit/graphql-introspection.test.ts | 73 + test/unit/java-acronym-names.test.ts | 48 + test/unit/url-input.test.ts | 99 + tsconfig.json | 2 +- vitest.config.ts | 9 + 32 files changed, 2289 insertions(+), 1133 deletions(-) create mode 100644 MIGRATING.md delete mode 100644 packages/quicktype-core/src/input/io/$fetch.ts delete mode 100644 test/check-clean-import.ts delete mode 100644 test/check-java-acronym-names.ts delete mode 100644 test/check-no-node-imports.ts delete mode 100644 test/check-url-input.ts create mode 100644 test/unit/core-package.test.ts create mode 100644 test/unit/graphql-introspection.test.ts create mode 100644 test/unit/java-acronym-names.test.ts create mode 100644 test/unit/url-input.test.ts create mode 100644 vitest.config.ts diff --git a/.github/workflows/publish-npm.yaml b/.github/workflows/publish-npm.yaml index 468c3b8fe3..6193c34915 100644 --- a/.github/workflows/publish-npm.yaml +++ b/.github/workflows/publish-npm.yaml @@ -7,12 +7,6 @@ on: jobs: publish-npm: runs-on: ubuntu-22.04 - env: - # quicktype-core's build (packages/quicktype-core/env.sh) swaps in - # a CI-only fetch shim whenever $CI is set — which GitHub Actions - # always sets. PUBLISH=true makes it skip that swap so releases - # ship the real $fetch (issue #2874). - PUBLISH: "true" permissions: # Required for npm Trusted Publishing (OIDC): npm mints # short-lived, per-run credentials from this token instead diff --git a/.github/workflows/publish-vscode.yaml b/.github/workflows/publish-vscode.yaml index e30346fa55..b08a386d50 100644 --- a/.github/workflows/publish-vscode.yaml +++ b/.github/workflows/publish-vscode.yaml @@ -7,12 +7,6 @@ on: jobs: publish-vscode: runs-on: ubuntu-22.04 - env: - # quicktype-core's build (packages/quicktype-core/env.sh) swaps in - # a CI-only fetch shim whenever $CI is set — which GitHub Actions - # always sets. PUBLISH=true makes it skip that swap so the bundled - # extension ships the real $fetch (issue #2874). - PUBLISH: "true" steps: - uses: actions/checkout@v3 - uses: ./.github/workflows/setup diff --git a/.github/workflows/setup/action.yaml b/.github/workflows/setup/action.yaml index 6eb9375109..db864c513e 100644 --- a/.github/workflows/setup/action.yaml +++ b/.github/workflows/setup/action.yaml @@ -1,12 +1,20 @@ name: Setup description: Setup common stuff for jobs +inputs: + node-version: + description: Node.js version to install; defaults to .nvmrc + required: false + default: "" runs: using: "composite" steps: - name: Setup environment shell: bash run: | - NODE_VERSION=$(cat .nvmrc | xargs) + NODE_VERSION="${{ inputs.node-version }}" + if [[ -z "$NODE_VERSION" ]]; then + NODE_VERSION=$(cat .nvmrc | xargs) + fi echo "node_version=$NODE_VERSION" >> $GITHUB_ENV # Create keys to control caching diff --git a/.github/workflows/test-pr.yaml b/.github/workflows/test-pr.yaml index 6f67d78118..2158202e87 100644 --- a/.github/workflows/test-pr.yaml +++ b/.github/workflows/test-pr.yaml @@ -6,10 +6,22 @@ on: - "release/**" jobs: build: + name: Build and unit tests (Node ${{ matrix.node-version }}) runs-on: ubuntu-22.04 + strategy: + fail-fast: false + matrix: + node-version: ["20", "24"] steps: - uses: actions/checkout@v3 - uses: ./.github/workflows/setup + with: + node-version: ${{ matrix.node-version }} + - run: npm run test:unit + - run: node dist/index.js --version + - name: Run representative fixtures on the minimum Node version + if: ${{ matrix.node-version == '20' }} + run: CPUs=2 QUICKTEST=true FIXTURE=javascript,typescript npm run test:fixtures -- test/inputs/json/samples/pokedex.json test: needs: [build] @@ -189,7 +201,7 @@ jobs: elixir-version: "1.15.7" otp-version: "26.0" - - run: QUICKTEST=true FIXTURE=${{ matrix.fixture }} npm test + - run: QUICKTEST=true FIXTURE=${{ matrix.fixture }} npm run test:fixtures test-complete: if: ${{ cancelled() || contains(needs.*.result, 'cancelled') || contains(needs.*.result, 'failure') }} diff --git a/.nvmrc b/.nvmrc index 517f38666b..fa3adfb744 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v22.14.0 +v24.6.0 diff --git a/AGENTS.md b/AGENTS.md index f0ba64eaaf..79d83a6966 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,7 +5,7 @@ Notes for coding agents working in this repository. ## Environment - This is a TypeScript/npm monorepo using npm workspaces. -- Prefer the Node version from `.nvmrc` (`nvm use`; currently Node 22.14.0). `package.json` requires Node >= 18.12.0. +- Prefer the Node version from `.nvmrc` (`nvm use`; currently Node 24.6.0). Published packages support Node >= 20. - Install dependencies with `npm ci`. ## Build and run @@ -29,25 +29,34 @@ Notes for coding agents working in this repository. ## Tests -- The test runner is `script/test`, exposed as: +- Vitest runs the standalone unit and regression tests: ```bash - npm test + npm run test:unit + npm run test:unit:watch ``` +- The cross-language fixture runner remains `script/test`, exposed as: + + ```bash + npm run test:fixtures + ``` + +- `npm test` runs the Vitest suite followed by the fixture suite. + - The full suite runs all fixtures and needs external language toolchains for many targets (`dotnet`, Java/Maven, Go, Rust, Python/mypy, PHP, Ruby, Kotlin, Scala, Elixir, etc.). On a machine without those tools, plain `npm test` will fail when it reaches the first missing toolchain. - For local focused testing, use fixture filters. Fixture names are in `test/languages.ts` and `test/fixtures.ts`; comma-separated fixture groups are supported: ```bash - QUICKTEST=true FIXTURE=javascript npm test - QUICKTEST=true FIXTURE=typescript npm test -- test/inputs/json/samples/pokedex.json - CPUs=2 QUICKTEST=true FIXTURE=javascript npm test + QUICKTEST=true FIXTURE=javascript npm run test:fixtures + QUICKTEST=true FIXTURE=typescript npm run test:fixtures -- test/inputs/json/samples/pokedex.json + CPUs=2 QUICKTEST=true FIXTURE=javascript npm run test:fixtures ``` `QUICKTEST=true` skips the large miscellaneous JSON input set. Extra arguments after `--` are sample files or directories to run. -- GitHub Actions uses the same pattern, e.g. `QUICKTEST=true FIXTURE=${{ matrix.fixture }} npm test`, after installing toolchain dependencies for each fixture group in `.github/workflows/test-pr.yaml`. +- GitHub Actions uses the same pattern, e.g. `QUICKTEST=true FIXTURE=${{ matrix.fixture }} npm run test:fixtures`, after installing toolchain dependencies for each fixture group in `.github/workflows/test-pr.yaml`. ## Validation performed @@ -57,8 +66,8 @@ The following commands were run successfully in this workspace: npm ci npm run build node dist/index.js --version -CPUs=2 QUICKTEST=true FIXTURE=javascript npm test -QUICKTEST=true FIXTURE=typescript npm test -- test/inputs/json/samples/pokedex.json +CPUs=2 QUICKTEST=true FIXTURE=javascript npm run test:fixtures +QUICKTEST=true FIXTURE=typescript npm run test:fixtures -- test/inputs/json/samples/pokedex.json ``` Also observed: `npm test` without fixture filters started the full 70-fixture suite and failed on this machine because `dotnet` is not installed. `npm run lint` currently fails because ESLint cannot find a configuration file. diff --git a/MIGRATING.md b/MIGRATING.md new file mode 100644 index 0000000000..99dc86e77e --- /dev/null +++ b/MIGRATING.md @@ -0,0 +1,17 @@ +# Migrating to quicktype 24 + +quicktype 24 raises the minimum supported Node.js version to Node 20. The +project itself is built, tested, and published with Node 24, while CI also +builds and tests the supported Node 20 floor. + +The CLI and published libraries now use the native `fetch` implementation +provided by Node.js and modern browsers. Applications running quicktype on a +supported Node.js version do not need to install or configure a fetch +polyfill. + +There are no intentional changes to generated code or the public quicktype +API in this release. TypeScript compiler versions are also unchanged. + +For contributors, `npm run test:unit` runs the Vitest regression suite and +`npm run test:fixtures` runs the cross-language fixture harness. `npm test` +runs both suites. diff --git a/README.md b/README.md index 9d9fcbbf97..46946907fc 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,8 @@ _Missing your favorite language? Please implement it!_ There are many ways to use `quicktype`. [app.quicktype.io](https://app.quicktype.io) is the most powerful and complete UI. The web app also works offline and doesn't send your sample data over the Internet, so paste away! +The quicktype CLI and Node.js packages require Node.js 20 or newer. + For the best CLI, we recommend installing `quicktype` globally via `npm`: ```bash diff --git a/package-lock.json b/package-lock.json index cfb5608069..47a4f4fe76 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "quicktype", - "version": "23.3.0", + "version": "24.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "quicktype", - "version": "23.3.0", + "version": "24.0.0", "license": "Apache-2.0", "workspaces": [ "./packages/quicktype-core", @@ -20,13 +20,12 @@ "collection-utils": "^1.0.1", "command-line-args": "^5.2.1", "command-line-usage": "^7.0.1", - "cross-fetch": "^4.0.0", "graphql": "^0.11.7", "lodash": "^4.17.21", "moment": "^2.30.1", - "quicktype-core": "20.0.12", - "quicktype-graphql-input": "20.0.2", - "quicktype-typescript-input": "20.0.2", + "quicktype-core": "24.0.0", + "quicktype-graphql-input": "24.0.0", + "quicktype-typescript-input": "24.0.0", "readable-stream": "^4.5.2", "stream-json": "1.8.0", "string-to-stream": "^3.0.1", @@ -37,11 +36,12 @@ }, "devDependencies": { "@biomejs/biome": "^1.9.4", - "@tsconfig/node18": "^1.0.1", + "@tsconfig/node20": "^20.1.6", "@types/command-line-args": "^5.2.0", "@types/command-line-usage": "^5.0.4", "@types/graphql": "^0.11.7", "@types/lodash": "^4.17.0", + "@types/node": "~20.19.0", "@types/semver": "^7.5.0", "@types/shelljs": "^0.8.15", "@types/stream-json": "^1.7.3", @@ -69,11 +69,12 @@ "tree-sitter-scala": "^0.24.0", "tree-sitter-typescript": "^0.23.2", "ts-node": "^10.9.2", + "vitest": "^4.1.10", "watch": "^1.0.2", "web-tree-sitter": "^0.26.9" }, "engines": { - "node": ">=18.12.0" + "node": ">=20.0.0" } }, "node_modules/@75lb/deep-merge": { @@ -281,6 +282,40 @@ "node": ">=12" } }, + "node_modules/@emnapi/core": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.11.1.tgz", + "integrity": "sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/wasi-threads": "1.2.2", + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/runtime": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@emnapi/wasi-threads": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.2.tgz", + "integrity": "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/win32-x64": { "version": "0.20.2", "cpu": [ @@ -528,7 +563,9 @@ } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { @@ -571,6 +608,25 @@ "node": ">=4.2.0" } }, + "node_modules/@napi-rs/wasm-runtime": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "dev": true, @@ -603,6 +659,16 @@ "node": ">= 8" } }, + "node_modules/@oxc-project/types": { + "version": "0.139.0", + "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.139.0.tgz", + "integrity": "sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/Boshen" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "dev": true, @@ -612,6 +678,277 @@ "node": ">=14" } }, + "node_modules/@rolldown/binding-android-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.1.5.tgz", + "integrity": "sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.1.5.tgz", + "integrity": "sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-darwin-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.1.5.tgz", + "integrity": "sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-freebsd-x64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.1.5.tgz", + "integrity": "sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm-gnueabihf": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.1.5.tgz", + "integrity": "sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.1.5.tgz", + "integrity": "sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-arm64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.1.5.tgz", + "integrity": "sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-ppc64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.1.5.tgz", + "integrity": "sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-s390x-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.1.5.tgz", + "integrity": "sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-gnu": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.1.5.tgz", + "integrity": "sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-linux-x64-musl": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.1.5.tgz", + "integrity": "sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-openharmony-arm64": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.1.5.tgz", + "integrity": "sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-wasm32-wasi": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.1.5.tgz", + "integrity": "sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "1.11.1", + "@emnapi/runtime": "1.11.1", + "@napi-rs/wasm-runtime": "^1.1.6" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-arm64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.1.5.tgz", + "integrity": "sha512-gHv82k63z4qpV5+Q1y/12KrK0ltWBukVDI8nZcbT7Tt/ZlOIVwppazneq0F93oDxTo3IgAMEDIoQh3E2n6mVsw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/binding-win32-x64-msvc": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.1.5.tgz", + "integrity": "sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@rolldown/pluginutils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.1.tgz", + "integrity": "sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@standard-schema/spec": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.1.0.tgz", + "integrity": "sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==", + "dev": true, + "license": "MIT" + }, "node_modules/@tootallnate/once": { "version": "1.1.2", "dev": true, @@ -636,16 +973,40 @@ "version": "1.0.3", "license": "MIT" }, - "node_modules/@tsconfig/node18": { - "version": "1.0.1", + "node_modules/@tsconfig/node20": { + "version": "20.1.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node20/-/node20-20.1.9.tgz", + "integrity": "sha512-IjlTv1RsvnPtUcjTqtVsZExKVq+KQx4g5pCP5tI7rAs6Xesl2qFwSz/tPDBC4JajkL/MlezBu3gPUwqRHl+RIg==", "dev": true, "license": "MIT" }, + "node_modules/@tybys/wasm-util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@types/browser-or-node": { "version": "1.3.2", "dev": true, "license": "MIT" }, + "node_modules/@types/chai": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" + } + }, "node_modules/@types/command-line-args": { "version": "5.2.0", "dev": true, @@ -656,6 +1017,20 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/deep-eql": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz", + "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/estree": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/glob": { "version": "7.2.0", "dev": true, @@ -702,9 +1077,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.14.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.1.tgz", - "integrity": "sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==", + "version": "20.19.43", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz", + "integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -775,6 +1150,7 @@ }, "node_modules/@types/urijs": { "version": "1.19.25", + "dev": true, "license": "MIT" }, "node_modules/@types/vscode": { @@ -1007,14 +1383,110 @@ "dev": true, "license": "ISC" }, - "node_modules/@vscode/test-cli": { - "version": "0.0.6", + "node_modules/@vitest/expect": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-4.1.10.tgz", + "integrity": "sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==", "dev": true, "license": "MIT", "dependencies": { - "@types/mocha": "^10.0.2", - "c8": "^9.1.0", - "chokidar": "^3.5.3", + "@standard-schema/spec": "^1.1.0", + "@types/chai": "^5.2.2", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "chai": "^6.2.2", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/pretty-format": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-4.1.10.tgz", + "integrity": "sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-4.1.10.tgz", + "integrity": "sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "4.1.10", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-4.1.10.tgz", + "integrity": "sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "@vitest/utils": "4.1.10", + "magic-string": "^0.30.21", + "pathe": "^2.0.3" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/@vitest/spy": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-4.1.10.tgz", + "integrity": "sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-4.1.10.tgz", + "integrity": "sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "4.1.10", + "convert-source-map": "^2.0.0", + "tinyrainbow": "^3.1.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vscode/test-cli": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/mocha": "^10.0.2", + "c8": "^9.1.0", + "chokidar": "^3.5.3", "enhanced-resolve": "^5.15.0", "glob": "^10.3.10", "minimatch": "^9.0.3", @@ -1301,6 +1773,16 @@ "node": ">=8" } }, + "node_modules/assertion-error": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz", + "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/asynckit": { "version": "0.4.0", "dev": true, @@ -1579,6 +2061,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/chai": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/chai/-/chai-6.2.2.tgz", + "integrity": "sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "4.1.2", "license": "MIT", @@ -1851,19 +2343,13 @@ }, "node_modules/core-util-is": { "version": "1.0.3", + "dev": true, "license": "MIT" }, "node_modules/create-require": { "version": "1.1.1", "license": "MIT" }, - "node_modules/cross-fetch": { - "version": "4.0.0", - "license": "MIT", - "dependencies": { - "node-fetch": "^2.6.12" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "dev": true, @@ -2039,7 +2525,6 @@ "version": "2.0.3", "dev": true, "license": "Apache-2.0", - "optional": true, "engines": { "node": ">=8" } @@ -2112,167 +2597,541 @@ "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/domutils": { - "version": "3.1.0", + "node_modules/domutils": { + "version": "3.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/duplexer2": { + "version": "0.1.4", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "readable-stream": "^2.0.2" + } + }, + "node_modules/duplexer2/node_modules/readable-stream": { + "version": "2.3.8", + "dev": true, + "license": "MIT", + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "dev": true, + "license": "MIT" + }, + "node_modules/emoji-regex": { + "version": "8.0.0", + "license": "MIT" + }, + "node_modules/end-of-stream": { + "version": "1.4.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "5.16.0", + "dev": true, + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/entities": { + "version": "4.5.0", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/es-define-property": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-get-iterator": { + "version": "1.1.3", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "is-arguments": "^1.1.1", + "is-map": "^2.0.2", + "is-set": "^2.0.2", + "is-string": "^1.0.7", + "isarray": "^2.0.5", + "stop-iteration-iterator": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-get-iterator/node_modules/isarray": { + "version": "2.0.5", + "dev": true, + "license": "MIT" + }, + "node_modules/es-module-lexer": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-2.3.0.tgz", + "integrity": "sha512-KLdwQm2NvGLDkQDCGvmiQrhkd0JbMzXthwQAUgWjQuQdBLFa3eiBP5arXZyA+f8x+x7OXgud6bq2rxjGtHV2tw==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.20.2", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.20.2", + "@esbuild/android-arm": "0.20.2", + "@esbuild/android-arm64": "0.20.2", + "@esbuild/android-x64": "0.20.2", + "@esbuild/darwin-arm64": "0.20.2", + "@esbuild/darwin-x64": "0.20.2", + "@esbuild/freebsd-arm64": "0.20.2", + "@esbuild/freebsd-x64": "0.20.2", + "@esbuild/linux-arm": "0.20.2", + "@esbuild/linux-arm64": "0.20.2", + "@esbuild/linux-ia32": "0.20.2", + "@esbuild/linux-loong64": "0.20.2", + "@esbuild/linux-mips64el": "0.20.2", + "@esbuild/linux-ppc64": "0.20.2", + "@esbuild/linux-riscv64": "0.20.2", + "@esbuild/linux-s390x": "0.20.2", + "@esbuild/linux-x64": "0.20.2", + "@esbuild/netbsd-x64": "0.20.2", + "@esbuild/openbsd-x64": "0.20.2", + "@esbuild/sunos-x64": "0.20.2", + "@esbuild/win32-arm64": "0.20.2", + "@esbuild/win32-ia32": "0.20.2", + "@esbuild/win32-x64": "0.20.2" + } + }, + "node_modules/esbuild/node_modules/@esbuild/aix-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.20.2.tgz", + "integrity": "sha512-D+EBOJHXdNZcLJRBkhENNG8Wji2kgc9AZ9KiPr1JuZjsNtyHzrsfLRrY0tk2H2aoFu6RANO1y1iPPUCDYWkb5g==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.20.2.tgz", + "integrity": "sha512-t98Ra6pw2VaDhqNWO2Oph2LXbz/EJcnLmKLGBJwEwXX/JAN83Fym1rU8l0JUWK6HkIbWONCSSatf4sf2NBRx/w==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.20.2.tgz", + "integrity": "sha512-mRzjLacRtl/tWU0SvD8lUEwb61yP9cqQo6noDZP/O8VkwafSYwZ4yWy24kan8jE/IMERpYncRt2dw438LP3Xmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/android-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.20.2.tgz", + "integrity": "sha512-btzExgV+/lMGDDa194CcUQm53ncxzeBrWJcncOBxuC6ndBkKxnHdFJn86mCIgTELsooUmwUm9FkhSp5HYu00Rg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.20.2.tgz", + "integrity": "sha512-4J6IRT+10J3aJH3l1yzEg9y3wkTDgDk7TSDFX+wKFiWjqWp/iCfLIYzGyasx9l0SAFPT1HwSCR+0w/h1ES/MjA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/darwin-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.20.2.tgz", + "integrity": "sha512-tBcXp9KNphnNH0dfhv8KYkZhjc+H3XBkF5DKtswJblV7KlT9EI2+jeA8DgBjp908WEuYll6pF+UStUCfEpdysA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.20.2.tgz", + "integrity": "sha512-d3qI41G4SuLiCGCFGUrKsSeTXyWG6yem1KcGZVS+3FYlYhtNoNgYrWcvkOoaqMhwXSMrZRl69ArHsGJ9mYdbbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/freebsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.20.2.tgz", + "integrity": "sha512-d+DipyvHRuqEeM5zDivKV1KuXn9WeRX6vqSqIDgwIfPQtwMP4jaDsQsDncjTDDsExT4lR/91OLjRo8bmC1e+Cw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.20.2.tgz", + "integrity": "sha512-VhLPeR8HTMPccbuWWcEUD1Az68TqaTYyj6nfE4QByZIQEQVWBB8vup8PpR7y1QHL3CpcF6xd5WVBU/+SBEvGTg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.20.2.tgz", + "integrity": "sha512-9pb6rBjGvTFNira2FLIWqDk/uaf42sSyLE8j1rnUpuzsODBq7FvpwHYZxQ/It/8b+QOS1RYfqgGFNLRI+qlq2A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/esbuild/node_modules/@esbuild/linux-ia32": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.20.2.tgz", + "integrity": "sha512-o10utieEkNPFDZFQm9CoP7Tvb33UutoJqg3qKf1PWVeeJhJw0Q347PxMvBgVVFgouYLGIhFYG0UGdBumROyiig==", + "cpu": [ + "ia32" + ], "dev": true, - "license": "BSD-2-Clause", - "dependencies": { - "dom-serializer": "^2.0.0", - "domelementtype": "^2.3.0", - "domhandler": "^5.0.3" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/duplexer2": { - "version": "0.1.4", + "node_modules/esbuild/node_modules/@esbuild/linux-loong64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.20.2.tgz", + "integrity": "sha512-PR7sp6R/UC4CFVomVINKJ80pMFlfDfMQMYynX7t1tNTeivQ6XdX5r2XovMmha/VjR1YN/HgHWsVcTRIMkymrgQ==", + "cpu": [ + "loong64" + ], "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "readable-stream": "^2.0.2" + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.8", + "node_modules/esbuild/node_modules/@esbuild/linux-mips64el": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.20.2.tgz", + "integrity": "sha512-4BlTqeutE/KnOiTG5Y6Sb/Hw6hsBOZapOVF6njAESHInhlQAghVVZL1ZpIctBOoTFbQyGW+LsVYZ8lSSB3wkjA==", + "cpu": [ + "mips64el" + ], "dev": true, "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", + "node_modules/esbuild/node_modules/@esbuild/linux-ppc64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.20.2.tgz", + "integrity": "sha512-rD3KsaDprDcfajSKdn25ooz5J5/fWBylaaXkuotBDGnMnDP1Uv5DLAN/45qfnf3JDYyJv/ytGHQaziHUdyzaAg==", + "cpu": [ + "ppc64" + ], "dev": true, - "license": "MIT" - }, - "node_modules/emoji-regex": { - "version": "8.0.0", - "license": "MIT" - }, - "node_modules/encoding": { - "version": "0.1.13", "license": "MIT", - "dependencies": { - "iconv-lite": "^0.6.2" + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/end-of-stream": { - "version": "1.4.4", + "node_modules/esbuild/node_modules/@esbuild/linux-riscv64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.20.2.tgz", + "integrity": "sha512-snwmBKacKmwTMmhLlz/3aH1Q9T8v45bKYGE3j26TsaOVtjIag4wLfWSiZykXzXuE1kbCE+zJRmwp+ZbIHinnVg==", + "cpu": [ + "riscv64" + ], "dev": true, "license": "MIT", "optional": true, - "dependencies": { - "once": "^1.4.0" + "os": [ + "linux" + ], + "engines": { + "node": ">=12" } }, - "node_modules/enhanced-resolve": { - "version": "5.16.0", + "node_modules/esbuild/node_modules/@esbuild/linux-s390x": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.20.2.tgz", + "integrity": "sha512-wcWISOobRWNm3cezm5HOZcYz1sKoHLd8VL1dl309DiixxVFoFe/o8HnwuIwn6sXre88Nwj+VwZUvJf4AFxkyrQ==", + "cpu": [ + "s390x" + ], "dev": true, "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=10.13.0" + "node": ">=12" } }, - "node_modules/entities": { - "version": "4.5.0", + "node_modules/esbuild/node_modules/@esbuild/linux-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.20.2.tgz", + "integrity": "sha512-1MdwI6OOTsfQfek8sLwgyjOXAu+wKhLEoaOLTjbijk6E2WONYpH9ZU2mNtR+lZ2B4uwr+usqGuVfFT9tMtGvGw==", + "cpu": [ + "x64" + ], "dev": true, - "license": "BSD-2-Clause", + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], "engines": { - "node": ">=0.12" - }, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" + "node": ">=12" } }, - "node_modules/es-define-property": { - "version": "1.0.0", + "node_modules/esbuild/node_modules/@esbuild/netbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.20.2.tgz", + "integrity": "sha512-K8/DhBxcVQkzYc43yJXDSyjlFeHQJBiowJ0uVL6Tor3jGQfSGHNNJcWxNbOI8v5k82prYqzPuwkzHt3J1T1iZQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, + "optional": true, + "os": [ + "netbsd" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-errors": { - "version": "1.3.0", + "node_modules/esbuild/node_modules/@esbuild/openbsd-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.20.2.tgz", + "integrity": "sha512-eMpKlV0SThJmmJgiVyN9jTPJ2VBPquf6Kt/nAoo6DgHAoN57K15ZghiHaMvqjCye/uU4X5u3YSMgVBI1h3vKrQ==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], "engines": { - "node": ">= 0.4" + "node": ">=12" } }, - "node_modules/es-get-iterator": { - "version": "1.1.3", + "node_modules/esbuild/node_modules/@esbuild/sunos-x64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.20.2.tgz", + "integrity": "sha512-2UyFtRC6cXLyejf/YEld4Hajo7UHILetzE1vsRcGL3earZEW77JxrFjH4Ez2qaTiEfMgAXxfAZCm1fvM/G/o8w==", + "cpu": [ + "x64" + ], "dev": true, "license": "MIT", - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "is-arguments": "^1.1.1", - "is-map": "^2.0.2", - "is-set": "^2.0.2", - "is-string": "^1.0.7", - "isarray": "^2.0.5", - "stop-iteration-iterator": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" } }, - "node_modules/es-get-iterator/node_modules/isarray": { - "version": "2.0.5", + "node_modules/esbuild/node_modules/@esbuild/win32-arm64": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.20.2.tgz", + "integrity": "sha512-GRibxoawM9ZCnDxnP3usoUDO9vUkpAxIIZ6GQI+IlVmr5kP3zUq+l17xELTHMWTWzjxa2guPNyrpq1GWmPvcGQ==", + "cpu": [ + "arm64" + ], "dev": true, - "license": "MIT" + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } }, - "node_modules/esbuild": { + "node_modules/esbuild/node_modules/@esbuild/win32-ia32": { "version": "0.20.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.20.2.tgz", + "integrity": "sha512-HfLOfn9YWmkSKRQqovpnITazdtquEW8/SoHW7pWpuEeguaZI4QnCRW6b+oZTztdBnZOS2hqJ6im/D5cPzBTTlQ==", + "cpu": [ + "ia32" + ], "dev": true, - "hasInstallScript": true, "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, + "optional": true, + "os": [ + "win32" + ], "engines": { "node": ">=12" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.20.2", - "@esbuild/android-arm": "0.20.2", - "@esbuild/android-arm64": "0.20.2", - "@esbuild/android-x64": "0.20.2", - "@esbuild/darwin-arm64": "0.20.2", - "@esbuild/darwin-x64": "0.20.2", - "@esbuild/freebsd-arm64": "0.20.2", - "@esbuild/freebsd-x64": "0.20.2", - "@esbuild/linux-arm": "0.20.2", - "@esbuild/linux-arm64": "0.20.2", - "@esbuild/linux-ia32": "0.20.2", - "@esbuild/linux-loong64": "0.20.2", - "@esbuild/linux-mips64el": "0.20.2", - "@esbuild/linux-ppc64": "0.20.2", - "@esbuild/linux-riscv64": "0.20.2", - "@esbuild/linux-s390x": "0.20.2", - "@esbuild/linux-x64": "0.20.2", - "@esbuild/netbsd-x64": "0.20.2", - "@esbuild/openbsd-x64": "0.20.2", - "@esbuild/sunos-x64": "0.20.2", - "@esbuild/win32-arm64": "0.20.2", - "@esbuild/win32-ia32": "0.20.2", - "@esbuild/win32-x64": "0.20.2" } }, "node_modules/escalade": { @@ -2566,6 +3425,16 @@ "node": ">=4.0" } }, + "node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/esutils": { "version": "2.0.2", "dev": true, @@ -2611,6 +3480,16 @@ "node": ">=6" } }, + "node_modules/expect-type": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.4.0.tgz", + "integrity": "sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/falafel": { "version": "2.2.5", "dev": true, @@ -2805,6 +3684,21 @@ "version": "1.0.0", "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "dev": true, @@ -3096,16 +3990,6 @@ "node": ">= 6" } }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/ieee754": { "version": "1.2.1", "funding": [ @@ -3406,17 +4290,10 @@ "call-bind": "^1.0.7" }, "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "license": "MIT", - "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/is-string": { @@ -3484,6 +4361,7 @@ }, "node_modules/isarray": { "version": "1.0.0", + "dev": true, "license": "MIT" }, "node_modules/isexe": { @@ -3660,6 +4538,267 @@ "immediate": "~3.0.5" } }, + "node_modules/lightningcss": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss/-/lightningcss-1.32.0.tgz", + "integrity": "sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==", + "dev": true, + "license": "MPL-2.0", + "dependencies": { + "detect-libc": "^2.0.3" + }, + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + }, + "optionalDependencies": { + "lightningcss-android-arm64": "1.32.0", + "lightningcss-darwin-arm64": "1.32.0", + "lightningcss-darwin-x64": "1.32.0", + "lightningcss-freebsd-x64": "1.32.0", + "lightningcss-linux-arm-gnueabihf": "1.32.0", + "lightningcss-linux-arm64-gnu": "1.32.0", + "lightningcss-linux-arm64-musl": "1.32.0", + "lightningcss-linux-x64-gnu": "1.32.0", + "lightningcss-linux-x64-musl": "1.32.0", + "lightningcss-win32-arm64-msvc": "1.32.0", + "lightningcss-win32-x64-msvc": "1.32.0" + } + }, + "node_modules/lightningcss-android-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-android-arm64/-/lightningcss-android-arm64-1.32.0.tgz", + "integrity": "sha512-YK7/ClTt4kAK0vo6w3X+Pnm0D2cf2vPHbhOXdoNti1Ga0al1P4TBZhwjATvjNwLEBCnKvjJc2jQgHXH0NEwlAg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-arm64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.32.0.tgz", + "integrity": "sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-darwin-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-darwin-x64/-/lightningcss-darwin-x64-1.32.0.tgz", + "integrity": "sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-freebsd-x64": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-freebsd-x64/-/lightningcss-freebsd-x64-1.32.0.tgz", + "integrity": "sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm-gnueabihf": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm-gnueabihf/-/lightningcss-linux-arm-gnueabihf-1.32.0.tgz", + "integrity": "sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-gnu/-/lightningcss-linux-arm64-gnu-1.32.0.tgz", + "integrity": "sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-arm64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-arm64-musl/-/lightningcss-linux-arm64-musl-1.32.0.tgz", + "integrity": "sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-gnu": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-gnu/-/lightningcss-linux-x64-gnu-1.32.0.tgz", + "integrity": "sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-linux-x64-musl": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-linux-x64-musl/-/lightningcss-linux-x64-musl-1.32.0.tgz", + "integrity": "sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-arm64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-arm64-msvc/-/lightningcss-win32-arm64-msvc-1.32.0.tgz", + "integrity": "sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, + "node_modules/lightningcss-win32-x64-msvc": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/lightningcss-win32-x64-msvc/-/lightningcss-win32-x64-msvc-1.32.0.tgz", + "integrity": "sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MPL-2.0", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">= 12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/parcel" + } + }, "node_modules/linkify-it": { "version": "3.0.3", "dev": true, @@ -4112,6 +5251,25 @@ "dev": true, "license": "ISC" }, + "node_modules/nanoid": { + "version": "3.3.15", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.15.tgz", + "integrity": "sha512-y7Wygv/7mEOvxTuEQDB8StXdMRBWf1kR/tlhAzBRUFkB2jfcLOAxO/SHmOO2zgz1pVgK29/kyupn059/bCHdjA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-build-utils": { "version": "1.0.2", "dev": true, @@ -4141,24 +5299,6 @@ "license": "MIT", "optional": true }, - "node_modules/node-fetch": { - "version": "2.6.12", - "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, "node_modules/node-gyp-build": { "version": "4.8.4", "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.4.tgz", @@ -4247,6 +5387,20 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/obug": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/obug/-/obug-2.1.3.tgz", + "integrity": "sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==", + "dev": true, + "funding": [ + "https://github.com/sponsors/sxzz", + "https://opencollective.com/debug" + ], + "license": "MIT", + "engines": { + "node": ">=12.20.0" + } + }, "node_modules/once": { "version": "1.4.0", "license": "ISC", @@ -4416,11 +5570,25 @@ "node": ">=8" } }, + "node_modules/pathe": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", + "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", + "dev": true, + "license": "MIT" + }, "node_modules/pend": { "version": "1.2.0", "dev": true, "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "dev": true, + "license": "ISC" + }, "node_modules/picomatch": { "version": "2.3.1", "dev": true, @@ -4432,19 +5600,41 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pluralize": { - "version": "7.0.0", + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "dev": true, "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.4" } }, - "node_modules/possible-typed-array-names": { - "version": "1.0.0", + "node_modules/postcss": { + "version": "8.5.16", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.16.tgz", + "integrity": "sha512-vuwillviilfKZsg0VGj5R/YwwcHx4SLsIOI/7K6mQkWx+l5cUHTjj5g0AasTBcyXsbfTgrwsUNmVUb5xVwyPwg==", "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "license": "MIT", + "dependencies": { + "nanoid": "^3.3.12", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, "engines": { - "node": ">= 0.4" + "node": "^10 || ^12 || >=14" } }, "node_modules/prebuild-install": { @@ -4490,6 +5680,7 @@ }, "node_modules/process-nextick-args": { "version": "2.0.1", + "dev": true, "license": "MIT" }, "node_modules/promise-timeout": { @@ -4509,6 +5700,7 @@ }, "node_modules/punycode": { "version": "2.3.1", + "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -4751,6 +5943,40 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/rolldown": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.1.5.tgz", + "integrity": "sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@oxc-project/types": "=0.139.0", + "@rolldown/pluginutils": "^1.0.0" + }, + "bin": { + "rolldown": "bin/cli.mjs" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "optionalDependencies": { + "@rolldown/binding-android-arm64": "1.1.5", + "@rolldown/binding-darwin-arm64": "1.1.5", + "@rolldown/binding-darwin-x64": "1.1.5", + "@rolldown/binding-freebsd-x64": "1.1.5", + "@rolldown/binding-linux-arm-gnueabihf": "1.1.5", + "@rolldown/binding-linux-arm64-gnu": "1.1.5", + "@rolldown/binding-linux-arm64-musl": "1.1.5", + "@rolldown/binding-linux-ppc64-gnu": "1.1.5", + "@rolldown/binding-linux-s390x-gnu": "1.1.5", + "@rolldown/binding-linux-x64-gnu": "1.1.5", + "@rolldown/binding-linux-x64-musl": "1.1.5", + "@rolldown/binding-openharmony-arm64": "1.1.5", + "@rolldown/binding-wasm32-wasi": "1.1.5", + "@rolldown/binding-win32-arm64-msvc": "1.1.5", + "@rolldown/binding-win32-x64-msvc": "1.1.5" + } + }, "node_modules/run-parallel": { "version": "1.2.0", "dev": true, @@ -4785,10 +6011,6 @@ "node": ">=10" } }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "license": "MIT" - }, "node_modules/sax": { "version": "1.3.0", "dev": true, @@ -4908,6 +6130,13 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/siginfo": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz", + "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==", + "dev": true, + "license": "ISC" + }, "node_modules/signal-exit": { "version": "4.1.0", "dev": true, @@ -4970,18 +6199,35 @@ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { - "node": ">=8" + "node": ">=8" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "dev": true, + "license": "BSD-3-Clause", + "optional": true, + "engines": { + "node": ">=0.10.0" } }, - "node_modules/source-map": { - "version": "0.6.1", + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", "dev": true, "license": "BSD-3-Clause", - "optional": true, "engines": { "node": ">=0.10.0" } }, + "node_modules/stackback": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz", + "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==", + "dev": true, + "license": "MIT" + }, "node_modules/static-eval": { "version": "2.1.1", "dev": true, @@ -5067,6 +6313,13 @@ "util-deprecate": "~1.0.1" } }, + "node_modules/std-env": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-4.2.0.tgz", + "integrity": "sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==", + "dev": true, + "license": "MIT" + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "dev": true, @@ -5332,6 +6585,81 @@ "version": "1.0.2", "license": "MIT" }, + "node_modules/tinybench": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz", + "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinyexec": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.2.4.tgz", + "integrity": "sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/tinyglobby": { + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "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==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/tinyrainbow": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.0.tgz", + "integrity": "sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.2.3", "dev": true, @@ -5351,18 +6679,6 @@ "node": ">=8.0" } }, - "node_modules/tr46": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-4.1.1.tgz", - "integrity": "sha512-2lv/66T7e5yNyhAAC4NaKe5nVavzuGJQVVtRYLyQ2OI8tsJ61PMLlelehb0wi2Hx6+hT/OJUWZcw8MjlSRnxvw==", - "license": "MIT", - "dependencies": { - "punycode": "^2.3.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/tree-sitter-c": { "version": "0.24.1", "resolved": "https://registry.npmjs.org/tree-sitter-c/-/tree-sitter-c-0.24.1.tgz", @@ -5827,6 +7143,14 @@ } } }, + "node_modules/tslib": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", + "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", + "dev": true, + "license": "0BSD", + "optional": true + }, "node_modules/tunnel": { "version": "0.0.6", "dev": true, @@ -6001,6 +7325,224 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/vitest": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-4.1.10.tgz", + "integrity": "sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "4.1.10", + "@vitest/mocker": "4.1.10", + "@vitest/pretty-format": "4.1.10", + "@vitest/runner": "4.1.10", + "@vitest/snapshot": "4.1.10", + "@vitest/spy": "4.1.10", + "@vitest/utils": "4.1.10", + "es-module-lexer": "^2.0.0", + "expect-type": "^1.3.0", + "magic-string": "^0.30.21", + "obug": "^2.1.1", + "pathe": "^2.0.3", + "picomatch": "^4.0.3", + "std-env": "^4.0.0-rc.1", + "tinybench": "^2.9.0", + "tinyexec": "^1.0.2", + "tinyglobby": "^0.2.15", + "tinyrainbow": "^3.1.0", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^20.0.0 || ^22.0.0 || >=24.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@opentelemetry/api": "^1.9.0", + "@types/node": "^20.0.0 || ^22.0.0 || >=24.0.0", + "@vitest/browser-playwright": "4.1.10", + "@vitest/browser-preview": "4.1.10", + "@vitest/browser-webdriverio": "4.1.10", + "@vitest/coverage-istanbul": "4.1.10", + "@vitest/coverage-v8": "4.1.10", + "@vitest/ui": "4.1.10", + "happy-dom": "*", + "jsdom": "*", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@opentelemetry/api": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser-playwright": { + "optional": true + }, + "@vitest/browser-preview": { + "optional": true + }, + "@vitest/browser-webdriverio": { + "optional": true + }, + "@vitest/coverage-istanbul": { + "optional": true + }, + "@vitest/coverage-v8": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + }, + "vite": { + "optional": false + } + } + }, + "node_modules/vitest/node_modules/@vitest/mocker": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", + "integrity": "sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "4.1.10", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.21" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/vitest/node_modules/magic-string": { + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.5" + } + }, + "node_modules/vitest/node_modules/picomatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/vitest/node_modules/vite": { + "version": "8.1.4", + "resolved": "https://registry.npmjs.org/vite/-/vite-8.1.4.tgz", + "integrity": "sha512-bTT9PsdWO+MQMNG9ZXIP/qM9wGh37DFxTV/sPq9cFpHr3w4jkgef032PkAL9jAqhk3Nz8NQw3O8n6/xFkqO4QQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "lightningcss": "^1.32.0", + "picomatch": "^4.0.5", + "postcss": "^8.5.16", + "rolldown": "~1.1.4", + "tinyglobby": "^0.2.17" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^20.19.0 || >=22.12.0", + "@vitejs/devtools": "^0.3.0", + "esbuild": "^0.27.0 || ^0.28.0", + "jiti": ">=1.21.0", + "less": "^4.0.0", + "sass": "^1.70.0", + "sass-embedded": "^1.70.0", + "stylus": ">=0.54.8", + "sugarss": "^5.0.0", + "terser": "^5.16.0", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "@vitejs/devtools": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "jiti": { + "optional": true + }, + "less": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, "node_modules/vlq": { "version": "0.2.3", "dev": true, @@ -6028,32 +7570,6 @@ "dev": true, "license": "MIT" }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "license": "BSD-2-Clause", - "engines": { - "node": ">=12" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.2", - "license": "MIT" - }, - "node_modules/whatwg-url": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-13.0.0.tgz", - "integrity": "sha512-9WWbymnqj57+XEuqADHrCJ2eSXzn8WXIW/YSGaZtb2WKAInQ6CHfaUUcTyyver0p8BDg5StLQq8h1vtZuwmOig==", - "license": "MIT", - "dependencies": { - "tr46": "^4.1.1", - "webidl-conversions": "^7.0.0" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/which": { "version": "2.0.2", "dev": true, @@ -6115,6 +7631,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/why-is-node-running": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz", + "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==", + "dev": true, + "license": "MIT", + "dependencies": { + "siginfo": "^2.0.0", + "stackback": "0.0.2" + }, + "bin": { + "why-is-node-running": "cli.js" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/word-wrap": { "version": "1.2.5", "dev": true, @@ -6264,13 +7797,18 @@ "license": "ISC" }, "node_modules/yaml": { - "version": "2.4.1", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.0.tgz", + "integrity": "sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==", "license": "ISC", "bin": { "yaml": "bin.mjs" }, "engines": { - "node": ">= 14" + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" } }, "node_modules/yargs": { @@ -6346,13 +7884,12 @@ } }, "packages/quicktype-core": { - "version": "18.0.15", + "version": "24.0.0", "license": "Apache-2.0", "dependencies": { "@glideapps/ts-necessities": "2.2.3", "browser-or-node": "^3.0.0", "collection-utils": "^1.0.1", - "cross-fetch": "^4.0.0", "is-url": "^1.2.4", "js-base64": "^3.7.7", "lodash": "^4.17.21", @@ -6367,7 +7904,7 @@ "devDependencies": { "@types/browser-or-node": "^1.3.2", "@types/is-url": "^1.2.32", - "@types/node": "~22.14.0", + "@types/node": "~20.19.0", "@types/pako": "^1.0.0", "@types/pluralize": "0.0.30", "@types/readable-stream": "4.0.10", @@ -6376,6 +7913,9 @@ "@types/wordwrap": "^1.0.3", "command-line-args": "^5.2.1", "typescript": "~5.8.3" + }, + "engines": { + "node": ">=20.0.0" } }, "packages/quicktype-core/node_modules/pluralize": { @@ -6386,7 +7926,7 @@ } }, "packages/quicktype-graphql-input": { - "version": "18.0.15", + "version": "24.0.0", "license": "Apache-2.0", "dependencies": { "collection-utils": "^1.0.1", @@ -6395,12 +7935,15 @@ }, "devDependencies": { "@types/graphql": "^0.11.7", - "@types/node": "~22.14.0", + "@types/node": "~20.19.0", "typescript": "~5.8.3" + }, + "engines": { + "node": ">=20.0.0" } }, "packages/quicktype-typescript-input": { - "version": "18.0.15", + "version": "24.0.0", "license": "Apache-2.0", "dependencies": { "@mark.probst/typescript-json-schema": "0.55.0", @@ -6408,69 +7951,10 @@ "typescript": "4.9.5" }, "devDependencies": { - "@types/node": "~22.14.0" - } - }, - "packages/quicktype-typescript-input/node_modules/@glideapps/ts-necessities": { - "version": "2.1.2", - "license": "MIT" - }, - "packages/quicktype-typescript-input/node_modules/browser-or-node": { - "version": "1.3.0", - "license": "MIT" - }, - "packages/quicktype-typescript-input/node_modules/isomorphic-fetch": { - "version": "2.2.1", - "license": "MIT", - "dependencies": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "packages/quicktype-typescript-input/node_modules/js-base64": { - "version": "2.6.4", - "license": "BSD-3-Clause" - }, - "packages/quicktype-typescript-input/node_modules/node-fetch": { - "version": "1.7.3", - "license": "MIT", - "dependencies": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "packages/quicktype-typescript-input/node_modules/quicktype-core": { - "version": "20.0.0", - "license": "Apache-2.0", - "dependencies": { - "@glideapps/ts-necessities": "2.1.2", - "@types/urijs": "^1.19.8", - "browser-or-node": "^1.2.1", - "collection-utils": "^1.0.1", - "is-url": "^1.2.4", - "isomorphic-fetch": "^2.2.1", - "js-base64": "^2.4.3", - "lodash": "^4.17.21", - "pako": "^1.0.6", - "pluralize": "^7.0.0", - "readable-stream": "2.3.7", - "unicode-properties": "^1.4.1", - "urijs": "^1.19.1", - "wordwrap": "^1.0.0", - "yaml": "^1.5.0" - } - }, - "packages/quicktype-typescript-input/node_modules/readable-stream": { - "version": "2.3.7", - "license": "MIT", - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" + "@types/node": "~20.19.0" + }, + "engines": { + "node": ">=20.0.0" } }, "packages/quicktype-typescript-input/node_modules/typescript": { @@ -6486,19 +7970,12 @@ "node": ">=4.2.0" } }, - "packages/quicktype-typescript-input/node_modules/yaml": { - "version": "1.10.2", - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "packages/quicktype-vscode": { "name": "quicktype", - "version": "23.0.122", + "version": "24.0.0", "devDependencies": { "@types/mocha": "^10.0.6", - "@types/node": "~22.14.0", + "@types/node": "~20.19.0", "@types/node-persist": "^3.1.8", "@types/readable-stream": "^4.0.10", "@types/vscode": "^1.87.0", diff --git a/package.json b/package.json index 146b5c6059..526100e88a 100644 --- a/package.json +++ b/package.json @@ -1,19 +1,22 @@ { "name": "quicktype", - "version": "23.3.0", + "version": "24.0.0", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": "https://github.com/glideapps/quicktype", "engines": { - "node": ">=18.12.0" + "node": ">=20.0.0" }, "scripts": { "pub": "script/publish-npm.sh && script/publish-vscode.sh", "pub:npm": "script/publish-npm.sh", "pub:vscode": "script/publish-vscode.sh", - "build": "npm run clean && npm run build --workspaces --if-present && tsc", - "test": "script/test", + "build": "npm run clean && npm run build --workspaces --if-present && node node_modules/typescript/bin/tsc", + "test": "npm run test:unit && npm run test:fixtures", + "test:unit": "vitest run", + "test:unit:watch": "vitest", + "test:fixtures": "script/test", "start": "script/watch", "clean": "rm -rf dist *~ packages/*/{dist,out}", "debug": "node --inspect-brk --max-old-space-size=4096 ./dist/index.js", @@ -32,13 +35,12 @@ "collection-utils": "^1.0.1", "command-line-args": "^5.2.1", "command-line-usage": "^7.0.1", - "cross-fetch": "^4.0.0", "graphql": "^0.11.7", "lodash": "^4.17.21", "moment": "^2.30.1", - "quicktype-core": "20.0.12", - "quicktype-graphql-input": "20.0.2", - "quicktype-typescript-input": "20.0.2", + "quicktype-core": "24.0.0", + "quicktype-graphql-input": "24.0.0", + "quicktype-typescript-input": "24.0.0", "readable-stream": "^4.5.2", "stream-json": "1.8.0", "string-to-stream": "^3.0.1", @@ -46,11 +48,12 @@ }, "devDependencies": { "@biomejs/biome": "^1.9.4", - "@tsconfig/node18": "^1.0.1", + "@tsconfig/node20": "^20.1.6", "@types/command-line-args": "^5.2.0", "@types/command-line-usage": "^5.0.4", "@types/graphql": "^0.11.7", "@types/lodash": "^4.17.0", + "@types/node": "~20.19.0", "@types/semver": "^7.5.0", "@types/shelljs": "^0.8.15", "@types/stream-json": "^1.7.3", @@ -78,16 +81,10 @@ "tree-sitter-scala": "^0.24.0", "tree-sitter-typescript": "^0.23.2", "ts-node": "^10.9.2", + "vitest": "^4.1.10", "watch": "^1.0.2", "web-tree-sitter": "^0.26.9" }, - "overrides": { - "cross-fetch": { - "node-fetch": { - "whatwg-url": "^13.0.0" - } - } - }, "files": ["dist"], "bin": "dist/index.js" } diff --git a/packages/quicktype-core/package.json b/packages/quicktype-core/package.json index cf03a0621c..3d5ab0dba3 100644 --- a/packages/quicktype-core/package.json +++ b/packages/quicktype-core/package.json @@ -1,20 +1,22 @@ { "name": "quicktype-core", - "version": "18.0.15", + "version": "24.0.0", "description": "The quicktype engine as a library", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": "https://github.com/glideapps/quicktype", + "engines": { + "node": ">=20.0.0" + }, "scripts": { "clean": "rm -rf dist node_modules *~", - "build": "tsc" + "build": "node ../../node_modules/typescript/bin/tsc" }, "dependencies": { "@glideapps/ts-necessities": "2.2.3", "browser-or-node": "^3.0.0", "collection-utils": "^1.0.1", - "cross-fetch": "^4.0.0", "is-url": "^1.2.4", "js-base64": "^3.7.7", "lodash": "^4.17.21", @@ -29,7 +31,7 @@ "devDependencies": { "@types/browser-or-node": "^1.3.2", "@types/is-url": "^1.2.32", - "@types/node": "~22.14.0", + "@types/node": "~20.19.0", "@types/pako": "^1.0.0", "@types/pluralize": "0.0.30", "@types/readable-stream": "4.0.10", @@ -39,13 +41,6 @@ "command-line-args": "^5.2.1", "typescript": "~5.8.3" }, - "overrides": { - "cross-fetch": { - "node-fetch": { - "whatwg-url": "^13.0.0" - } - } - }, "files": ["dist"], "browser": { "fs": false, diff --git a/packages/quicktype-core/src/input/io/$fetch.ts b/packages/quicktype-core/src/input/io/$fetch.ts deleted file mode 100644 index e2dade593d..0000000000 --- a/packages/quicktype-core/src/input/io/$fetch.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type CrossFetch from "cross-fetch"; - -let fetch: typeof CrossFetch; - -try { - fetch = global.fetch ?? require("cross-fetch").default; -} catch { - fetch = require("cross-fetch").default; -} - -export { fetch }; diff --git a/packages/quicktype-core/src/input/io/NodeIO.ts b/packages/quicktype-core/src/input/io/NodeIO.ts index 02aeb98c80..0480134006 100644 --- a/packages/quicktype-core/src/input/io/NodeIO.ts +++ b/packages/quicktype-core/src/input/io/NodeIO.ts @@ -11,8 +11,6 @@ import { panic } from "../../support/Support"; import { getStream } from "./get-stream"; -import { fetch } from "./$fetch"; - interface HttpHeaders { [key: string]: string; } @@ -73,10 +71,8 @@ const ReadableWithFrom = Readable as unknown as { }; function readableFromResponseBody(body: unknown): Readable { - // Native fetch (Node >= 18, browsers) returns a WHATWG ReadableStream, - // which lacks the Node stream API that our consumers rely on, so we have - // to wrap it. The cross-fetch fallback (node-fetch) already returns a - // Node stream, which we pass through unchanged. + // Native fetch returns a WHATWG ReadableStream, which lacks the Node + // stream API that our consumers rely on, so we have to wrap it. if (typeof (body as WebReadableStream).getReader === "function") { return ReadableWithFrom.from( webStreamChunks(body as WebReadableStream), @@ -105,7 +101,7 @@ export async function readableFromFileOrURL( ): Promise { try { if (isURL(fileOrURL)) { - const response = await fetch(fileOrURL, { + const response = await globalThis.fetch(fileOrURL, { headers: parseHeaders(httpHeaders), }); diff --git a/packages/quicktype-graphql-input/package.json b/packages/quicktype-graphql-input/package.json index f1ce47a750..cbacaa4669 100644 --- a/packages/quicktype-graphql-input/package.json +++ b/packages/quicktype-graphql-input/package.json @@ -1,14 +1,17 @@ { "name": "quicktype-graphql-input", - "version": "18.0.15", + "version": "24.0.0", "package": "Package for using GraphQL as an input language to quicktype", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": "https://github.com/glideapps/quicktype", + "engines": { + "node": ">=20.0.0" + }, "scripts": { "clean": "rm -rf dist node_modules *~", - "build": "tsc" + "build": "node ../../node_modules/typescript/bin/tsc" }, "dependencies": { "quicktype-core": "file:../quicktype-core", @@ -16,7 +19,7 @@ "graphql": "^0.11.7" }, "devDependencies": { - "@types/node": "~22.14.0", + "@types/node": "~20.19.0", "@types/graphql": "^0.11.7", "typescript": "~5.8.3" }, diff --git a/packages/quicktype-typescript-input/package.json b/packages/quicktype-typescript-input/package.json index 08c12c944e..a1c1db120c 100644 --- a/packages/quicktype-typescript-input/package.json +++ b/packages/quicktype-typescript-input/package.json @@ -1,14 +1,17 @@ { "name": "quicktype-typescript-input", - "version": "18.0.15", + "version": "24.0.0", "description": "Package for using TypeScript as an input language to quicktype", "license": "Apache-2.0", "main": "dist/index.js", "types": "dist/index.d.ts", "repository": "https://github.com/glideapps/quicktype", + "engines": { + "node": ">=20.0.0" + }, "scripts": { "clean": "rm -rf dist node_modules *~", - "build": "tsc" + "build": "node ../../node_modules/typescript/bin/tsc" }, "dependencies": { "quicktype-core": "file:../quicktype-core", @@ -16,7 +19,7 @@ "@mark.probst/typescript-json-schema": "0.55.0" }, "devDependencies": { - "@types/node": "~22.14.0" + "@types/node": "~20.19.0" }, "files": ["dist"] } diff --git a/packages/quicktype-vscode/package.json b/packages/quicktype-vscode/package.json index 702830d326..44c2d8d076 100644 --- a/packages/quicktype-vscode/package.json +++ b/packages/quicktype-vscode/package.json @@ -2,7 +2,7 @@ "name": "quicktype", "displayName": "Paste JSON as Code", "description": "Copy JSON, paste as Go, TypeScript, C#, C++ and more.", - "version": "23.0.122", + "version": "24.0.0", "publisher": "quicktype", "icon": "media/icon.png", "galleryBanner": { @@ -129,8 +129,8 @@ "scripts": { "pub": "vsce publish -p $VSCE_TOKEN", "package": "vsce package", - "build": "tsc -p ./", - "watch": "tsc -watch -p ./", + "build": "node ../../node_modules/typescript/bin/tsc -p ./", + "watch": "node ../../node_modules/typescript/bin/tsc -watch -p ./", "test": "npm run build && node ./node_modules/vscode/bin/test", "vscode:prepublish": "npm run esbuild-base -- --minify", "esbuild-base": "esbuild ./src/extension.ts --bundle --outfile=dist/extension.js --external:vscode --format=cjs --platform=node", @@ -139,7 +139,7 @@ }, "devDependencies": { "@types/mocha": "^10.0.6", - "@types/node": "~22.14.0", + "@types/node": "~20.19.0", "@types/node-persist": "^3.1.8", "@types/readable-stream": "^4.0.10", "@types/vscode": "^1.87.0", diff --git a/src/GraphQLIntrospection.ts b/src/GraphQLIntrospection.ts index db2093a0a1..efca421202 100644 --- a/src/GraphQLIntrospection.ts +++ b/src/GraphQLIntrospection.ts @@ -1,5 +1,4 @@ import { exceptionToString } from "@glideapps/ts-necessities"; -import fetch from "cross-fetch"; import { introspectionQuery } from "graphql"; import { panic } from "quicktype-core"; @@ -12,6 +11,11 @@ const defaultHeaders: { [name: string]: string } = { const headerRegExp = /^([^:]+):\s*(.*)$/; +interface IntrospectionResult { + errors?: unknown; + data?: unknown; +} + export async function introspectServer( url: string, method: string, @@ -32,15 +36,15 @@ export async function introspectServer( headers[matches[1]] = matches[2]; } - let result; + let result: IntrospectionResult; try { - const response = await fetch(url, { + const response = await globalThis.fetch(url, { method, headers: headers, body: JSON.stringify({ query: introspectionQuery }), }); - result = await response.json(); + result = (await response.json()) as IntrospectionResult; } catch (error) { return panic( `Error while fetching introspection query result: ${exceptionToString(error)}`, diff --git a/test/check-clean-import.ts b/test/check-clean-import.ts deleted file mode 100644 index 8a6540ed61..0000000000 --- a/test/check-clean-import.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { execFileSync } from "node:child_process"; -import * as path from "node:path"; - -// Guard: importing the built quicktype-core must not write to stdout. -// -// quicktype-core's build used to swap in a CI-only fetch shim ($fetch.ci.ts) -// whenever $CI was set — that substitution is gone now — and the shim used to -// start with a top-level console.info, so every published package since -// 23.3.1 printed "=== RUNNING IN CI, USE FETCH.CI ===" on import — corrupting -// redirected CLI output (`quicktype ... > out.ts` produced non-compiling -// code). See https://github.com/glideapps/quicktype/issues/2874. -// -// This check requires the built package in a child process and fails the test -// run if the import produces any stdout output. - -export function checkCoreImportKeepsStdoutClean(): void { - const coreDir = path.join(__dirname, "..", "packages", "quicktype-core"); - const stdout = execFileSync( - process.execPath, - ["-e", `require(${JSON.stringify(coreDir)});`], - { encoding: "utf8" }, - ); - if (stdout !== "") { - console.error( - `error: requiring quicktype-core wrote to stdout: - - ${JSON.stringify(stdout)} - -Importing quicktype-core must not print anything: CLI users redirect stdout -(quicktype ... > out.ts), so any stray output corrupts generated code. See -https://github.com/glideapps/quicktype/issues/2874`, - ); - process.exit(1); - } -} - -// Allow running the check standalone: -// npx ts-node --project test/tsconfig.json test/check-clean-import.ts -if (require.main === module) { - checkCoreImportKeepsStdoutClean(); - console.error("* importing quicktype-core keeps stdout clean"); -} diff --git a/test/check-java-acronym-names.ts b/test/check-java-acronym-names.ts deleted file mode 100644 index 9480553c45..0000000000 --- a/test/check-java-acronym-names.ts +++ /dev/null @@ -1,105 +0,0 @@ -// Guard: Java enum constants must keep acronyms uppercase for every -// --acronym-style setting. -// -// Java enum constants are rendered in UPPER_UNDERSCORE style. Before the fix -// in https://github.com/glideapps/quicktype/pull/2851 (issue #2850), the -// acronym-style option was still applied to words recognized as acronyms -// (e.g. "SPA"), so with --acronym-style=camel the JSON enum value -// "MULTI_SPA_IN_GROUP_REJECTED" produced the constant -// "MULTI_Spa_IN_GROUP_REJECTED" (and "MULTI_spa_IN_GROUP_REJECTED" with -// lowerCase). -// -// The regular fixture harness cannot catch this: the mangled constants are -// self-consistent identifiers, so the generated code still compiles, and -// (de)serialization uses the raw JSON names, so round-tripping succeeds. -// This check instead generates Java code directly and asserts on the emitted -// *identifier*. Note that we must NOT just check that the output contains -// "MULTI_SPA_IN_GROUP_REJECTED" — the raw JSON name always appears in the -// string literals of toValue()/forValue(), even when the identifier is -// mangled. We extract the identifier from `case : return "";` -// and compare that. - -import { InputData, JSONSchemaInput, quicktype } from "quicktype-core"; - -// "spa" is a known acronym (see Acronyms.const.ts), so acronym styling would -// apply to the SPA word if the fix regressed. -const enumValue = "MULTI_SPA_IN_GROUP_REJECTED"; - -const schema = JSON.stringify({ - $schema: "http://json-schema.org/draft-06/schema#", - type: "object", - properties: { - messageCode: { - type: "string", - enum: [enumValue], - }, - }, - required: ["messageCode"], -}); - -const acronymStyles = ["original", "pascal", "camel", "lowerCase"]; - -async function javaEnumConstantIdentifier( - acronymStyle: string, -): Promise { - const schemaInput = new JSONSchemaInput(undefined); - await schemaInput.addSource({ name: "TopLevel", schema }); - const inputData = new InputData(); - inputData.addInput(schemaInput); - - const result = await quicktype({ - inputData, - lang: "java", - rendererOptions: { "acronym-style": acronymStyle }, - }); - const output = result.lines.join("\n"); - - // Matches e.g. `case MULTI_SPA_IN_GROUP_REJECTED: return "MULTI_SPA_IN_GROUP_REJECTED";` - // in the generated MessageCode.toValue() — the capture is the identifier. - const match = output.match( - new RegExp(`case (\\w+): return "${enumValue}";`), - ); - if (match === null) { - console.error( - `error: could not find the enum constant for "${enumValue}" in the generated Java code (acronym-style=${acronymStyle}):\n\n${output}`, - ); - process.exit(1); - } - - return match[1]; -} - -export async function checkJavaEnumAcronymCasing(): Promise { - const failures: string[] = []; - for (const style of acronymStyles) { - const identifier = await javaEnumConstantIdentifier(style); - if (identifier !== enumValue) { - failures.push( - ` acronym-style=${style}: got "${identifier}", expected "${enumValue}"`, - ); - } - } - - if (failures.length > 0) { - console.error( - `error: Java enum constants must keep acronyms uppercase for every acronym-style (issue #2850): - -${failures.join("\n")} - -javaNameStyle must force allUpperWordStyle for acronyms in UPPER_UNDERSCORE -names — see packages/quicktype-core/src/language/Java/utils.ts and -https://github.com/glideapps/quicktype/pull/2851`, - ); - process.exit(1); - } -} - -// Allow running the check standalone: -// NODE_PATH=`pwd`/node_modules npx ts-node --project test/tsconfig.json test/check-java-acronym-names.ts -if (require.main === module) { - checkJavaEnumAcronymCasing().then(() => { - console.error( - "* Java enum constants keep acronyms uppercase for every acronym-style", - ); - }); -} diff --git a/test/check-no-node-imports.ts b/test/check-no-node-imports.ts deleted file mode 100644 index 3e727b9eca..0000000000 --- a/test/check-no-node-imports.ts +++ /dev/null @@ -1,76 +0,0 @@ -// This is the Node-only test harness, so "node:" imports are fine *here* — -// the guard below only restricts packages/quicktype-core/src. -import * as fs from "node:fs"; -import * as path from "node:path"; - -// Guard: quicktype-core must stay bundleable for the browser. -// -// quicktype-core's package.json declares `"browser": { "fs": false }`, which -// tells web bundlers (webpack, browserify, ...) to stub out the `fs` module. -// That mapping only matches the *bare* specifier "fs" — an import of -// "node:fs" (or any other "node:"-prefixed builtin) is NOT remapped, so it -// breaks web bundles of quicktype-core even though the code behaves the same -// under Node. This regression already happened once between 23.2.0 and -// 23.2.5: see https://github.com/glideapps/quicktype/issues/2763. -// -// This check fails the test run if any "node:"-prefixed import sneaks back -// into packages/quicktype-core/src. It is scoped to quicktype-core only: the -// CLI in the root `src/` directory is Node-only and may use "node:" imports -// freely. - -const coreSrcDir = path.join( - __dirname, - "..", - "packages", - "quicktype-core", - "src", -); - -// Matches static imports/re-exports (`from "node:fs"`), dynamic imports -// (`import("node:fs")`), and CommonJS requires (`require("node:fs")`). -const nodeImportPattern = /(?:from\s+|import\s*\(\s*|require\s*\(\s*)["']node:/; - -function findNodeImports(dir: string): string[] { - const offenders: string[] = []; - for (const entry of fs.readdirSync(dir, { withFileTypes: true })) { - const fullPath = path.join(dir, entry.name); - if (entry.isDirectory()) { - offenders.push(...findNodeImports(fullPath)); - } else if (entry.isFile() && entry.name.endsWith(".ts")) { - const lines = fs.readFileSync(fullPath, "utf8").split("\n"); - for (let i = 0; i < lines.length; i++) { - if (nodeImportPattern.test(lines[i])) { - offenders.push( - `${path.relative(path.join(__dirname, ".."), fullPath)}:${i + 1}: ${lines[i].trim()}`, - ); - } - } - } - } - - return offenders; -} - -export function checkCoreHasNoNodePrefixedImports(): void { - const offenders = findNodeImports(coreSrcDir); - if (offenders.length > 0) { - const offenderList = offenders.map((o) => ` ${o}`).join("\n"); - console.error( - `error: found "node:"-prefixed imports in packages/quicktype-core/src: - -${offenderList} - -quicktype-core must use bare builtin specifiers (e.g. "fs", not "node:fs"): -its package.json's "browser" field only stubs bare specifiers, so "node:" -imports break web bundlers. See https://github.com/glideapps/quicktype/issues/2763`, - ); - process.exit(1); - } -} - -// Allow running the check standalone: -// npx ts-node --project test/tsconfig.json test/check-no-node-imports.ts -if (require.main === module) { - checkCoreHasNoNodePrefixedImports(); - console.error('* quicktype-core has no "node:"-prefixed imports'); -} diff --git a/test/check-url-input.ts b/test/check-url-input.ts deleted file mode 100644 index 54a427de73..0000000000 --- a/test/check-url-input.ts +++ /dev/null @@ -1,141 +0,0 @@ -// Guard: URL inputs must work with the native (WHATWG) fetch on Node >= 18. -// -// quicktype-core's $fetch.ts prefers `global.fetch` when it exists. On -// Node >= 18 that is the native (undici) fetch, whose `response.body` is a -// WHATWG ReadableStream, not a Node Readable. NodeIO's readableFromFileOrURL -// used to cast that body straight to a Node Readable, so *every* URL-based -// input failed: JSON URLs with "readStream.setEncoding is not a function" -// (surfaced as "Syntax error in input JSON"), and schema URLs / remote $refs -// with "inputStream.once is not a function" (surfaced as "Could not fetch -// schema"). See issues #2613, #2678, and #2821. -// -// The fixture harness only feeds quicktype local files, so it cannot catch -// this. This check serves a JSON sample and a JSON Schema with a relative -// $ref from a local HTTP server and runs the CLI against the URLs. - -import * as fs from "node:fs"; -import * as http from "node:http"; -import type { AddressInfo } from "node:net"; -import * as os from "node:os"; -import * as path from "node:path"; - -import { main as quicktype } from "../src"; - -const files: { [name: string]: string } = { - "sample.json": JSON.stringify({ - veryUniquePropertyName: "quicktype", - count: 3, - }), - "main.schema": JSON.stringify({ - $schema: "http://json-schema.org/draft-07/schema#", - type: "object", - properties: { - referenced: { $ref: "referenced.schema" }, - }, - required: ["referenced"], - }), - "referenced.schema": JSON.stringify({ - $schema: "http://json-schema.org/draft-07/schema#", - type: "object", - properties: { - veryUniqueReferencedProperty: { type: "string" }, - }, - required: ["veryUniqueReferencedProperty"], - }), -}; - -async function generateTypeScript( - baseURL: string, - srcLang: string, - file: string, -): Promise { - const outDir = fs.mkdtempSync(path.join(os.tmpdir(), "quicktype-url-")); - const outPath = path.join(outDir, "out.ts"); - try { - await quicktype({ - srcLang, - src: [`${baseURL}/${file}`], - lang: "typescript", - out: outPath, - topLevel: "TopLevel", - quiet: true, - telemetry: "disable", - }); - return fs.readFileSync(outPath, "utf8"); - } finally { - fs.rmSync(outDir, { recursive: true, force: true }); - } -} - -export async function checkURLInput(): Promise { - const server = http.createServer((req, res) => { - const content = files[path.basename(req.url ?? "")]; - if (content === undefined) { - res.writeHead(404); - res.end(); - return; - } - res.writeHead(200, { "Content-Type": "application/json" }); - res.end(content); - }); - await new Promise((resolve) => - server.listen(0, "127.0.0.1", resolve), - ); - const { port } = server.address() as AddressInfo; - const baseURL = `http://127.0.0.1:${port}`; - - const failures: string[] = []; - try { - try { - const json = await generateTypeScript( - baseURL, - "json", - "sample.json", - ); - if (!json.includes("veryUniquePropertyName")) { - failures.push( - ` JSON from URL: output lacks the sample's property:\n${json}`, - ); - } - } catch (e) { - failures.push(` JSON from URL: quicktype threw: ${e}`); - } - - try { - const schema = await generateTypeScript( - baseURL, - "schema", - "main.schema", - ); - if (!schema.includes("veryUniqueReferencedProperty")) { - failures.push( - ` schema from URL: output lacks the $ref-ed schema's property:\n${schema}`, - ); - } - } catch (e) { - failures.push(` schema from URL: quicktype threw: ${e}`); - } - } finally { - server.close(); - } - - if (failures.length > 0) { - console.error( - `error: URL inputs must work with the native fetch on Node >= 18 (issues #2613, #2678, #2821): - -${failures.join("\n")} - -readableFromFileOrURL must convert fetch's WHATWG ReadableStream body into a -Node-style Readable — see packages/quicktype-core/src/input/io/NodeIO.ts`, - ); - process.exit(1); - } -} - -// Allow running the check standalone: -// NODE_PATH=`pwd`/node_modules npx ts-node --project test/tsconfig.json test/check-url-input.ts -if (require.main === module) { - checkURLInput().then(() => { - console.error("* URL inputs work with the native fetch"); - }); -} diff --git a/test/fixtures/javascript-prop-types/main.js b/test/fixtures/javascript-prop-types/main.js index 36febff60b..2bba909e6e 100644 --- a/test/fixtures/javascript-prop-types/main.js +++ b/test/fixtures/javascript-prop-types/main.js @@ -1,21 +1,25 @@ -import { readFileSync } from "fs"; -import { argv } from "process"; +import { readFileSync } from "node:fs"; +import { argv } from "node:process"; +import PropTypes from "prop-types"; import { TopLevel } from "./toplevel.js"; -import checkPropTypes from "check-prop-types"; const sample = argv[2]; const json = readFileSync(sample); const obj = JSON.parse(json); -const results = checkPropTypes( - { obj: TopLevel }, - { obj }, - "prop", - "MyComponent", -); +const errors = []; +const originalConsoleError = console.error; +console.error = (...args) => errors.push(args.join(" ")); -if (results) { - console.log("Failure:", results); +try { + PropTypes.resetWarningCache(); + PropTypes.checkPropTypes({ obj: TopLevel }, { obj }, "prop", "MyComponent"); +} finally { + console.error = originalConsoleError; +} + +if (errors.length > 0) { + console.log("Failure:", errors.join("\n")); } else { console.log("Success"); } diff --git a/test/fixtures/javascript-prop-types/package-lock.json b/test/fixtures/javascript-prop-types/package-lock.json index 28386aacfa..895cf2b898 100644 --- a/test/fixtures/javascript-prop-types/package-lock.json +++ b/test/fixtures/javascript-prop-types/package-lock.json @@ -1,330 +1,95 @@ { - "name": "javascript-prop-types", - "version": "0.1.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "javascript-prop-types", - "version": "0.1.0", - "license": "Apache-2.0", - "dependencies": { - "check-prop-types": "^1.1.2" - } - }, - "node_modules/asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "peer": true - }, - "node_modules/check-prop-types": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/check-prop-types/-/check-prop-types-1.1.2.tgz", - "integrity": "sha512-hGDrZ1yhRgKuP1yzZ5sUX/PPmlKBLOF1GyF0Z008Sienko3BFZmlCXnmq+npRTIL/WlFCUzThyd+F5PQnnT1ug==", - "peerDependencies": { - "prop-types": "<=15.6.0" - } - }, - "node_modules/core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "peer": true - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "peer": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/fbjs": { - "version": "0.8.18", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz", - "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==", - "peer": true, - "dependencies": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.30" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "peer": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", - "peer": true, - "dependencies": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "peer": true, - "dependencies": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "peer": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "peer": true, - "dependencies": { - "asap": "~2.0.3" - } - }, - "node_modules/prop-types": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", - "integrity": "sha512-H16NHdiZ8szYSKNkCpmKmS8BCogxyABjJ1AqQknIY2iTpy1xC04egoBAzjKm+WU2pbuNxFonw921dnxR0QYAdw==", - "peer": true, - "dependencies": { - "fbjs": "^0.8.16", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "peer": true - }, - "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==", - "peer": true - }, - "node_modules/ua-parser-js": { - "version": "0.7.32", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", - "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/ua-parser-js" + "name": "javascript-prop-types", + "version": "0.1.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "javascript-prop-types", + "version": "0.1.0", + "license": "Apache-2.0", + "dependencies": { + "prop-types": "^15.8.1" + } }, - { - "type": "paypal", - "url": "https://paypal.me/faisalman" + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "license": "MIT" + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "license": "MIT" } - ], - "peer": true, - "engines": { - "node": "*" - } - }, - "node_modules/whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", - "peer": true - } - }, - "dependencies": { - "asap": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", - "integrity": "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==", - "peer": true - }, - "check-prop-types": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/check-prop-types/-/check-prop-types-1.1.2.tgz", - "integrity": "sha512-hGDrZ1yhRgKuP1yzZ5sUX/PPmlKBLOF1GyF0Z008Sienko3BFZmlCXnmq+npRTIL/WlFCUzThyd+F5PQnnT1ug==", - "requires": {} - }, - "core-js": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", - "integrity": "sha512-ZiPp9pZlgxpWRu0M+YWbm6+aQ84XEfH1JRXvfOc/fILWI0VKhLC2LX13X1NYq4fULzLMq7Hfh43CSo2/aIaUPA==", - "peer": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "peer": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "fbjs": { - "version": "0.8.18", - "resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.18.tgz", - "integrity": "sha512-EQaWFK+fEPSoibjNy8IxUtaFOMXcWsY0JaVrQoZR9zC8N2Ygf9iDITPWjUTVIax95b6I742JFLqASHfsag/vKA==", - "peer": true, - "requires": { - "core-js": "^1.0.0", - "isomorphic-fetch": "^2.1.1", - "loose-envify": "^1.0.0", - "object-assign": "^4.1.0", - "promise": "^7.1.1", - "setimmediate": "^1.0.5", - "ua-parser-js": "^0.7.30" - } - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "peer": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", - "peer": true - }, - "isomorphic-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz", - "integrity": "sha512-9c4TNAKYXM5PRyVcwUZrF3W09nQ+sO7+jydgs4ZGW9dhsLG2VOlISJABombdQqQRXCwuYG3sYV/puGf5rp0qmA==", - "peer": true, - "requires": { - "node-fetch": "^1.0.1", - "whatwg-fetch": ">=0.10.0" - } - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "peer": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "peer": true, - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "node-fetch": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz", - "integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==", - "peer": true, - "requires": { - "encoding": "^0.1.11", - "is-stream": "^1.0.1" - } }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "peer": true - }, - "promise": { - "version": "7.3.1", - "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz", - "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==", - "peer": true, - "requires": { - "asap": "~2.0.3" - } - }, - "prop-types": { - "version": "15.6.0", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz", - "integrity": "sha512-H16NHdiZ8szYSKNkCpmKmS8BCogxyABjJ1AqQknIY2iTpy1xC04egoBAzjKm+WU2pbuNxFonw921dnxR0QYAdw==", - "peer": true, - "requires": { - "fbjs": "^0.8.16", - "loose-envify": "^1.3.1", - "object-assign": "^4.1.1" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "peer": true - }, - "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==", - "peer": true - }, - "ua-parser-js": { - "version": "0.7.32", - "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.32.tgz", - "integrity": "sha512-f9BESNVhzlhEFf2CHMSj40NWOjYPl1YKYbrvIr/hFTDEmLq7SRbWvm7FcdcpCYT95zrOhC7gZSxjdnnTpBcwVw==", - "peer": true - }, - "whatwg-fetch": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz", - "integrity": "sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA==", - "peer": true + "dependencies": { + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } } - } } diff --git a/test/fixtures/javascript-prop-types/package.json b/test/fixtures/javascript-prop-types/package.json index 91b5d9b092..1c019133d2 100644 --- a/test/fixtures/javascript-prop-types/package.json +++ b/test/fixtures/javascript-prop-types/package.json @@ -10,6 +10,6 @@ "author": "", "license": "Apache-2.0", "dependencies": { - "check-prop-types": "^1.1.2" + "prop-types": "^15.8.1" } } diff --git a/test/test.ts b/test/test.ts index e3e5ddf760..f25c371b0f 100755 --- a/test/test.ts +++ b/test/test.ts @@ -1,16 +1,10 @@ -import cluster from "node:cluster"; - -import * as os from "os"; +import * as os from "node:os"; import * as _ from "lodash"; -import { inParallel } from "./lib/multicore"; -import { execAsync, type Sample } from "./utils"; -import { type Fixture, allFixtures } from "./fixtures"; import { affectedFixtures, divideParallelJobs } from "./buildkite"; -import { checkCoreImportKeepsStdoutClean } from "./check-clean-import"; -import { checkJavaEnumAcronymCasing } from "./check-java-acronym-names"; -import { checkCoreHasNoNodePrefixedImports } from "./check-no-node-imports"; -import { checkURLInput } from "./check-url-input"; +import { type Fixture, allFixtures } from "./fixtures"; +import { inParallel } from "./lib/multicore"; +import { type Sample, execAsync } from "./utils"; const exit = require("exit"); const CPUs = Number.parseInt(process.env.CPUs || "0", 10) || os.cpus().length; @@ -22,31 +16,6 @@ const CPUs = Number.parseInt(process.env.CPUs || "0", 10) || os.cpus().length; export type WorkItem = { sample: Sample; fixtureName: string }; async function main(sources: string[]) { - // Cheap sanity check, run before any fixture: quicktype-core must not - // use "node:"-prefixed imports or it breaks web bundlers (issue #2763). - checkCoreHasNoNodePrefixedImports(); - - // Regression check for issue #2874: importing the built quicktype-core - // must not write to stdout — CI builds used to swap in a fetch shim that - // printed a banner on import, corrupting redirected CLI output. - checkCoreImportKeepsStdoutClean(); - - // Regression check for issue #2850: Java enum constants must keep - // acronyms uppercase for every --acronym-style. The fixture harness - // can't catch this (mangled constants still compile and round-trip). - await checkJavaEnumAcronymCasing(); - - // Regression check for issues #2613, #2678, #2821: URL inputs must work - // with the native (WHATWG) fetch on Node >= 18. The fixture harness only - // uses local files, so it can't catch this. Only run it in the cluster - // primary: forked workers re-execute main() too, and in a cluster worker - // `server.listen(0)` gives every worker the *same* shared port, with - // connections round-robined between them — concurrent workers cross-talk - // and hit each others' closing servers. - if (cluster.isPrimary) { - await checkURLInput(); - } - let fixtures = affectedFixtures(); const fixturesFromCmdline = process.env.FIXTURE; if (fixturesFromCmdline) { @@ -94,8 +63,8 @@ async function main(sources: string[]) { ); for (const fixture of fixtures) { - await execAsync(`rm -rf test/runs`); - await execAsync(`mkdir -p test/runs`); + await execAsync("rm -rf test/runs"); + await execAsync("mkdir -p test/runs"); await fixture.setup(); } diff --git a/test/tsconfig.json b/test/tsconfig.json index a042b47f70..00ab6ac191 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@tsconfig/node18/tsconfig.json", + "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { "strict": true, "alwaysStrict": true, @@ -7,5 +7,5 @@ "noUnusedParameters": true, "resolveJsonModule": true }, - "include": ["*.ts", "../dist/*.js", "../dist/*.d.ts"] + "include": ["*.ts", "unit/**/*.ts", "../dist/*.js", "../dist/*.d.ts"] } diff --git a/test/unit/core-package.test.ts b/test/unit/core-package.test.ts new file mode 100644 index 0000000000..01da64ce83 --- /dev/null +++ b/test/unit/core-package.test.ts @@ -0,0 +1,53 @@ +import { execFileSync } from "node:child_process"; +import * as fs from "node:fs"; +import * as path from "node:path"; + +import { describe, expect, test } from "vitest"; + +const repositoryRoot = process.cwd(); +const coreDirectory = path.join(repositoryRoot, "packages", "quicktype-core"); +const coreSourceDirectory = path.join(coreDirectory, "src"); +const nodeImportPattern = /(?:from\s+|import\s*\(\s*|require\s*\(\s*)["']node:/; + +function findNodeImports(directory: string): string[] { + const offenders: string[] = []; + + for (const entry of fs.readdirSync(directory, { withFileTypes: true })) { + const fullPath = path.join(directory, entry.name); + if (entry.isDirectory()) { + offenders.push(...findNodeImports(fullPath)); + continue; + } + + if (!entry.isFile() || !entry.name.endsWith(".ts")) { + continue; + } + + const lines = fs.readFileSync(fullPath, "utf8").split("\n"); + for (let index = 0; index < lines.length; index++) { + if (nodeImportPattern.test(lines[index])) { + offenders.push( + `${path.relative(repositoryRoot, fullPath)}:${index + 1}: ${lines[index].trim()}`, + ); + } + } + } + + return offenders; +} + +describe("quicktype-core package", () => { + test("does not write to stdout when imported", () => { + const stdout = execFileSync( + process.execPath, + ["-e", `require(${JSON.stringify(coreDirectory)});`], + { encoding: "utf8" }, + ); + + expect(stdout).toBe(""); + }); + + test("does not use node:-prefixed imports in browser-compatible source", () => { + expect(findNodeImports(coreSourceDirectory)).toEqual([]); + }); +}); diff --git a/test/unit/graphql-introspection.test.ts b/test/unit/graphql-introspection.test.ts new file mode 100644 index 0000000000..a0ed7f212e --- /dev/null +++ b/test/unit/graphql-introspection.test.ts @@ -0,0 +1,73 @@ +import * as http from "node:http"; +import type { AddressInfo } from "node:net"; + +import { describe, expect, test } from "vitest"; + +import { introspectServer } from "../../src/GraphQLIntrospection"; + +describe("GraphQL introspection with native fetch", () => { + test("posts the introspection query and forwards custom headers", async () => { + let receivedRequest: + | { + method: string | undefined; + headers: http.IncomingHttpHeaders; + body: string; + } + | undefined; + + const server = http.createServer((request, response) => { + const chunks: Buffer[] = []; + request.on("data", (chunk: Buffer) => chunks.push(chunk)); + request.on("end", () => { + receivedRequest = { + method: request.method, + headers: request.headers, + body: Buffer.concat(chunks).toString("utf8"), + }; + response.writeHead(200, { + "Content-Type": "application/json", + }); + response.end( + JSON.stringify({ + data: { + __schema: { queryType: { name: "Query" } }, + }, + }), + ); + }); + }); + + await new Promise((resolve) => + server.listen(0, "127.0.0.1", resolve), + ); + const { port } = server.address() as AddressInfo; + + try { + const result = await introspectServer( + `http://127.0.0.1:${port}/graphql`, + "POST", + ["Authorization: Bearer test-token"], + ); + + expect(JSON.parse(result)).toMatchObject({ + data: { __schema: { queryType: { name: "Query" } } }, + }); + expect(receivedRequest?.method).toBe("POST"); + expect(receivedRequest?.headers.authorization).toBe( + "Bearer test-token", + ); + expect(receivedRequest?.headers["content-type"]).toBe( + "application/json", + ); + expect(JSON.parse(receivedRequest?.body ?? "{}").query).toContain( + "__schema", + ); + } finally { + await new Promise((resolve, reject) => + server.close((error) => + error === undefined ? resolve() : reject(error), + ), + ); + } + }); +}); diff --git a/test/unit/java-acronym-names.test.ts b/test/unit/java-acronym-names.test.ts new file mode 100644 index 0000000000..29a5162bed --- /dev/null +++ b/test/unit/java-acronym-names.test.ts @@ -0,0 +1,48 @@ +import { InputData, JSONSchemaInput, quicktype } from "quicktype-core"; +import { describe, expect, test } from "vitest"; + +const enumValue = "MULTI_SPA_IN_GROUP_REJECTED"; +const schema = JSON.stringify({ + $schema: "http://json-schema.org/draft-06/schema#", + type: "object", + properties: { + messageCode: { + type: "string", + enum: [enumValue], + }, + }, + required: ["messageCode"], +}); + +async function javaEnumConstantIdentifier( + acronymStyle: string, +): Promise { + const schemaInput = new JSONSchemaInput(undefined); + await schemaInput.addSource({ name: "TopLevel", schema }); + const inputData = new InputData(); + inputData.addInput(schemaInput); + + const result = await quicktype({ + inputData, + lang: "java", + rendererOptions: { "acronym-style": acronymStyle }, + }); + const output = result.lines.join("\n"); + const match = output.match( + new RegExp(`case (\\w+): return "${enumValue}";`), + ); + + expect(match, `generated Java output:\n${output}`).not.toBeNull(); + return match?.[1] ?? ""; +} + +describe("Java enum acronym casing", () => { + test.each(["original", "pascal", "camel", "lowerCase"])( + "keeps acronyms uppercase with acronym-style=%s", + async (acronymStyle) => { + await expect( + javaEnumConstantIdentifier(acronymStyle), + ).resolves.toBe(enumValue); + }, + ); +}); diff --git a/test/unit/url-input.test.ts b/test/unit/url-input.test.ts new file mode 100644 index 0000000000..f709d0803c --- /dev/null +++ b/test/unit/url-input.test.ts @@ -0,0 +1,99 @@ +import * as fs from "node:fs"; +import * as http from "node:http"; +import type { AddressInfo } from "node:net"; +import * as os from "node:os"; +import * as path from "node:path"; + +import { afterAll, beforeAll, describe, expect, test } from "vitest"; + +import { main as quicktype } from "../../src"; + +const files: Record = { + "sample.json": JSON.stringify({ + veryUniquePropertyName: "quicktype", + count: 3, + }), + "main.schema": JSON.stringify({ + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + referenced: { $ref: "referenced.schema" }, + }, + required: ["referenced"], + }), + "referenced.schema": JSON.stringify({ + $schema: "http://json-schema.org/draft-07/schema#", + type: "object", + properties: { + veryUniqueReferencedProperty: { type: "string" }, + }, + required: ["veryUniqueReferencedProperty"], + }), +}; + +let server: http.Server; +let baseURL: string; + +async function generateTypeScript( + sourceLanguage: string, + filename: string, +): Promise { + const outputDirectory = fs.mkdtempSync( + path.join(os.tmpdir(), "quicktype-url-"), + ); + const outputPath = path.join(outputDirectory, "out.ts"); + + try { + await quicktype({ + srcLang: sourceLanguage, + src: [`${baseURL}/${filename}`], + lang: "typescript", + out: outputPath, + topLevel: "TopLevel", + quiet: true, + telemetry: "disable", + }); + return fs.readFileSync(outputPath, "utf8"); + } finally { + fs.rmSync(outputDirectory, { recursive: true, force: true }); + } +} + +beforeAll(async () => { + server = http.createServer((request, response) => { + const content = files[path.basename(request.url ?? "")]; + if (content === undefined) { + response.writeHead(404); + response.end(); + return; + } + + response.writeHead(200, { "Content-Type": "application/json" }); + response.end(content); + }); + await new Promise((resolve) => + server.listen(0, "127.0.0.1", resolve), + ); + const { port } = server.address() as AddressInfo; + baseURL = `http://127.0.0.1:${port}`; +}); + +afterAll(async () => { + await new Promise((resolve, reject) => + server.close((error) => + error === undefined ? resolve() : reject(error), + ), + ); +}); + +describe("native fetch URL inputs", () => { + test("generates types from a JSON URL", async () => { + const output = await generateTypeScript("json", "sample.json"); + expect(output).toContain("veryUniquePropertyName"); + }); + + test("resolves a relative remote JSON Schema reference", async () => { + const output = await generateTypeScript("schema", "main.schema"); + expect(output).toContain("veryUniqueReferencedProperty"); + }); +}); diff --git a/tsconfig.json b/tsconfig.json index 4f1446d5e8..478579a602 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,5 +1,5 @@ { - "extends": "@tsconfig/node18/tsconfig.json", + "extends": "@tsconfig/node20/tsconfig.json", "compilerOptions": { "lib": ["ES2022", "dom"], "allowJs": false, diff --git a/vitest.config.ts b/vitest.config.ts new file mode 100644 index 0000000000..9865b9fdd4 --- /dev/null +++ b/vitest.config.ts @@ -0,0 +1,9 @@ +import { defineConfig } from "vitest/config"; + +export default defineConfig({ + test: { + environment: "node", + include: ["test/unit/**/*.test.ts"], + testTimeout: 30_000, + }, +}); From bbab8af60a90a3f0699e341947b5b96740f6d085 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Thu, 9 Jul 2026 15:00:59 -0400 Subject: [PATCH 2/5] Fix npm 10 lockfile compatibility --- package-lock.json | 512 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 512 insertions(+) diff --git a/package-lock.json b/package-lock.json index 47a4f4fe76..d9d19e81a2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -316,6 +316,456 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", + "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", + "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", + "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", + "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", + "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", + "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", + "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", + "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", + "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", + "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", + "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", + "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", + "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", + "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", + "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", + "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", + "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", + "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", + "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", + "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", + "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", + "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", + "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", + "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", + "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, "node_modules/@esbuild/win32-x64": { "version": "0.20.2", "cpu": [ @@ -7415,6 +7865,24 @@ } } }, + "node_modules/vitest/node_modules/@esbuild/win32-x64": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", + "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "peer": true, + "engines": { + "node": ">=18" + } + }, "node_modules/vitest/node_modules/@vitest/mocker": { "version": "4.1.10", "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-4.1.10.tgz", @@ -7442,6 +7910,50 @@ } } }, + "node_modules/vitest/node_modules/esbuild": { + "version": "0.28.1", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", + "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "peer": true, + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.28.1", + "@esbuild/android-arm": "0.28.1", + "@esbuild/android-arm64": "0.28.1", + "@esbuild/android-x64": "0.28.1", + "@esbuild/darwin-arm64": "0.28.1", + "@esbuild/darwin-x64": "0.28.1", + "@esbuild/freebsd-arm64": "0.28.1", + "@esbuild/freebsd-x64": "0.28.1", + "@esbuild/linux-arm": "0.28.1", + "@esbuild/linux-arm64": "0.28.1", + "@esbuild/linux-ia32": "0.28.1", + "@esbuild/linux-loong64": "0.28.1", + "@esbuild/linux-mips64el": "0.28.1", + "@esbuild/linux-ppc64": "0.28.1", + "@esbuild/linux-riscv64": "0.28.1", + "@esbuild/linux-s390x": "0.28.1", + "@esbuild/linux-x64": "0.28.1", + "@esbuild/netbsd-arm64": "0.28.1", + "@esbuild/netbsd-x64": "0.28.1", + "@esbuild/openbsd-arm64": "0.28.1", + "@esbuild/openbsd-x64": "0.28.1", + "@esbuild/openharmony-arm64": "0.28.1", + "@esbuild/sunos-x64": "0.28.1", + "@esbuild/win32-arm64": "0.28.1", + "@esbuild/win32-ia32": "0.28.1", + "@esbuild/win32-x64": "0.28.1" + } + }, "node_modules/vitest/node_modules/magic-string": { "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", From 64b2200485ad5f0cd132c5be3d4830ba96f5e1af Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Fri, 10 Jul 2026 09:36:40 -0400 Subject: [PATCH 3/5] Address review feedback - Port the rationale comments from the deleted standalone checks into the migrated Vitest tests, including the issue links. - Guard the javascript-prop-types fixture against prop-types' production no-op shims with a sentinel self-check. - Remove the unused node_modules_key/source_key cache keys from the setup action. Co-Authored-By: Claude Fable 5 --- .github/workflows/setup/action.yaml | 9 --------- test/fixtures/javascript-prop-types/main.js | 20 ++++++++++++++++++- test/unit/core-package.test.ts | 17 ++++++++++++++++ test/unit/java-acronym-names.test.ts | 22 +++++++++++++++++++++ test/unit/url-input.test.ts | 13 ++++++++++++ 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/.github/workflows/setup/action.yaml b/.github/workflows/setup/action.yaml index db864c513e..083e4bdc66 100644 --- a/.github/workflows/setup/action.yaml +++ b/.github/workflows/setup/action.yaml @@ -17,15 +17,6 @@ runs: fi echo "node_version=$NODE_VERSION" >> $GITHUB_ENV - # Create keys to control caching - BASE_KEY="${{ runner.os }}" - - NODE_MODULES_KEY="$BASE_KEY-${{ hashFiles('package-lock.json') }}" - echo "node_modules_key=$NODE_MODULES_KEY" >> $GITHUB_ENV - - SOURCE_KEY="$NODE_MODULES_KEY-${{ hashFiles('src/**') }}" - echo "source_key=$SOURCE_KEY" >> $GITHUB_ENV - - name: Setup node uses: actions/setup-node@v4 with: diff --git a/test/fixtures/javascript-prop-types/main.js b/test/fixtures/javascript-prop-types/main.js index 2bba909e6e..a8795f3f90 100644 --- a/test/fixtures/javascript-prop-types/main.js +++ b/test/fixtures/javascript-prop-types/main.js @@ -11,14 +11,32 @@ const errors = []; const originalConsoleError = console.error; console.error = (...args) => errors.push(args.join(" ")); +let checkerWorks = false; try { + // With NODE_ENV=production, prop-types exports no-op shims, which would + // make every sample "succeed". Prove the checker reports errors before + // trusting its silence. + PropTypes.resetWarningCache(); + PropTypes.checkPropTypes( + { sentinel: PropTypes.string.isRequired }, + {}, + "prop", + "SelfTest", + ); + checkerWorks = errors.length > 0; + errors.length = 0; + PropTypes.resetWarningCache(); PropTypes.checkPropTypes({ obj: TopLevel }, { obj }, "prop", "MyComponent"); } finally { console.error = originalConsoleError; } -if (errors.length > 0) { +if (!checkerWorks) { + console.log( + "Failure: prop-types checks are disabled (NODE_ENV=production?)", + ); +} else if (errors.length > 0) { console.log("Failure:", errors.join("\n")); } else { console.log("Success"); diff --git a/test/unit/core-package.test.ts b/test/unit/core-package.test.ts index 01da64ce83..9da254d2ad 100644 --- a/test/unit/core-package.test.ts +++ b/test/unit/core-package.test.ts @@ -7,6 +7,9 @@ import { describe, expect, test } from "vitest"; const repositoryRoot = process.cwd(); const coreDirectory = path.join(repositoryRoot, "packages", "quicktype-core"); const coreSourceDirectory = path.join(coreDirectory, "src"); + +// Matches static imports/re-exports (`from "node:fs"`), dynamic imports +// (`import("node:fs")`), and CommonJS requires (`require("node:fs")`). const nodeImportPattern = /(?:from\s+|import\s*\(\s*|require\s*\(\s*)["']node:/; function findNodeImports(directory: string): string[] { @@ -37,6 +40,11 @@ function findNodeImports(directory: string): string[] { } describe("quicktype-core package", () => { + // Importing the built quicktype-core must not print anything: CLI users + // redirect stdout (`quicktype ... > out.ts`), so any stray output + // corrupts generated code. A CI-only fetch shim with a top-level + // console.info shipped in every published package from 23.3.1 until the + // fix — see https://github.com/glideapps/quicktype/issues/2874. test("does not write to stdout when imported", () => { const stdout = execFileSync( process.execPath, @@ -47,6 +55,15 @@ describe("quicktype-core package", () => { expect(stdout).toBe(""); }); + // quicktype-core must stay bundleable for the browser: its package.json + // declares `"browser": { "fs": false }`, which tells web bundlers to stub + // out the `fs` module — but that mapping only matches the *bare* + // specifier "fs". A "node:"-prefixed import is NOT remapped, so it breaks + // web bundles even though Node behaves the same. This regressed once + // between 23.2.0 and 23.2.5 — see + // https://github.com/glideapps/quicktype/issues/2763. The guard is scoped + // to quicktype-core; the CLI in the root src/ directory is Node-only and + // may use "node:" imports freely. test("does not use node:-prefixed imports in browser-compatible source", () => { expect(findNodeImports(coreSourceDirectory)).toEqual([]); }); diff --git a/test/unit/java-acronym-names.test.ts b/test/unit/java-acronym-names.test.ts index 29a5162bed..a48a13b4d1 100644 --- a/test/unit/java-acronym-names.test.ts +++ b/test/unit/java-acronym-names.test.ts @@ -1,6 +1,26 @@ +// Java enum constants must keep acronyms uppercase for every --acronym-style +// setting. They are rendered in UPPER_UNDERSCORE style, but before the fix in +// https://github.com/glideapps/quicktype/pull/2851 (issue #2850) the +// acronym-style option was still applied to words recognized as acronyms +// (e.g. "SPA"), so with --acronym-style=camel the JSON enum value +// "MULTI_SPA_IN_GROUP_REJECTED" produced the constant +// "MULTI_Spa_IN_GROUP_REJECTED" (and "MULTI_spa_IN_GROUP_REJECTED" with +// lowerCase). +// +// The fixture harness cannot catch this: the mangled constants are +// self-consistent identifiers, so the generated code still compiles, and +// (de)serialization uses the raw JSON names, so round-tripping succeeds. +// This test instead generates Java code directly and asserts on the emitted +// *identifier*. Note that we must NOT just check that the output contains +// "MULTI_SPA_IN_GROUP_REJECTED" — the raw JSON name always appears in the +// string literals of toValue()/forValue(), even when the identifier is +// mangled. + import { InputData, JSONSchemaInput, quicktype } from "quicktype-core"; import { describe, expect, test } from "vitest"; +// "spa" is a known acronym (see Acronyms.const.ts), so acronym styling would +// apply to the SPA word if the fix regressed. const enumValue = "MULTI_SPA_IN_GROUP_REJECTED"; const schema = JSON.stringify({ $schema: "http://json-schema.org/draft-06/schema#", @@ -28,6 +48,8 @@ async function javaEnumConstantIdentifier( rendererOptions: { "acronym-style": acronymStyle }, }); const output = result.lines.join("\n"); + // Matches e.g. `case MULTI_SPA_IN_GROUP_REJECTED: return "MULTI_SPA_IN_GROUP_REJECTED";` + // in the generated MessageCode.toValue() — the capture is the identifier. const match = output.match( new RegExp(`case (\\w+): return "${enumValue}";`), ); diff --git a/test/unit/url-input.test.ts b/test/unit/url-input.test.ts index f709d0803c..eeb17002c0 100644 --- a/test/unit/url-input.test.ts +++ b/test/unit/url-input.test.ts @@ -1,3 +1,16 @@ +// URL inputs must work with the native (WHATWG) fetch. Its `response.body` +// is a WHATWG ReadableStream, not a Node Readable, and NodeIO's +// readableFromFileOrURL used to cast that body straight to a Node Readable, +// so *every* URL-based input failed: JSON URLs with "readStream.setEncoding +// is not a function" (surfaced as "Syntax error in input JSON"), and schema +// URLs / remote $refs with "inputStream.once is not a function" (surfaced as +// "Could not fetch schema"). See issues #2613, #2678, and #2821, and the +// stream wrapping in packages/quicktype-core/src/input/io/NodeIO.ts. +// +// The fixture harness only feeds quicktype local files, so it cannot catch +// this. These tests serve a JSON sample and a JSON Schema with a relative +// $ref from a local HTTP server and run quicktype against the URLs. + import * as fs from "node:fs"; import * as http from "node:http"; import type { AddressInfo } from "node:net"; From 2584bf2198c5ee31ce10328d3b7c47229a0baf2b Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Fri, 10 Jul 2026 10:38:29 -0400 Subject: [PATCH 4/5] Update test commands in README and COMMENT-INJECTION docs npm test now runs the Vitest unit suite before the fixture harness, so the documented FIXTURE=... npm test forms were misleading. Point them at npm run test:fixtures and mention npm run test:unit. Co-Authored-By: Claude Fable 5 --- COMMENT-INJECTION.md | 2 +- README.md | 13 ++++++++----- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/COMMENT-INJECTION.md b/COMMENT-INJECTION.md index 2f96d814ed..5f2f77db5f 100644 --- a/COMMENT-INJECTION.md +++ b/COMMENT-INJECTION.md @@ -19,7 +19,7 @@ The schema puts comment-closing text in both an object `description` and a prope Run: ```bash -CPUs=1 QUICKTEST=true FIXTURE=schema-typescript npm test -- test/inputs/schema/comment-injection.schema +CPUs=1 QUICKTEST=true FIXTURE=schema-typescript npm run test:fixtures -- test/inputs/schema/comment-injection.schema ``` Expected result: the generated TypeScript validates `comment-injection.1.json` and prints equivalent JSON. diff --git a/README.md b/README.md index 46946907fc..b05d7a06a7 100644 --- a/README.md +++ b/README.md @@ -249,13 +249,16 @@ files, URLs, or add other options. ### Test ```bash -# Run full test suite -npm run test +# Run full test suite (unit tests plus all fixtures) +npm test + +# Run only the Vitest unit tests +npm run test:unit # Test a specific language (see test/languages.ts) -FIXTURE=golang npm test +FIXTURE=golang npm run test:fixtures # Test a single sample or directory -FIXTURE=swift npm test -- pokedex.json -FIXTURE=swift npm test -- test/inputs/json/samples +FIXTURE=swift npm run test:fixtures -- pokedex.json +FIXTURE=swift npm run test:fixtures -- test/inputs/json/samples ``` From 4188aae8c9512019727e1c1454ec0a689ab30e48 Mon Sep 17 00:00:00 2001 From: Mark Probst Date: Fri, 10 Jul 2026 11:54:56 -0400 Subject: [PATCH 5/5] Link migration guide from README --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b05d7a06a7..d2ea677bc7 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,8 @@ _Missing your favorite language? Please implement it!_ There are many ways to use `quicktype`. [app.quicktype.io](https://app.quicktype.io) is the most powerful and complete UI. The web app also works offline and doesn't send your sample data over the Internet, so paste away! -The quicktype CLI and Node.js packages require Node.js 20 or newer. +The quicktype CLI and Node.js packages require Node.js 20 or newer. See +[Migrating to quicktype 24](MIGRATING.md) for upgrade details. For the best CLI, we recommend installing `quicktype` globally via `npm`: