From 3cb0f4218c4f88cb526b69deedda0476a9acc111 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 00:17:58 +0800 Subject: [PATCH 01/10] chore: harden cross-package quality checks --- .codex/skills/tat-change-triage/SKILL.md | 9 + .codex/skills/tat-contract-guard/SKILL.md | 15 + .codex/skills/tat-harness-engineer/SKILL.md | 10 + .codex/skills/tat-release-check/SKILL.md | 10 + .github/workflows/ci.yml | 30 +- .github/workflows/examples-ci.yml | 3 +- .github/workflows/publish-npm.yml | 19 +- .github/workflows/publish-vscode.yml | 16 +- .gitignore | 1 + AGENTS.md | 31 +- README.md | 4 + ...ry-resolution-and-extension-assumptions.md | 26 + Rules/project-tat-cli-exit-codes.md | 24 + Rules/project-tat-json-result-contract.md | 21 + Rules/project-tat-schema-compatibility.md | 26 + package-lock.json | 4410 +++++++++++++++++ package.json | 18 + packages/tat-shared/package.json | 13 + packages/tat-shared/src/contracts.ts | 46 + packages/tat-shared/src/fileFormat.ts | 31 + packages/tat-shared/src/index.ts | 2 + packages/tat-shared/tests/contracts.test.ts | 86 + packages/tat-shared/tsconfig.json | 19 + scripts/smoke-packaged-cli.mjs | 86 + tat-cli/package.json | 1 + tat-cli/src/fileFormat.ts | 34 +- tat-cli/src/types.ts | 42 +- .../contracts/cli-extension.contract.test.ts | 193 + .../contracts/fixtures/contract-fail.tat.yml | 11 + .../fixtures/contract-filter.tat.yaml | 14 + .../contracts/fixtures/contract-pass.tat.json | 27 + tests/contracts/fixtures/invalid.tat.json | 15 + .../contracts/fixtures/request-error.tat.yaml | 8 + vscode-extension/CLAUDE.md | 14 +- vscode-extension/package.json | 5 +- vscode-extension/src/fileParser.ts | 22 +- vscode-extension/src/promptVariables.ts | 12 +- vscode-extension/src/tatRunner.ts | 15 +- vscode-extension/src/types.ts | 4 +- vscode-extension/tests/tatOutput.test.ts | 51 + 40 files changed, 5278 insertions(+), 146 deletions(-) create mode 100644 .codex/skills/tat-change-triage/SKILL.md create mode 100644 .codex/skills/tat-contract-guard/SKILL.md create mode 100644 .codex/skills/tat-harness-engineer/SKILL.md create mode 100644 .codex/skills/tat-release-check/SKILL.md create mode 100644 Rules/project-tat-binary-resolution-and-extension-assumptions.md create mode 100644 Rules/project-tat-cli-exit-codes.md create mode 100644 Rules/project-tat-json-result-contract.md create mode 100644 Rules/project-tat-schema-compatibility.md create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 packages/tat-shared/package.json create mode 100644 packages/tat-shared/src/contracts.ts create mode 100644 packages/tat-shared/src/fileFormat.ts create mode 100644 packages/tat-shared/src/index.ts create mode 100644 packages/tat-shared/tests/contracts.test.ts create mode 100644 packages/tat-shared/tsconfig.json create mode 100644 scripts/smoke-packaged-cli.mjs create mode 100644 tests/contracts/cli-extension.contract.test.ts create mode 100644 tests/contracts/fixtures/contract-fail.tat.yml create mode 100644 tests/contracts/fixtures/contract-filter.tat.yaml create mode 100644 tests/contracts/fixtures/contract-pass.tat.json create mode 100644 tests/contracts/fixtures/invalid.tat.json create mode 100644 tests/contracts/fixtures/request-error.tat.yaml create mode 100644 vscode-extension/tests/tatOutput.test.ts diff --git a/.codex/skills/tat-change-triage/SKILL.md b/.codex/skills/tat-change-triage/SKILL.md new file mode 100644 index 0000000..12cf656 --- /dev/null +++ b/.codex/skills/tat-change-triage/SKILL.md @@ -0,0 +1,9 @@ +# tat-change-triage + +Use this skill before modifying `tat-cli/`, `vscode-extension/`, or `packages/tat-shared/`. + +Checklist: +- Map touched files to affected surfaces: schema, shared contracts, file parsing, CLI flags, exit codes, output shape, binary resolution, extension output formatting. +- If any affected surface crosses package boundaries, require `npm run test:contracts` before completion. +- If `tat-cli/` changes, explicitly decide whether `vscode-extension/` is impacted and record that in the handoff. +- Prefer `npm run verify` as the default repo-wide safety check. diff --git a/.codex/skills/tat-contract-guard/SKILL.md b/.codex/skills/tat-contract-guard/SKILL.md new file mode 100644 index 0000000..104963a --- /dev/null +++ b/.codex/skills/tat-contract-guard/SKILL.md @@ -0,0 +1,15 @@ +# tat-contract-guard + +Use this skill whenever a change touches any of: +- `packages/tat-shared/src/contracts.ts` +- `tat-cli/src/types.ts` +- `tat-cli/src/schema.ts` +- `tat-cli/src/cli.ts` +- `vscode-extension/src/tatRunner.ts` +- `vscode-extension/src/resultFormatting.ts` + +Requirements: +- Update or add contract tests under `tests/contracts/`. +- Keep exit codes `0 / 1 / 2` stable unless the user explicitly requests a breaking change. +- Keep CLI JSON output parseable by `RunResultSchema`. +- If the contract changes intentionally, update extension docs and repo rules in the same change. diff --git a/.codex/skills/tat-harness-engineer/SKILL.md b/.codex/skills/tat-harness-engineer/SKILL.md new file mode 100644 index 0000000..1b251c2 --- /dev/null +++ b/.codex/skills/tat-harness-engineer/SKILL.md @@ -0,0 +1,10 @@ +# tat-harness-engineer + +Use this skill when adding or modifying cross-package fixtures or regression coverage. + +Responsibilities: +- Own fixtures under `tests/contracts/fixtures/`. +- Prefer real CLI execution against the built artifact over spawn-only mocks. +- Cover JSON, `.tat.yml`, and `.tat.yaml` paths when contract behavior might drift. +- Route real CLI stdout through extension-side parsing/formatting helpers where possible. +- Keep the harness fast and deterministic; avoid slow external services when a local test server is enough. diff --git a/.codex/skills/tat-release-check/SKILL.md b/.codex/skills/tat-release-check/SKILL.md new file mode 100644 index 0000000..5a2709b --- /dev/null +++ b/.codex/skills/tat-release-check/SKILL.md @@ -0,0 +1,10 @@ +# tat-release-check + +Use this skill before publish or version-bump changes. + +Checklist: +- Run `npm run verify`. +- Run `npm run smoke:packaged-cli` before npm publish. +- Confirm `tat --version` comes from `tat-cli/package.json`. +- Confirm `schema.json` and shared file-format helpers remain aligned. +- Confirm workflow changes keep using `npm ci`, not `npm install`. diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 73e7713..34a9ab1 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -7,8 +7,12 @@ on: branches: [main] jobs: - check: - runs-on: ubuntu-latest + verify: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 @@ -16,22 +20,12 @@ jobs: with: node-version: 20 - - name: Install CLI deps - working-directory: tat-cli + - name: Install workspace dependencies run: npm ci - - name: Install extension deps - working-directory: vscode-extension - run: npm install + - name: Verify workspace + run: npm run verify - - name: Lint CLI - working-directory: tat-cli - run: npm run lint - - - name: Test CLI - working-directory: tat-cli - run: npm test - - - name: Lint extension (catches type drift) - working-directory: vscode-extension - run: npm run lint + - name: Smoke packaged CLI + if: matrix.os == 'ubuntu-latest' + run: npm run smoke:packaged-cli diff --git a/.github/workflows/examples-ci.yml b/.github/workflows/examples-ci.yml index 6d3c30b..849c29b 100644 --- a/.github/workflows/examples-ci.yml +++ b/.github/workflows/examples-ci.yml @@ -17,8 +17,7 @@ jobs: with: node-version: 20 - - name: Install CLI deps - working-directory: tat-cli + - name: Install workspace dependencies run: npm ci - name: Build CLI diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 4d587b2..6e82b38 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -36,21 +36,14 @@ jobs: node-version: 20 registry-url: https://registry.npmjs.org - - name: Install dependencies - working-directory: tat-cli + - name: Install workspace dependencies run: npm ci - - name: Lint - working-directory: tat-cli - run: npm run lint + - name: Verify workspace + run: npm run verify - - name: Test - working-directory: tat-cli - run: npm test - - - name: Build - working-directory: tat-cli - run: npm run build + - name: Smoke packaged CLI + run: npm run smoke:packaged-cli - name: Publish to npm working-directory: tat-cli @@ -73,5 +66,5 @@ jobs: title: "chore: bump version after npm publish" body: Automated patch bump after publishing the npm package. add-paths: | + package-lock.json tat-cli/package.json - tat-cli/package-lock.json diff --git a/.github/workflows/publish-vscode.yml b/.github/workflows/publish-vscode.yml index 540db39..7018b76 100644 --- a/.github/workflows/publish-vscode.yml +++ b/.github/workflows/publish-vscode.yml @@ -35,17 +35,11 @@ jobs: with: node-version: 20 - - name: Install dependencies - working-directory: vscode-extension - run: npm install - - - name: Lint - working-directory: vscode-extension - run: npm run lint + - name: Install workspace dependencies + run: npm ci - - name: Build - working-directory: vscode-extension - run: npm run build + - name: Verify workspace + run: npm run verify - name: Publish to VS Code Marketplace working-directory: vscode-extension @@ -68,5 +62,5 @@ jobs: title: "chore(vscode): bump version after marketplace publish" body: Automated patch bump after publishing to VS Code Marketplace. add-paths: | + package-lock.json vscode-extension/package.json - vscode-extension/package-lock.json diff --git a/.gitignore b/.gitignore index b4f83ff..9048583 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules/ dist/ coverage/ +.vite/ *.log .DS_Store Thumbs.db diff --git a/AGENTS.md b/AGENTS.md index b47659e..695f211 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,14 +5,20 @@ This file provides guidance to AI coding agents when working with code in this r ## Commands ```bash +npm install # install all workspace deps from the repo root +npm run verify # root quality gate: lint + tests + builds + contract harness +npm run test:contracts # cross-package CLI ↔ extension contract harness npm --prefix tat-cli run build # compile with tsup → tat-cli/dist/cli.js npm --prefix tat-cli run lint # type-check only (tsc --noEmit) npm --prefix tat-cli test # run all tests once (vitest run) npm --prefix tat-cli run test:watch # watch mode npm --prefix tat-cli exec vitest run tests/asserter.test.ts # run a single test file +npm --prefix vscode-extension run build +npm --prefix vscode-extension run lint ``` `tat-cli/` is the package root for the CLI. Build output is ESM only (`tat-cli/dist/cli.js`) with a `#!/usr/bin/env node` shebang injected by tsup. Entry point is `tat-cli/src/cli.ts`. +`packages/tat-shared/` is the shared internal workspace package for file-format helpers and runtime-validated result contracts consumed by both the CLI and the VS Code extension. ## Cross-Package Impact Rule @@ -28,10 +34,15 @@ At minimum, inspect `vscode-extension/` when a CLI change touches: If the extension is affected, update its source, docs, and tests in the same change. Prefer running: +```bash +npm run verify +``` + +For targeted cross-package checks during development: + ```bash npm --prefix tat-cli exec vitest run vscode-extension/tests --config tat-cli/vitest.config.ts -npm --prefix vscode-extension run lint -npm --prefix vscode-extension run build +npm --prefix tat-cli exec vitest run tests/contracts --config tat-cli/vitest.config.ts ``` If the extension is not affected, mention that check in the PR summary or final handoff. @@ -41,7 +52,7 @@ If the extension is not affected, mention that check in the PR summary or final The execution flow for `tat run ` is: 1. **`tat-cli/src/cli.ts`** — Commander CLI entry. Exports `runCommand` and `validateCommand` for testability. Uses ESM main guard (`process.argv[1] === fileURLToPath(import.meta.url)`) to prevent `program.parse()` from running when imported in tests. Exit codes: 0 = pass, 1 = test failures, 2 = configuration/file errors or no matching suites. -2. **`tat-cli/src/fileFormat.ts`** — File format detection and parsing. Exports `TAT_EXTENSIONS` (`.tat.json`, `.tat.yml`, `.tat.yaml`), `isTatFile` (extension check), and `parseFileContent` (routes to `JSON.parse` or `yaml.parse` based on extension). +2. **`packages/tat-shared/src/fileFormat.ts`** — Shared file format detection and parsing. Owns `TAT_EXTENSIONS`, `isTatFile`, `isYamlTatFile`, and `parseTatFileContent` so CLI and extension stay in sync. 3. **`tat-cli/src/runner.ts`** — Core logic: `loadAndValidate` (reads file, delegates parsing to `parseFileContent`, then Zod-validates), `resolveEnv` (inline object or external JSON file), `runSetup` (spawns shell command with `stdin`/`stderr` inherited so interactive prompts work, captures stdout as JSON env), `filterSuites` (tag/name filtering), `warnUndefinedVars` (pre-run scan for undefined `{{variables}}`), `run` (loops suites/tests, handles `skip` and `bail`, merges captures into vars between tests). 4. **`tat-cli/src/asserter.ts`** — Builds the response context object (`$status`, `$headers`, `$body`, `$duration`, plus spread body fields) and evaluates assertion strings via `@nanotiny/json-expression`'s `evaluate()`. 5. **`tat-cli/src/capturer.ts`** — Extracts values from the response context using `@nanotiny/json-expression`'s `query()`; captured values become `{{variable}}` interpolation vars for subsequent tests. @@ -49,7 +60,9 @@ The execution flow for `tat run ` is: 7. **`tat-cli/src/http.ts`** — Thin `fetch` wrapper; auto-sets `Content-Type: application/json` for object bodies. Accepts optional `timeoutMs` and uses `AbortController` to enforce it. Throws `TatRequestError` on network failure or timeout. 8. **`tat-cli/src/reporter.ts`** — Formats `RunResult` as console (colored, with live streaming callbacks), JSON, or JUnit XML. Handles `skipped` tests in all three formats. 9. **`tat-cli/src/schema.ts`** — Zod schema for the test file format. -10. **`tat-cli/src/types.ts`** — Shared TypeScript interfaces (`Suite`, `Test`, `TestResult`, `RunResult`, etc.). +10. **`packages/tat-shared/src/contracts.ts`** — Shared runtime-validated result schemas and types (`AssertionResult`, `TestResult`, `SuiteResult`, `RunResult`). +11. **`tat-cli/src/types.ts`** — CLI-specific input types (`Suite`, `Test`, `HttpMethod`) plus re-exports of shared result contract types. +12. **`tests/contracts/`** — Cross-package harness that runs the built CLI against JSON/YML/YAML fixtures and validates the output through the extension-side parser/formatter path. ### Assertion and capture expression syntax @@ -58,3 +71,13 @@ Both assertions (`assert`) and capture paths (`capture`) are powered by [`@nanot ### Key data flow Captures accumulate across all suites in a single run. The merged env for each test is `{ ...staticEnv, ...captures }`. The `onSuiteStart` / `onTestResult` callbacks on `run()` are used by the CLI for live console streaming. + +## Repo-Local AI Assets + +- Repo-local skills live under `.codex/skills/`. +- Durable project memory lives under `Rules/`. +- When making cross-package changes, consult: + - `.codex/skills/tat-change-triage/SKILL.md` + - `.codex/skills/tat-contract-guard/SKILL.md` + - `.codex/skills/tat-harness-engineer/SKILL.md` + - `.codex/skills/tat-release-check/SKILL.md` diff --git a/README.md b/README.md index 89ad19c..bb9fdab 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,10 @@ code --install-extension nanotiny.tat-test-runner ## Common Commands ```bash +npm install +npm run verify +npm run test:contracts + npm --prefix tat-cli run build npm --prefix tat-cli run lint npm --prefix tat-cli test diff --git a/Rules/project-tat-binary-resolution-and-extension-assumptions.md b/Rules/project-tat-binary-resolution-and-extension-assumptions.md new file mode 100644 index 0000000..e31f7ff --- /dev/null +++ b/Rules/project-tat-binary-resolution-and-extension-assumptions.md @@ -0,0 +1,26 @@ +--- +tags: + - rule + - rule/project/tat +created: 2026-04-24 +updated: 2026-04-24 +scope: project/tat +status: active +--- + +# Binary resolution order and extension assumptions are stable + +## Rule + +`vscode-extension/src/tatRunner.ts` must preserve its binary resolution order unless an intentional compatibility change is made: + +1. `tat.cliPath` +2. `node_modules/.bin/tat[.cmd]` in the workspace +3. `tat-cli/node_modules/.bin/tat[.cmd]` or `tat-cli/dist/cli.js` in the repo workspace +4. `where tat` / `which tat` +5. `npx @nanotiny/tiny-api-test` + +## Enforcement + +- Windows behavior is part of the contract; keep `.cmd` handling covered by tests. +- Any change to resolution or stdout parsing assumptions must run through `tests/contracts/` and the extension test suite. diff --git a/Rules/project-tat-cli-exit-codes.md b/Rules/project-tat-cli-exit-codes.md new file mode 100644 index 0000000..a1fa114 --- /dev/null +++ b/Rules/project-tat-cli-exit-codes.md @@ -0,0 +1,24 @@ +--- +tags: + - rule + - rule/project/tat +created: 2026-04-24 +updated: 2026-04-24 +scope: project/tat +status: active +--- + +# CLI exit codes are stable + +## Rule + +`tat` must preserve this exit code contract unless an explicit breaking change is approved: + +- `0` = all selected tests passed +- `1` = test failures, but stdout still contains valid `RunResult` JSON when `--output json` is used +- `2` = configuration, validation, file discovery, or filter-selection errors + +## Enforcement + +- Any change touching CLI command handling, validation, or stdout/stderr behavior must update `tests/contracts/` if the behavior changes intentionally. +- The VS Code extension relies on the `0/1/2` contract to distinguish test failures from invocation errors. diff --git a/Rules/project-tat-json-result-contract.md b/Rules/project-tat-json-result-contract.md new file mode 100644 index 0000000..fa35bfb --- /dev/null +++ b/Rules/project-tat-json-result-contract.md @@ -0,0 +1,21 @@ +--- +tags: + - rule + - rule/project/tat +created: 2026-04-24 +updated: 2026-04-24 +scope: project/tat +status: active +--- + +# JSON result shape comes from the shared contract + +## Rule + +`AssertionResult`, `TestResult`, `SuiteResult`, and `RunResult` are owned by `packages/tat-shared/src/contracts.ts`. + +## Enforcement + +- The CLI must keep `--output json` compatible with `RunResultSchema`. +- The extension must validate CLI JSON with `RunResultSchema` instead of assuming shape by convention. +- Any intentional contract change must update `tests/contracts/`, extension formatting/parsing, and relevant docs in the same change. diff --git a/Rules/project-tat-schema-compatibility.md b/Rules/project-tat-schema-compatibility.md new file mode 100644 index 0000000..025f16b --- /dev/null +++ b/Rules/project-tat-schema-compatibility.md @@ -0,0 +1,26 @@ +--- +tags: + - rule + - rule/project/tat +created: 2026-04-24 +updated: 2026-04-24 +scope: project/tat +status: active +--- + +# Test file parsing and schema compatibility must stay aligned + +## Rule + +The supported file extensions and raw parsing behavior for `.tat.json`, `.tat.yml`, and `.tat.yaml` must remain aligned across: + +- `packages/tat-shared/src/fileFormat.ts` +- `tat-cli/src/schema.ts` +- `tat-cli/schema.json` +- `vscode-extension/src/fileParser.ts` +- `vscode-extension/src/promptVariables.ts` + +## Enforcement + +- Changes to parsing or schema behavior require CLI tests and contract harness updates. +- The extension may add editor-only behavior, but not a divergent parse contract. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..1876770 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4410 @@ +{ + "name": "tat-workspace", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "tat-workspace", + "workspaces": [ + "tat-cli", + "vscode-extension", + "packages/tat-shared" + ] + }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz", + "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz", + "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz", + "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@nanotiny/tiny-api-test": { + "resolved": "tat-cli", + "link": true + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tat/shared": { + "resolved": "packages/tat-shared", + "link": true + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "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/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, + "node_modules/debug": { + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.3" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/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/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, + "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/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, + "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/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true, + "license": "MIT" + }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, + "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/postcss": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", + "fsevents": "~2.3.2" + } + }, + "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/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, + "node_modules/tat-test-runner": { + "resolved": "vscode-extension", + "link": true + }, + "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": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, + "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/yaml": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", + "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14.6" + }, + "funding": { + "url": "https://github.com/sponsors/eemeli" + } + }, + "node_modules/zod": { + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "packages/tat-shared": { + "name": "@tat/shared", + "version": "0.0.0", + "dependencies": { + "yaml": "^2.7.0", + "zod": "^3.22.0" + } + }, + "tat-cli": { + "name": "@nanotiny/tiny-api-test", + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "@nanotiny/json-expression": "^0.0.10", + "chalk": "^5.3.0", + "commander": "^12.0.0", + "undici": "^6.25.0", + "yaml": "^2.7.0", + "zod": "^3.22.0" + }, + "bin": { + "tat": "dist/cli.js" + }, + "devDependencies": { + "@tat/shared": "file:../packages/tat-shared", + "@types/node": "^24.5.2", + "tsup": "^8.0.0", + "typescript": "^5.4.0", + "vitest": "^2.0.0" + }, + "engines": { + "node": ">=18.17" + } + }, + "tat-cli/node_modules/@esbuild/aix-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz", + "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/android-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz", + "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/android-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz", + "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/android-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz", + "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/darwin-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz", + "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/darwin-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz", + "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz", + "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/freebsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz", + "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-arm": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz", + "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz", + "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz", + "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-loong64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz", + "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-mips64el": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz", + "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-ppc64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz", + "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-riscv64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz", + "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-s390x": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz", + "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/linux-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz", + "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/netbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz", + "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/openbsd-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz", + "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/sunos-x64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz", + "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/win32-arm64": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz", + "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/win32-ia32": { + "version": "0.27.7", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz", + "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@esbuild/win32-x64": { + "version": "0.27.7", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.13", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.5.0", + "@jridgewell/trace-mapping": "^0.3.24" + } + }, + "tat-cli/node_modules/@jridgewell/resolve-uri": { + "version": "3.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6.0.0" + } + }, + "tat-cli/node_modules/@jridgewell/trace-mapping": { + "version": "0.3.31", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "tat-cli/node_modules/@nanotiny/json-expression": { + "version": "0.0.10", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, + "tat-cli/node_modules/@types/node": { + "version": "24.12.2", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~7.16.0" + } + }, + "tat-cli/node_modules/acorn": { + "version": "8.16.0", + "dev": true, + "license": "MIT", + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "tat-cli/node_modules/any-promise": { + "version": "1.3.0", + "dev": true, + "license": "MIT" + }, + "tat-cli/node_modules/bundle-require": { + "version": "5.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "load-tsconfig": "^0.2.3" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "peerDependencies": { + "esbuild": ">=0.18" + } + }, + "tat-cli/node_modules/chalk": { + "version": "5.6.2", + "license": "MIT", + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "tat-cli/node_modules/chokidar": { + "version": "4.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "readdirp": "^4.0.1" + }, + "engines": { + "node": ">= 14.16.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, + "tat-cli/node_modules/commander": { + "version": "12.1.0", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "tat-cli/node_modules/confbox": { + "version": "0.1.8", + "dev": true, + "license": "MIT" + }, + "tat-cli/node_modules/consola": { + "version": "3.4.2", + "dev": true, + "license": "MIT", + "engines": { + "node": "^14.18.0 || >=16.10.0" + } + }, + "tat-cli/node_modules/esbuild": { + "version": "0.27.7", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.7", + "@esbuild/android-arm": "0.27.7", + "@esbuild/android-arm64": "0.27.7", + "@esbuild/android-x64": "0.27.7", + "@esbuild/darwin-arm64": "0.27.7", + "@esbuild/darwin-x64": "0.27.7", + "@esbuild/freebsd-arm64": "0.27.7", + "@esbuild/freebsd-x64": "0.27.7", + "@esbuild/linux-arm": "0.27.7", + "@esbuild/linux-arm64": "0.27.7", + "@esbuild/linux-ia32": "0.27.7", + "@esbuild/linux-loong64": "0.27.7", + "@esbuild/linux-mips64el": "0.27.7", + "@esbuild/linux-ppc64": "0.27.7", + "@esbuild/linux-riscv64": "0.27.7", + "@esbuild/linux-s390x": "0.27.7", + "@esbuild/linux-x64": "0.27.7", + "@esbuild/netbsd-arm64": "0.27.7", + "@esbuild/netbsd-x64": "0.27.7", + "@esbuild/openbsd-arm64": "0.27.7", + "@esbuild/openbsd-x64": "0.27.7", + "@esbuild/openharmony-arm64": "0.27.7", + "@esbuild/sunos-x64": "0.27.7", + "@esbuild/win32-arm64": "0.27.7", + "@esbuild/win32-ia32": "0.27.7", + "@esbuild/win32-x64": "0.27.7" + } + }, + "tat-cli/node_modules/fdir": { + "version": "6.5.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "picomatch": "^3 || ^4" + }, + "peerDependenciesMeta": { + "picomatch": { + "optional": true + } + } + }, + "tat-cli/node_modules/fix-dts-default-cjs-exports": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "magic-string": "^0.30.17", + "mlly": "^1.7.4", + "rollup": "^4.34.8" + } + }, + "tat-cli/node_modules/joycon": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=10" + } + }, + "tat-cli/node_modules/lilconfig": { + "version": "3.1.3", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, + "tat-cli/node_modules/lines-and-columns": { + "version": "1.2.4", + "dev": true, + "license": "MIT" + }, + "tat-cli/node_modules/load-tsconfig": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "tat-cli/node_modules/mlly": { + "version": "1.8.2", + "dev": true, + "license": "MIT", + "dependencies": { + "acorn": "^8.16.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.3" + } + }, + "tat-cli/node_modules/mz": { + "version": "2.7.0", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0", + "object-assign": "^4.0.1", + "thenify-all": "^1.0.0" + } + }, + "tat-cli/node_modules/object-assign": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "tat-cli/node_modules/pathe": { + "version": "2.0.3", + "dev": true, + "license": "MIT" + }, + "tat-cli/node_modules/picomatch": { + "version": "4.0.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "tat-cli/node_modules/pirates": { + "version": "4.0.7", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "tat-cli/node_modules/pkg-types": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "confbox": "^0.1.8", + "mlly": "^1.7.4", + "pathe": "^2.0.1" + } + }, + "tat-cli/node_modules/postcss-load-config": { + "version": "6.0.1", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "lilconfig": "^3.1.1" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "jiti": ">=1.21.0", + "postcss": ">=8.0.9", + "tsx": "^4.8.1", + "yaml": "^2.4.2" + }, + "peerDependenciesMeta": { + "jiti": { + "optional": true + }, + "postcss": { + "optional": true + }, + "tsx": { + "optional": true + }, + "yaml": { + "optional": true + } + } + }, + "tat-cli/node_modules/readdirp": { + "version": "4.1.2", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.18.0" + }, + "funding": { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + }, + "tat-cli/node_modules/resolve-from": { + "version": "5.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "tat-cli/node_modules/source-map": { + "version": "0.7.6", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">= 12" + } + }, + "tat-cli/node_modules/sucrase": { + "version": "3.35.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.2", + "commander": "^4.0.0", + "lines-and-columns": "^1.1.6", + "mz": "^2.7.0", + "pirates": "^4.0.1", + "tinyglobby": "^0.2.11", + "ts-interface-checker": "^0.1.9" + }, + "bin": { + "sucrase": "bin/sucrase", + "sucrase-node": "bin/sucrase-node" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "tat-cli/node_modules/sucrase/node_modules/commander": { + "version": "4.1.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "tat-cli/node_modules/thenify": { + "version": "3.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "any-promise": "^1.0.0" + } + }, + "tat-cli/node_modules/thenify-all": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "dependencies": { + "thenify": ">= 3.1.0 < 4" + }, + "engines": { + "node": ">=0.8" + } + }, + "tat-cli/node_modules/tinyglobby": { + "version": "0.2.15", + "dev": true, + "license": "MIT", + "dependencies": { + "fdir": "^6.5.0", + "picomatch": "^4.0.3" + }, + "engines": { + "node": ">=12.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/SuperchupuDev" + } + }, + "tat-cli/node_modules/tree-kill": { + "version": "1.2.2", + "dev": true, + "license": "MIT", + "bin": { + "tree-kill": "cli.js" + } + }, + "tat-cli/node_modules/ts-interface-checker": { + "version": "0.1.13", + "dev": true, + "license": "Apache-2.0" + }, + "tat-cli/node_modules/tsup": { + "version": "8.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-require": "^5.1.0", + "cac": "^6.7.14", + "chokidar": "^4.0.3", + "consola": "^3.4.0", + "debug": "^4.4.0", + "esbuild": "^0.27.0", + "fix-dts-default-cjs-exports": "^1.0.0", + "joycon": "^3.1.1", + "picocolors": "^1.1.1", + "postcss-load-config": "^6.0.1", + "resolve-from": "^5.0.0", + "rollup": "^4.34.8", + "source-map": "^0.7.6", + "sucrase": "^3.35.0", + "tinyexec": "^0.3.2", + "tinyglobby": "^0.2.11", + "tree-kill": "^1.2.2" + }, + "bin": { + "tsup": "dist/cli-default.js", + "tsup-node": "dist/cli-node.js" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@microsoft/api-extractor": "^7.36.0", + "@swc/core": "^1", + "postcss": "^8.4.12", + "typescript": ">=4.5.0" + }, + "peerDependenciesMeta": { + "@microsoft/api-extractor": { + "optional": true + }, + "@swc/core": { + "optional": true + }, + "postcss": { + "optional": true + }, + "typescript": { + "optional": true + } + } + }, + "tat-cli/node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "tat-cli/node_modules/ufo": { + "version": "1.6.3", + "dev": true, + "license": "MIT" + }, + "tat-cli/node_modules/undici": { + "version": "6.25.0", + "license": "MIT", + "engines": { + "node": ">=18.17" + } + }, + "tat-cli/node_modules/undici-types": { + "version": "7.16.0", + "dev": true, + "license": "MIT" + }, + "vscode-extension": { + "name": "tat-test-runner", + "version": "1.0.5", + "license": "MIT", + "dependencies": { + "yaml": "^2.7.0" + }, + "devDependencies": { + "@tat/shared": "file:../packages/tat-shared", + "@types/node": "^20.0.0", + "@types/vscode": "^1.87.0", + "@vscode/vsce": "^2.24.0", + "esbuild": "^0.21.0", + "typescript": "^5.4.0", + "vitest": "^2.0.0" + }, + "engines": { + "vscode": "^1.87.0" + } + }, + "vscode-extension/node_modules/@azure/abort-controller": { + "version": "2.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "vscode-extension/node_modules/@azure/core-auth": { + "version": "1.10.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-util": "^1.13.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/core-client": { + "version": "1.10.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-rest-pipeline": "^1.22.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/core-rest-pipeline": { + "version": "1.23.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@azure/core-auth": "^1.10.0", + "@azure/core-tracing": "^1.3.0", + "@azure/core-util": "^1.13.0", + "@azure/logger": "^1.3.0", + "@typespec/ts-http-runtime": "^0.3.4", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/core-tracing": { + "version": "1.3.1", + "dev": true, + "license": "MIT", + "dependencies": { + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/core-util": { + "version": "1.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.1.2", + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/identity": { + "version": "4.13.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/abort-controller": "^2.0.0", + "@azure/core-auth": "^1.9.0", + "@azure/core-client": "^1.9.2", + "@azure/core-rest-pipeline": "^1.17.0", + "@azure/core-tracing": "^1.0.0", + "@azure/core-util": "^1.11.0", + "@azure/logger": "^1.0.0", + "@azure/msal-browser": "^5.5.0", + "@azure/msal-node": "^5.1.0", + "open": "^10.1.0", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/logger": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@typespec/ts-http-runtime": "^0.3.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@azure/msal-browser": { + "version": "5.6.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "vscode-extension/node_modules/@azure/msal-common": { + "version": "16.4.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "vscode-extension/node_modules/@azure/msal-node": { + "version": "5.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/msal-common": "16.4.0", + "jsonwebtoken": "^9.0.0", + "uuid": "^8.3.0" + }, + "engines": { + "node": ">=20" + } + }, + "vscode-extension/node_modules/@types/node": { + "version": "20.19.37", + "dev": true, + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "vscode-extension/node_modules/@types/vscode": { + "version": "1.110.0", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/@typespec/ts-http-runtime": { + "version": "0.3.4", + "dev": true, + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "vscode-extension/node_modules/@vscode/vsce": { + "version": "2.32.0", + "dev": true, + "license": "MIT", + "dependencies": { + "@azure/identity": "^4.1.0", + "@vscode/vsce-sign": "^2.0.0", + "azure-devops-node-api": "^12.5.0", + "chalk": "^2.4.2", + "cheerio": "^1.0.0-rc.9", + "cockatiel": "^3.1.2", + "commander": "^6.2.1", + "form-data": "^4.0.0", + "glob": "^7.0.6", + "hosted-git-info": "^4.0.2", + "jsonc-parser": "^3.2.0", + "leven": "^3.1.0", + "markdown-it": "^12.3.2", + "mime": "^1.3.4", + "minimatch": "^3.0.3", + "parse-semver": "^1.1.1", + "read": "^1.0.7", + "semver": "^7.5.2", + "tmp": "^0.2.1", + "typed-rest-client": "^1.8.4", + "url-join": "^4.0.1", + "xml2js": "^0.5.0", + "yauzl": "^2.3.1", + "yazl": "^2.2.2" + }, + "bin": { + "vsce": "vsce" + }, + "engines": { + "node": ">= 16" + }, + "optionalDependencies": { + "keytar": "^7.7.0" + } + }, + "vscode-extension/node_modules/@vscode/vsce-sign": { + "version": "2.0.9", + "dev": true, + "hasInstallScript": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optionalDependencies": { + "@vscode/vsce-sign-alpine-arm64": "2.0.6", + "@vscode/vsce-sign-alpine-x64": "2.0.6", + "@vscode/vsce-sign-darwin-arm64": "2.0.6", + "@vscode/vsce-sign-darwin-x64": "2.0.6", + "@vscode/vsce-sign-linux-arm": "2.0.6", + "@vscode/vsce-sign-linux-arm64": "2.0.6", + "@vscode/vsce-sign-linux-x64": "2.0.6", + "@vscode/vsce-sign-win32-arm64": "2.0.6", + "@vscode/vsce-sign-win32-x64": "2.0.6" + } + }, + "vscode-extension/node_modules/@vscode/vsce-sign-win32-x64": { + "version": "2.0.6", + "cpu": [ + "x64" + ], + "dev": true, + "license": "SEE LICENSE IN LICENSE.txt", + "optional": true, + "os": [ + "win32" + ] + }, + "vscode-extension/node_modules/agent-base": { + "version": "7.1.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14" + } + }, + "vscode-extension/node_modules/ansi-styles": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "vscode-extension/node_modules/argparse": { + "version": "2.0.1", + "dev": true, + "license": "Python-2.0" + }, + "vscode-extension/node_modules/asynckit": { + "version": "0.4.0", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/azure-devops-node-api": { + "version": "12.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "tunnel": "0.0.6", + "typed-rest-client": "^1.8.4" + } + }, + "vscode-extension/node_modules/balanced-match": { + "version": "1.0.2", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/base64-js": { + "version": "1.5.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/bl": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "vscode-extension/node_modules/boolbase": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "vscode-extension/node_modules/brace-expansion": { + "version": "1.1.13", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "vscode-extension/node_modules/buffer": { + "version": "5.7.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "vscode-extension/node_modules/buffer-crc32": { + "version": "0.2.13", + "dev": true, + "license": "MIT", + "engines": { + "node": "*" + } + }, + "vscode-extension/node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "dev": true, + "license": "BSD-3-Clause" + }, + "vscode-extension/node_modules/bundle-name": { + "version": "4.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "run-applescript": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/call-bound": { + "version": "1.0.4", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "get-intrinsic": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/chalk": { + "version": "2.4.2", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "vscode-extension/node_modules/cheerio": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "encoding-sniffer": "^0.2.1", + "htmlparser2": "^10.1.0", + "parse5": "^7.3.0", + "parse5-htmlparser2-tree-adapter": "^7.1.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^7.19.0", + "whatwg-mimetype": "^4.0.0" + }, + "engines": { + "node": ">=20.18.1" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "vscode-extension/node_modules/cheerio-select": { + "version": "2.1.0", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "vscode-extension/node_modules/chownr": { + "version": "1.1.4", + "dev": true, + "license": "ISC", + "optional": true + }, + "vscode-extension/node_modules/cockatiel": { + "version": "3.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=16" + } + }, + "vscode-extension/node_modules/color-convert": { + "version": "1.9.3", + "dev": true, + "license": "MIT", + "dependencies": { + "color-name": "1.1.3" + } + }, + "vscode-extension/node_modules/color-name": { + "version": "1.1.3", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/combined-stream": { + "version": "1.0.8", + "dev": true, + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "vscode-extension/node_modules/commander": { + "version": "6.2.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, + "vscode-extension/node_modules/concat-map": { + "version": "0.0.1", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/css-select": { + "version": "5.2.2", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "vscode-extension/node_modules/css-what": { + "version": "6.2.2", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "vscode-extension/node_modules/decompress-response": { + "version": "6.0.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/deep-extend": { + "version": "0.6.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=4.0.0" + } + }, + "vscode-extension/node_modules/default-browser": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "bundle-name": "^4.1.0", + "default-browser-id": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/default-browser-id": { + "version": "5.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/define-lazy-prop": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/delayed-stream": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "vscode-extension/node_modules/detect-libc": { + "version": "2.1.2", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, + "vscode-extension/node_modules/dom-serializer": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "vscode-extension/node_modules/domelementtype": { + "version": "2.3.0", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "vscode-extension/node_modules/domhandler": { + "version": "5.0.3", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "vscode-extension/node_modules/domutils": { + "version": "3.2.2", + "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" + } + }, + "vscode-extension/node_modules/dunder-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, + "vscode-extension/node_modules/encoding-sniffer": { + "version": "0.2.1", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "vscode-extension/node_modules/end-of-stream": { + "version": "1.4.5", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "vscode-extension/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" + } + }, + "vscode-extension/node_modules/es-define-property": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/es-errors": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/es-object-atoms": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/es-set-tostringtag": { + "version": "2.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/escape-string-regexp": { + "version": "1.0.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "vscode-extension/node_modules/expand-template": { + "version": "2.0.3", + "dev": true, + "license": "(MIT OR WTFPL)", + "optional": true, + "engines": { + "node": ">=6" + } + }, + "vscode-extension/node_modules/fd-slicer": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "pend": "~1.2.0" + } + }, + "vscode-extension/node_modules/form-data": { + "version": "4.0.5", + "dev": true, + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "vscode-extension/node_modules/fs-constants": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/fs.realpath": { + "version": "1.0.0", + "dev": true, + "license": "ISC" + }, + "vscode-extension/node_modules/function-bind": { + "version": "1.1.2", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/get-intrinsic": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/get-proto": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/github-from-package": { + "version": "0.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/glob": { + "version": "7.2.3", + "dev": true, + "license": "ISC", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "vscode-extension/node_modules/gopd": { + "version": "1.2.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/has-flag": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "vscode-extension/node_modules/has-symbols": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/has-tostringtag": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/hasown": { + "version": "2.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/hosted-git-info": { + "version": "4.1.0", + "dev": true, + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "vscode-extension/node_modules/htmlparser2": { + "version": "10.1.0", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.2.2", + "entities": "^7.0.1" + } + }, + "vscode-extension/node_modules/htmlparser2/node_modules/entities": { + "version": "7.0.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "vscode-extension/node_modules/http-proxy-agent": { + "version": "7.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.0", + "debug": "^4.3.4" + }, + "engines": { + "node": ">= 14" + } + }, + "vscode-extension/node_modules/https-proxy-agent": { + "version": "7.0.6", + "dev": true, + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.2", + "debug": "4" + }, + "engines": { + "node": ">= 14" + } + }, + "vscode-extension/node_modules/iconv-lite": { + "version": "0.6.3", + "dev": true, + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "vscode-extension/node_modules/ieee754": { + "version": "1.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause", + "optional": true + }, + "vscode-extension/node_modules/inflight": { + "version": "1.0.6", + "dev": true, + "license": "ISC", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "vscode-extension/node_modules/inherits": { + "version": "2.0.4", + "dev": true, + "license": "ISC" + }, + "vscode-extension/node_modules/ini": { + "version": "1.3.8", + "dev": true, + "license": "ISC", + "optional": true + }, + "vscode-extension/node_modules/is-docker": { + "version": "3.0.0", + "dev": true, + "license": "MIT", + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/is-inside-container": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-docker": "^3.0.0" + }, + "bin": { + "is-inside-container": "cli.js" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/is-wsl": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "is-inside-container": "^1.0.0" + }, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/jsonc-parser": { + "version": "3.3.1", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/jsonwebtoken": { + "version": "9.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "jws": "^4.0.1", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^7.5.4" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "vscode-extension/node_modules/jwa": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-equal-constant-time": "^1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "vscode-extension/node_modules/jws": { + "version": "4.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "jwa": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "vscode-extension/node_modules/keytar": { + "version": "7.9.0", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-addon-api": "^4.3.0", + "prebuild-install": "^7.0.1" + } + }, + "vscode-extension/node_modules/leven": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, + "vscode-extension/node_modules/linkify-it": { + "version": "3.0.3", + "dev": true, + "license": "MIT", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "vscode-extension/node_modules/lodash.includes": { + "version": "4.3.0", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lodash.isboolean": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lodash.isinteger": { + "version": "4.0.4", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lodash.isnumber": { + "version": "3.0.3", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lodash.isplainobject": { + "version": "4.0.6", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lodash.isstring": { + "version": "4.0.1", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lodash.once": { + "version": "4.1.1", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/lru-cache": { + "version": "6.0.0", + "dev": true, + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "vscode-extension/node_modules/markdown-it": { + "version": "12.3.2", + "dev": true, + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "vscode-extension/node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "dev": true, + "license": "BSD-2-Clause", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "vscode-extension/node_modules/math-intrinsics": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "vscode-extension/node_modules/mdurl": { + "version": "1.0.1", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/mime": { + "version": "1.6.0", + "dev": true, + "license": "MIT", + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "vscode-extension/node_modules/mime-db": { + "version": "1.52.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "vscode-extension/node_modules/mime-types": { + "version": "2.1.35", + "dev": true, + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "vscode-extension/node_modules/mimic-response": { + "version": "3.1.0", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/minimatch": { + "version": "3.1.5", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "vscode-extension/node_modules/minimist": { + "version": "1.2.8", + "dev": true, + "license": "MIT", + "optional": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/mkdirp-classic": { + "version": "0.5.3", + "dev": true, + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/mute-stream": { + "version": "0.0.8", + "dev": true, + "license": "ISC" + }, + "vscode-extension/node_modules/napi-build-utils": { + "version": "2.0.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/node-abi": { + "version": "3.89.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "vscode-extension/node_modules/node-addon-api": { + "version": "4.3.0", + "dev": true, + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/nth-check": { + "version": "2.1.1", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "vscode-extension/node_modules/object-inspect": { + "version": "1.13.4", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/once": { + "version": "1.4.0", + "dev": true, + "license": "ISC", + "dependencies": { + "wrappy": "1" + } + }, + "vscode-extension/node_modules/open": { + "version": "10.2.0", + "dev": true, + "license": "MIT", + "dependencies": { + "default-browser": "^5.2.1", + "define-lazy-prop": "^3.0.0", + "is-inside-container": "^1.0.0", + "wsl-utils": "^0.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/parse-semver": { + "version": "1.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "semver": "^5.1.0" + } + }, + "vscode-extension/node_modules/parse-semver/node_modules/semver": { + "version": "5.7.2", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "vscode-extension/node_modules/parse5": { + "version": "7.3.0", + "dev": true, + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "vscode-extension/node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "vscode-extension/node_modules/parse5-parser-stream": { + "version": "7.1.2", + "dev": true, + "license": "MIT", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "vscode-extension/node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "vscode-extension/node_modules/path-is-absolute": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "vscode-extension/node_modules/pend": { + "version": "1.2.0", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/prebuild-install": { + "version": "7.1.3", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.0", + "expand-template": "^2.0.3", + "github-from-package": "0.0.0", + "minimist": "^1.2.3", + "mkdirp-classic": "^0.5.3", + "napi-build-utils": "^2.0.0", + "node-abi": "^3.3.0", + "pump": "^3.0.0", + "rc": "^1.2.7", + "simple-get": "^4.0.0", + "tar-fs": "^2.0.0", + "tunnel-agent": "^0.6.0" + }, + "bin": { + "prebuild-install": "bin.js" + }, + "engines": { + "node": ">=10" + } + }, + "vscode-extension/node_modules/pump": { + "version": "3.0.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "vscode-extension/node_modules/qs": { + "version": "6.15.0", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/rc": { + "version": "1.2.8", + "dev": true, + "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", + "optional": true, + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "bin": { + "rc": "cli.js" + } + }, + "vscode-extension/node_modules/read": { + "version": "1.0.7", + "dev": true, + "license": "ISC", + "dependencies": { + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" + } + }, + "vscode-extension/node_modules/readable-stream": { + "version": "3.6.2", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "vscode-extension/node_modules/run-applescript": { + "version": "7.1.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/safe-buffer": { + "version": "5.2.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "vscode-extension/node_modules/safer-buffer": { + "version": "2.1.2", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/sax": { + "version": "1.6.0", + "dev": true, + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=11.0.0" + } + }, + "vscode-extension/node_modules/semver": { + "version": "7.7.4", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "vscode-extension/node_modules/side-channel": { + "version": "1.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3", + "side-channel-list": "^1.0.0", + "side-channel-map": "^1.0.1", + "side-channel-weakmap": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/side-channel-list": { + "version": "1.0.0", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/side-channel-map": { + "version": "1.0.1", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/side-channel-weakmap": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.2", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.5", + "object-inspect": "^1.13.3", + "side-channel-map": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "vscode-extension/node_modules/simple-concat": { + "version": "1.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/simple-get": { + "version": "4.0.1", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "optional": true, + "dependencies": { + "decompress-response": "^6.0.0", + "once": "^1.3.1", + "simple-concat": "^1.0.0" + } + }, + "vscode-extension/node_modules/string_decoder": { + "version": "1.3.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "vscode-extension/node_modules/strip-json-comments": { + "version": "2.0.1", + "dev": true, + "license": "MIT", + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "vscode-extension/node_modules/supports-color": { + "version": "5.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "vscode-extension/node_modules/tar-fs": { + "version": "2.1.4", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "chownr": "^1.1.1", + "mkdirp-classic": "^0.5.2", + "pump": "^3.0.0", + "tar-stream": "^2.1.4" + } + }, + "vscode-extension/node_modules/tar-stream": { + "version": "2.2.0", + "dev": true, + "license": "MIT", + "optional": true, + "dependencies": { + "bl": "^4.0.3", + "end-of-stream": "^1.4.1", + "fs-constants": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "vscode-extension/node_modules/tmp": { + "version": "0.2.5", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.14" + } + }, + "vscode-extension/node_modules/tslib": { + "version": "2.8.1", + "dev": true, + "license": "0BSD" + }, + "vscode-extension/node_modules/tunnel": { + "version": "0.0.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + } + }, + "vscode-extension/node_modules/tunnel-agent": { + "version": "0.6.0", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "safe-buffer": "^5.0.1" + }, + "engines": { + "node": "*" + } + }, + "vscode-extension/node_modules/typed-rest-client": { + "version": "1.8.11", + "dev": true, + "license": "MIT", + "dependencies": { + "qs": "^6.9.1", + "tunnel": "0.0.6", + "underscore": "^1.12.1" + } + }, + "vscode-extension/node_modules/typescript": { + "version": "5.9.3", + "dev": true, + "license": "Apache-2.0", + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "vscode-extension/node_modules/uc.micro": { + "version": "1.0.6", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/underscore": { + "version": "1.13.8", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/undici": { + "version": "7.24.6", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20.18.1" + } + }, + "vscode-extension/node_modules/undici-types": { + "version": "6.21.0", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/url-join": { + "version": "4.0.1", + "dev": true, + "license": "MIT" + }, + "vscode-extension/node_modules/util-deprecate": { + "version": "1.0.2", + "dev": true, + "license": "MIT", + "optional": true + }, + "vscode-extension/node_modules/uuid": { + "version": "8.3.2", + "dev": true, + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "vscode-extension/node_modules/whatwg-encoding": { + "version": "3.1.1", + "dev": true, + "license": "MIT", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "vscode-extension/node_modules/whatwg-mimetype": { + "version": "4.0.0", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "vscode-extension/node_modules/wrappy": { + "version": "1.0.2", + "dev": true, + "license": "ISC" + }, + "vscode-extension/node_modules/wsl-utils": { + "version": "0.1.0", + "dev": true, + "license": "MIT", + "dependencies": { + "is-wsl": "^3.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "vscode-extension/node_modules/xml2js": { + "version": "0.5.0", + "dev": true, + "license": "MIT", + "dependencies": { + "sax": ">=0.6.0", + "xmlbuilder": "~11.0.0" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "vscode-extension/node_modules/xmlbuilder": { + "version": "11.0.1", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4.0" + } + }, + "vscode-extension/node_modules/yallist": { + "version": "4.0.0", + "dev": true, + "license": "ISC" + }, + "vscode-extension/node_modules/yauzl": { + "version": "2.10.0", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "vscode-extension/node_modules/yazl": { + "version": "2.5.1", + "dev": true, + "license": "MIT", + "dependencies": { + "buffer-crc32": "~0.2.3" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..94600e0 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "tat-workspace", + "private": true, + "workspaces": [ + "tat-cli", + "vscode-extension", + "packages/tat-shared" + ], + "scripts": { + "build": "npm --prefix tat-cli run build && npm --prefix vscode-extension run build", + "lint": "npm --prefix tat-cli run lint && npm --prefix vscode-extension run lint && npm run lint:shared", + "lint:shared": "npm exec --workspace tat-cli -- tsc -p ../packages/tat-shared/tsconfig.json --noEmit", + "test": "npm --prefix tat-cli test && npm --prefix tat-cli exec vitest run vscode-extension/tests packages/tat-shared/tests --config tat-cli/vitest.config.ts", + "test:contracts": "npm --prefix tat-cli exec vitest run tests/contracts --config tat-cli/vitest.config.ts", + "verify": "npm run lint && npm run test && npm run build && npm run test:contracts", + "smoke:packaged-cli": "node scripts/smoke-packaged-cli.mjs" + } +} diff --git a/packages/tat-shared/package.json b/packages/tat-shared/package.json new file mode 100644 index 0000000..2b340c1 --- /dev/null +++ b/packages/tat-shared/package.json @@ -0,0 +1,13 @@ +{ + "name": "@tat/shared", + "private": true, + "version": "0.0.0", + "type": "module", + "exports": { + ".": "./src/index.ts" + }, + "dependencies": { + "yaml": "^2.7.0", + "zod": "^3.22.0" + } +} diff --git a/packages/tat-shared/src/contracts.ts b/packages/tat-shared/src/contracts.ts new file mode 100644 index 0000000..9c0a355 --- /dev/null +++ b/packages/tat-shared/src/contracts.ts @@ -0,0 +1,46 @@ +import { z } from 'zod'; + +export const AssertionActualSchema = z.object({ + operand: z.string(), + value: z.unknown(), +}); + +export const AssertionResultSchema = z.object({ + expr: z.string(), + passed: z.boolean(), + error: z.string().optional(), + actual: z.array(AssertionActualSchema).optional(), +}); + +export const TestResultSchema = z.object({ + name: z.string(), + passed: z.boolean(), + skipped: z.boolean().optional(), + assertions: z.array(AssertionResultSchema), + durationMs: z.number(), + error: z.string().optional(), + captures: z.record(z.string()).optional(), + responseStatus: z.number().optional(), + responseBody: z.unknown().optional(), + responseHeaders: z.record(z.string()).optional(), +}); + +export const SuiteResultSchema = z.object({ + name: z.string(), + tags: z.array(z.string()), + tests: z.array(TestResultSchema), +}); + +export const RunResultSchema = z.object({ + suites: z.array(SuiteResultSchema), + total: z.number(), + passed: z.number(), + failed: z.number(), + skipped: z.number(), + durationMs: z.number(), +}); + +export type AssertionResult = z.infer; +export type TestResult = z.infer; +export type SuiteResult = z.infer; +export type RunResult = z.infer; diff --git a/packages/tat-shared/src/fileFormat.ts b/packages/tat-shared/src/fileFormat.ts new file mode 100644 index 0000000..d95b77e --- /dev/null +++ b/packages/tat-shared/src/fileFormat.ts @@ -0,0 +1,31 @@ +import { parse as parseYaml } from 'yaml'; + +export const TAT_EXTENSIONS = ['.tat.json', '.tat.yml', '.tat.yaml'] as const; + +export function isTatFile(filePath: string): boolean { + return TAT_EXTENSIONS.some((ext) => filePath.endsWith(ext)); +} + +export function isYamlTatFile(filePath: string): boolean { + return filePath.endsWith('.tat.yml') || filePath.endsWith('.tat.yaml'); +} + +export function parseTatFileContent(filePath: string, raw: string): unknown { + if (filePath.endsWith('.tat.json')) { + try { + return JSON.parse(raw); + } catch (error) { + throw new Error(`Invalid JSON in ${filePath}: ${(error as Error).message}`); + } + } + + if (isYamlTatFile(filePath)) { + try { + return parseYaml(raw); + } catch (error) { + throw new Error(`Invalid YAML in ${filePath}: ${(error as Error).message}`); + } + } + + throw new Error(`Unsupported file format: ${filePath}`); +} diff --git a/packages/tat-shared/src/index.ts b/packages/tat-shared/src/index.ts new file mode 100644 index 0000000..0956894 --- /dev/null +++ b/packages/tat-shared/src/index.ts @@ -0,0 +1,2 @@ +export * from './contracts.js'; +export * from './fileFormat.js'; diff --git a/packages/tat-shared/tests/contracts.test.ts b/packages/tat-shared/tests/contracts.test.ts new file mode 100644 index 0000000..30f8f74 --- /dev/null +++ b/packages/tat-shared/tests/contracts.test.ts @@ -0,0 +1,86 @@ +import { describe, expect, it } from 'vitest'; + +import { + AssertionResultSchema, + RunResultSchema, + TAT_EXTENSIONS, + isTatFile, + parseTatFileContent, +} from '../src/index.js'; + +describe('tat shared result contracts', () => { + it('accepts the current CLI RunResult shape', () => { + const parsed = RunResultSchema.parse({ + suites: [ + { + name: 'Users', + tags: ['smoke'], + tests: [ + { + name: 'Get user', + passed: true, + assertions: [], + durationMs: 8, + responseStatus: 200, + responseBody: { id: 1, name: 'Ada' }, + responseHeaders: { 'content-type': 'application/json' }, + }, + ], + }, + ], + total: 1, + passed: 1, + failed: 0, + skipped: 0, + durationMs: 8, + }); + + expect(parsed.suites[0].tests[0].responseStatus).toBe(200); + }); + + it('rejects invalid actual operand entries', () => { + expect(() => + AssertionResultSchema.parse({ + expr: '$status == 200', + passed: false, + actual: [{ operand: 123, value: 500 }], + }), + ).toThrow(); + }); +}); + +describe('tat shared file format helpers', () => { + it('tracks the supported tat extensions', () => { + expect(TAT_EXTENSIONS).toEqual(['.tat.json', '.tat.yml', '.tat.yaml']); + }); + + it('detects tat files across json and yaml variants', () => { + expect(isTatFile('users.tat.json')).toBe(true); + expect(isTatFile('users.tat.yml')).toBe(true); + expect(isTatFile('users.tat.yaml')).toBe(true); + expect(isTatFile('users.json')).toBe(false); + }); + + it('parses yaml test files with the same helper the CLI and extension use', () => { + const parsed = parseTatFileContent( + 'users.tat.yml', + `suites: + - name: Users + tests: + - name: Get user + method: GET + url: https://example.test/users/1 + assert: + - "$status == 200" +`, + ) as { suites: Array<{ name: string }> }; + + expect(parsed.suites[0].name).toBe('Users'); + }); + + it('throws a clear unsupported format error', () => { + expect(() => parseTatFileContent('users.json', '{}')).toThrow( + 'Unsupported file format: users.json', + ); + }); +}); diff --git a/packages/tat-shared/tsconfig.json b/packages/tat-shared/tsconfig.json new file mode 100644 index 0000000..dd5be94 --- /dev/null +++ b/packages/tat-shared/tsconfig.json @@ -0,0 +1,19 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "bundler", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "noEmit": true + }, + "include": [ + "src/**/*", + "tests/**/*" + ], + "exclude": [ + "node_modules", + "dist" + ] +} diff --git a/scripts/smoke-packaged-cli.mjs b/scripts/smoke-packaged-cli.mjs new file mode 100644 index 0000000..bf39ef1 --- /dev/null +++ b/scripts/smoke-packaged-cli.mjs @@ -0,0 +1,86 @@ +import { execFileSync } from 'node:child_process'; +import { mkdtempSync, mkdirSync, writeFileSync, existsSync, rmSync } from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +const tatCliDir = path.join(rootDir, 'tat-cli'); +const tmpRoot = mkdtempSync(path.join(os.tmpdir(), 'tat-pack-smoke-')); +const packDir = path.join(tmpRoot, 'pack'); +const installDir = path.join(tmpRoot, 'install'); + +function runNpm(args, options = {}) { + const npmCli = process.env.npm_execpath; + if (!npmCli) { + throw new Error('npm_execpath is not available; cannot run npm from the smoke script.'); + } + + return execFileSync(process.execPath, [npmCli, ...args], options); +} + +mkdirSync(packDir, { recursive: true }); +mkdirSync(installDir, { recursive: true }); + +try { + const packedName = runNpm( + ['pack', '--silent', '--pack-destination', packDir], + { cwd: tatCliDir, encoding: 'utf-8' }, + ).trim(); + + const tarballPath = path.join(packDir, packedName); + if (!existsSync(tarballPath)) { + throw new Error(`Packed tarball was not created: ${tarballPath}`); + } + + runNpm(['init', '-y'], { cwd: installDir, stdio: 'ignore' }); + runNpm(['install', '--silent', tarballPath], { cwd: installDir, stdio: 'inherit' }); + + const installedCli = path.join( + installDir, + 'node_modules', + '@nanotiny', + 'tiny-api-test', + 'dist', + 'cli.js', + ); + + if (!existsSync(installedCli)) { + throw new Error(`Installed CLI entrypoint not found: ${installedCli}`); + } + + const fixturePath = path.join(installDir, 'smoke.tat.json'); + writeFileSync( + fixturePath, + JSON.stringify({ + suites: [ + { + name: 'Smoke', + tests: [ + { + name: 'Schema only', + method: 'GET', + url: 'https://example.test', + assert: ['$status == 200'], + }, + ], + }, + ], + }, null, 2), + 'utf-8', + ); + + const output = execFileSync( + process.execPath, + [installedCli, 'validate', fixturePath], + { cwd: installDir, encoding: 'utf-8' }, + ); + + if (!output.includes('valid')) { + throw new Error(`Packaged CLI smoke check did not report success.\n${output}`); + } + + console.log(`Packaged CLI smoke check passed: ${packedName}`); +} finally { + rmSync(tmpRoot, { recursive: true, force: true }); +} diff --git a/tat-cli/package.json b/tat-cli/package.json index 997a2f1..b370866 100644 --- a/tat-cli/package.json +++ b/tat-cli/package.json @@ -28,6 +28,7 @@ "zod": "^3.22.0" }, "devDependencies": { + "@tat/shared": "file:../packages/tat-shared", "@types/node": "^24.5.2", "tsup": "^8.0.0", "typescript": "^5.4.0", diff --git a/tat-cli/src/fileFormat.ts b/tat-cli/src/fileFormat.ts index 4312950..44a4754 100644 --- a/tat-cli/src/fileFormat.ts +++ b/tat-cli/src/fileFormat.ts @@ -1,29 +1,5 @@ -import { parse as parseYaml } from 'yaml'; - -export const TAT_EXTENSIONS = ['.tat.json', '.tat.yml', '.tat.yaml'] as const; - -/** Check whether a file path ends with a recognised TAT extension. */ -export function isTatFile(filePath: string): boolean { - return TAT_EXTENSIONS.some(ext => filePath.endsWith(ext)); -} - -/** Parse raw file content as JSON or YAML based on the file extension. */ -export function parseFileContent(filePath: string, raw: string): unknown { - if (filePath.endsWith('.tat.json')) { - try { - return JSON.parse(raw); - } catch (e) { - throw new Error(`Invalid JSON in ${filePath}: ${(e as Error).message}`); - } - } - - if (filePath.endsWith('.tat.yml') || filePath.endsWith('.tat.yaml')) { - try { - return parseYaml(raw); - } catch (e) { - throw new Error(`Invalid YAML in ${filePath}: ${(e as Error).message}`); - } - } - - throw new Error(`Unsupported file format: ${filePath}`); -} +export { + TAT_EXTENSIONS, + isTatFile, + parseTatFileContent as parseFileContent, +} from '@tat/shared'; diff --git a/tat-cli/src/types.ts b/tat-cli/src/types.ts index 11d5c16..2e8447c 100644 --- a/tat-cli/src/types.ts +++ b/tat-cli/src/types.ts @@ -1,5 +1,12 @@ export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD'; +export type { + AssertionResult, + TestResult, + SuiteResult, + RunResult, +} from '@tat/shared'; + export interface Suite { name: string; tags?: string[]; @@ -25,40 +32,7 @@ export interface Test { timeout?: number; } -export interface AssertionResult { - expr: string; - passed: boolean; - error?: string; - actual?: Array<{ operand: string; value: unknown }>; -} - -export interface TestResult { - name: string; - passed: boolean; - skipped?: boolean; - assertions: AssertionResult[]; - durationMs: number; - error?: string; - captures?: Record; - responseStatus?: number; - responseBody?: unknown; - responseHeaders?: Record; -} - -export interface SuiteResult { - name: string; - tags: string[]; - tests: TestResult[]; -} - -export interface RunResult { - suites: SuiteResult[]; - total: number; - passed: number; - failed: number; - skipped: number; - durationMs: number; -} +import type { RunResult } from '@tat/shared'; export interface FileRunResult { file: string; diff --git a/tests/contracts/cli-extension.contract.test.ts b/tests/contracts/cli-extension.contract.test.ts new file mode 100644 index 0000000..e7536b2 --- /dev/null +++ b/tests/contracts/cli-extension.contract.test.ts @@ -0,0 +1,193 @@ +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { createServer, type Server } from 'node:http'; +import { spawn } from 'node:child_process'; +import { fileURLToPath } from 'node:url'; +import path from 'node:path'; + +import { formatTestResultResponseLines } from '../../vscode-extension/src/resultFormatting'; +import { parseRunOutput } from '../../vscode-extension/src/tatRunner'; + +const rootDir = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..'); +const fixturesDir = path.join(rootDir, 'tests', 'contracts', 'fixtures'); +const cliPath = path.join(rootDir, 'tat-cli', 'dist', 'cli.js'); + +let server: Server; +let baseUrl: string; + +beforeAll(async () => { + server = createServer((req, res) => { + if (req.url === '/users/1') { + res.writeHead(200, { 'content-type': 'application/json' }); + res.end(JSON.stringify({ id: 1, name: 'Ada' })); + return; + } + + if (req.url === '/fail') { + res.writeHead(500, { 'content-type': 'application/json' }); + res.end(JSON.stringify({ error: 'boom' })); + return; + } + + res.writeHead(404, { 'content-type': 'application/json' }); + res.end(JSON.stringify({ error: 'not found' })); + }); + + await new Promise((resolve) => { + server.listen(0, '127.0.0.1', () => resolve()); + }); + + const address = server.address(); + if (!address || typeof address === 'string') { + throw new Error('Failed to start contract test server.'); + } + + baseUrl = `http://127.0.0.1:${address.port}`; +}); + +afterAll(async () => { + await new Promise((resolve, reject) => { + server.close((error) => { + if (error) { + reject(error); + return; + } + resolve(); + }); + }); +}); + +async function runTat(args: string[]): Promise<{ status: number | null; stdout: string; stderr: string }> { + return await new Promise((resolve, reject) => { + const child = spawn(process.execPath, [cliPath, ...args], { + cwd: rootDir, + stdio: ['ignore', 'pipe', 'pipe'], + }); + + let stdout = ''; + let stderr = ''; + + child.stdout.on('data', (chunk) => { + stdout += chunk.toString(); + }); + + child.stderr.on('data', (chunk) => { + stderr += chunk.toString(); + }); + + child.on('error', reject); + child.on('close', (status) => { + resolve({ status, stdout, stderr }); + }); + }); +} + +describe('CLI and VS Code extension contract harness', () => { + it('runs the built CLI against a .tat.json fixture and formats the result through extension helpers', async () => { + const fixture = path.join(fixturesDir, 'contract-pass.tat.json'); + + const runResult = await runTat([ + 'run', + fixture, + '--output', + 'json', + '--variables', + `baseUrl=${baseUrl}`, + '--insecure', + ]); + + expect(runResult.status).toBe(0); + + const parsed = parseRunOutput(runResult.stdout, `node ${cliPath} run ${fixture} --output json`); + const testResult = parsed.suites[0].tests[0]; + + expect(parsed.total).toBe(1); + expect(parsed.passed).toBe(1); + expect(testResult.captures).toEqual({ userId: '1' }); + + const responseLines = formatTestResultResponseLines(testResult); + expect(responseLines).toContain(' Response Status: 200'); + expect(responseLines.some((line) => line.includes('"name": "Ada"'))).toBe(true); + }); + + it('keeps exit code 1 while still emitting valid shared-contract JSON for a failing .tat.yml fixture', async () => { + const fixture = path.join(fixturesDir, 'contract-fail.tat.yml'); + const runResult = await runTat([ + 'run', + fixture, + '--output', + 'json', + '--variables', + `baseUrl=${baseUrl}`, + ]); + + expect(runResult.status).toBe(1); + + const parsed = parseRunOutput(runResult.stdout, `node ${cliPath} run ${fixture} --output json`); + expect(parsed.failed).toBe(1); + expect(parsed.suites[0].tests[0].assertions[0].expr).toBe('$status == 200'); + }); + + it('preserves skipped tests in .tat.yaml and still supports suite/test filters', async () => { + const fixture = path.join(fixturesDir, 'contract-filter.tat.yaml'); + + const fullRun = await runTat([ + 'run', + fixture, + '--output', + 'json', + '--variables', + `baseUrl=${baseUrl}`, + ]); + expect(fullRun.status).toBe(0); + + const fullParsed = parseRunOutput(fullRun.stdout, `node ${cliPath} run ${fixture} --output json`); + expect(fullParsed.total).toBe(2); + expect(fullParsed.skipped).toBe(1); + + const filteredRun = await runTat([ + 'run', + fixture, + '--output', + 'json', + '--suite', + 'Filters', + '--test', + 'Selected test', + '--variables', + `baseUrl=${baseUrl}`, + ]); + + expect(filteredRun.status).toBe(0); + const filteredParsed = parseRunOutput( + filteredRun.stdout, + `node ${cliPath} run ${fixture} --output json --suite Filters --test "Selected test"`, + ); + expect(filteredParsed.total).toBe(1); + expect(filteredParsed.skipped).toBe(0); + expect(filteredParsed.suites[0].tests[0].name).toBe('Selected test'); + }); + + it('emits request errors in the shared result shape for unreachable hosts', async () => { + const fixture = path.join(fixturesDir, 'request-error.tat.yaml'); + const runResult = await runTat(['run', fixture, '--output', 'json', '--timeout', '200']); + + expect(runResult.status).toBe(1); + + const parsed = parseRunOutput(runResult.stdout, `node ${cliPath} run ${fixture} --output json`); + expect(parsed.failed).toBe(1); + expect(parsed.suites[0].tests[0].error).toMatch(/fetch failed|connect|ECONNREFUSED|timeout/i); + }); + + it('keeps validate behavior stable for valid and invalid fixtures', async () => { + const validFixture = path.join(fixturesDir, 'contract-pass.tat.json'); + const invalidFixture = path.join(fixturesDir, 'invalid.tat.json'); + + const validResult = await runTat(['validate', validFixture]); + expect(validResult.status).toBe(0); + expect(validResult.stdout).toContain('valid'); + + const invalidResult = await runTat(['validate', invalidFixture]); + expect(invalidResult.status).toBe(2); + expect(invalidResult.stderr).toContain('Schema validation failed'); + }); +}); diff --git a/tests/contracts/fixtures/contract-fail.tat.yml b/tests/contracts/fixtures/contract-fail.tat.yml new file mode 100644 index 0000000..3ebcf1c --- /dev/null +++ b/tests/contracts/fixtures/contract-fail.tat.yml @@ -0,0 +1,11 @@ +suites: + - name: Failing users + tests: + - name: Fails with valid result json + method: GET + url: "{{baseUrl}}/fail" + assert: + - "$status == 200" + response: + status: true + body: true diff --git a/tests/contracts/fixtures/contract-filter.tat.yaml b/tests/contracts/fixtures/contract-filter.tat.yaml new file mode 100644 index 0000000..07a6f5b --- /dev/null +++ b/tests/contracts/fixtures/contract-filter.tat.yaml @@ -0,0 +1,14 @@ +suites: + - name: Filters + tests: + - name: Skipped test + skip: true + method: GET + url: "{{baseUrl}}/users/1" + assert: + - "$status == 200" + - name: Selected test + method: GET + url: "{{baseUrl}}/users/1" + assert: + - "$status == 200" diff --git a/tests/contracts/fixtures/contract-pass.tat.json b/tests/contracts/fixtures/contract-pass.tat.json new file mode 100644 index 0000000..bb3c32e --- /dev/null +++ b/tests/contracts/fixtures/contract-pass.tat.json @@ -0,0 +1,27 @@ +{ + "suites": [ + { + "name": "Users", + "tags": ["smoke"], + "tests": [ + { + "name": "Get user", + "method": "GET", + "url": "{{baseUrl}}/users/1", + "assert": [ + "$status == 200", + "id == 1" + ], + "capture": { + "userId": "id" + }, + "response": { + "status": true, + "body": true, + "headers": true + } + } + ] + } + ] +} diff --git a/tests/contracts/fixtures/invalid.tat.json b/tests/contracts/fixtures/invalid.tat.json new file mode 100644 index 0000000..d31c55d --- /dev/null +++ b/tests/contracts/fixtures/invalid.tat.json @@ -0,0 +1,15 @@ +{ + "suites": [ + { + "name": "Broken", + "tests": [ + { + "name": "Missing method and url", + "assert": [ + "$status == 200" + ] + } + ] + } + ] +} diff --git a/tests/contracts/fixtures/request-error.tat.yaml b/tests/contracts/fixtures/request-error.tat.yaml new file mode 100644 index 0000000..8b29783 --- /dev/null +++ b/tests/contracts/fixtures/request-error.tat.yaml @@ -0,0 +1,8 @@ +suites: + - name: Request errors + tests: + - name: Unreachable host + method: GET + url: "http://127.0.0.1:1/unreachable" + assert: + - "$status == 200" diff --git a/vscode-extension/CLAUDE.md b/vscode-extension/CLAUDE.md index 9c55cd6..51dbfec 100644 --- a/vscode-extension/CLAUDE.md +++ b/vscode-extension/CLAUDE.md @@ -8,6 +8,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co npm run build # bundle src/ → dist/extension.js via esbuild (CJS) npm run build:watch # same, with watch mode npm run lint # type-check only (tsc --noEmit), no emit +npm run test # run the extension unit tests through Vitest npm run package # produce tat-test-runner-x.x.x.vsix for distribution ``` @@ -15,7 +16,7 @@ Press **F5** in VS Code (with this folder open) to launch an Extension Developme ## Architecture -This is a VS Code extension that integrates the `tat` CLI into the Test Explorer UI. It is a **separate CJS package** — it must not import from the parent `../src` ESM package at runtime. +This is a VS Code extension that integrates the `tat` CLI into the Test Explorer UI. It is a **separate CJS package** and may only consume shared runtime contracts/helpers through the internal `@tat/shared` workspace package. It must not deep-import CLI source files. ### Build @@ -29,9 +30,9 @@ esbuild bundles everything into a single `dist/extension.js`. Key constraints: | File | Responsibility | |------|----------------| | `src/extension.ts` | `activate()` / `deactivate()` — wires `TatTestController`, `TatCodeLensProvider`, and the 4 commands | -| `src/types.ts` | Type-only re-exports of `RunResult`, `SuiteResult`, `TestResult`, `AssertionResult` from `../tat-cli/src/types.ts` — single source of truth, drift caught by `tsc --noEmit` | -| `src/fileParser.ts` | `parseTestFile(text, fileName)` — `JSON.parse` or `yaml.parse` for structure (based on file extension) + sequential regex line scan for `vscode.Range` positions. Also exports `isTatFile()` for extension checking. Uses `yaml` package for YAML parsing. | -| `src/tatRunner.ts` | Invokes the `tat` CLI as a child process via `execFileAsync`. Handles binary resolution, Windows `.cmd` wrapping, exit codes, and JSON parsing. | +| `src/types.ts` | Type-only re-exports of `RunResult`, `SuiteResult`, `TestResult`, `AssertionResult` from `@tat/shared` | +| `src/fileParser.ts` | Uses shared `parseTatFileContent()` / `isTatFile()` helpers from `@tat/shared` for structure, then adds VS Code-specific `Range` mapping | +| `src/tatRunner.ts` | Invokes the `tat` CLI as a child process. Handles binary resolution, Windows `.cmd` wrapping, exit codes, and validates JSON output with `RunResultSchema` from `@tat/shared` | | `src/testController.ts` | VS Code Testing API — discovers `*.tat.{json,yml,yaml}` files, builds the TestItem tree (file → suite → test), runs tests, maps results back to TestItems, populates the TEST RESULTS panel via `run.appendOutput()`. | | `src/codeLens.ts` | `TatCodeLensProvider` — "Run Suite ▶" / "Run Test ▶" CodeLens buttons above each suite and test in `.tat.json`, `.tat.yml`, and `.tat.yaml` files. | @@ -52,6 +53,11 @@ On Windows, `.cmd` files cannot be spawned directly by `execFile` — `resolveEx - Exit 1 → test failures; stdout **still contains valid `RunResult` JSON** — do not throw. - Exit 2 → config/validation error; stderr has the message. +The extension must keep these assumptions aligned with: +- `packages/tat-shared/src/contracts.ts` +- `tests/contracts/` +- `Rules/project-tat-cli-exit-codes.md` + ### TestItem ID scheme ``` diff --git a/vscode-extension/package.json b/vscode-extension/package.json index 4bbb378..0af4d61 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -103,16 +103,19 @@ "build": "node esbuild.js", "build:watch": "node esbuild.js --watch", "lint": "tsc --noEmit", + "test": "vitest run tests --config ../tat-cli/vitest.config.ts", "package": "vsce package --no-dependencies" }, "dependencies": { "yaml": "^2.7.0" }, "devDependencies": { + "@tat/shared": "file:../packages/tat-shared", "@types/node": "^20.0.0", "@types/vscode": "^1.87.0", "@vscode/vsce": "^2.24.0", "esbuild": "^0.21.0", - "typescript": "^5.4.0" + "typescript": "^5.4.0", + "vitest": "^2.0.0" } } diff --git a/vscode-extension/src/fileParser.ts b/vscode-extension/src/fileParser.ts index 7fd484e..7a6e0de 100644 --- a/vscode-extension/src/fileParser.ts +++ b/vscode-extension/src/fileParser.ts @@ -1,16 +1,8 @@ import * as vscode from 'vscode'; -import { parse as parseYaml } from 'yaml'; - -const TAT_EXTENSIONS = ['.tat.json', '.tat.yml', '.tat.yaml']; +import { isTatFile, isYamlTatFile, parseTatFileContent } from '@tat/shared'; /** Check whether a file path ends with a recognised TAT extension. */ -export function isTatFile(fileName: string): boolean { - return TAT_EXTENSIONS.some(ext => fileName.endsWith(ext)); -} - -function isYamlFile(fileName: string): boolean { - return fileName.endsWith('.tat.yml') || fileName.endsWith('.tat.yaml'); -} +export { isTatFile }; export interface ParsedTest { name: string; @@ -43,13 +35,9 @@ type TatFile = { export function parseTestFile(text: string, fileName = '.tat.json'): ParsedFile { let data: TatFile; try { - if (isYamlFile(fileName)) { - data = parseYaml(text) as TatFile; - } else { - data = JSON.parse(text) as TatFile; - } + data = parseTatFileContent(fileName, text) as TatFile; } catch { - const format = isYamlFile(fileName) ? 'YAML' : 'JSON'; + const format = isYamlTatFile(fileName) ? 'YAML' : 'JSON'; throw new Error(`${format} parse error in test file`); } @@ -61,7 +49,7 @@ export function parseTestFile(text: string, fileName = '.tat.json'): ParsedFile const suitesKeyLine = lines.findIndex(l => /"suites"\s*:/.test(l) || /^\s*suites\s*:/.test(l)); const fileRange = lineRange(lines, suitesKeyLine >= 0 ? suitesKeyLine : 0); - const yaml = isYamlFile(fileName); + const yaml = isYamlTatFile(fileName); const suites: ParsedSuite[] = []; let cursor = 0; diff --git a/vscode-extension/src/promptVariables.ts b/vscode-extension/src/promptVariables.ts index 9ff04f2..d83aca3 100644 --- a/vscode-extension/src/promptVariables.ts +++ b/vscode-extension/src/promptVariables.ts @@ -1,6 +1,6 @@ import { readFile } from 'fs/promises'; import * as path from 'path'; -import { parse as parseYaml } from 'yaml'; +import { isYamlTatFile, parseTatFileContent } from '@tat/shared'; interface PromptTest { name: string; @@ -28,18 +28,12 @@ export interface PromptVariable { sourceTestName: string; } -function isYamlFile(fileName: string): boolean { - return fileName.endsWith('.tat.yml') || fileName.endsWith('.tat.yaml'); -} - function parseTatFile(text: string, filePath: string): PromptTatFile { let parsed: unknown; try { - parsed = isYamlFile(filePath) - ? parseYaml(text) - : JSON.parse(text); + parsed = parseTatFileContent(filePath, text); } catch (error) { - const format = isYamlFile(filePath) ? 'YAML' : 'JSON'; + const format = isYamlTatFile(filePath) ? 'YAML' : 'JSON'; const message = error instanceof Error ? error.message : String(error); throw new Error(`${format} parse error in test file ${filePath}: ${message}`); } diff --git a/vscode-extension/src/tatRunner.ts b/vscode-extension/src/tatRunner.ts index 4b977dc..c8e457c 100644 --- a/vscode-extension/src/tatRunner.ts +++ b/vscode-extension/src/tatRunner.ts @@ -2,6 +2,7 @@ import { execFile, execSync, spawn } from 'child_process'; import { promisify } from 'util'; import * as path from 'path'; import * as fs from 'fs'; +import { RunResultSchema } from '@tat/shared'; import type { RunResult } from './types'; const execFileAsync = promisify(execFile); @@ -52,6 +53,18 @@ export interface ActiveRunFileHandle { cancel(): void; } +export function parseRunOutput(stdout: string, command: string): RunResult { + try { + return RunResultSchema.parse(JSON.parse(stdout.trim())); + } catch { + throw new Error( + `tat output was not valid JSON.\n` + + `Command: ${command}\n` + + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, + ); + } +} + export class TatNotFoundError extends Error { constructor(message: string) { super(message); @@ -202,7 +215,7 @@ export function startRunFile( if (code === 0 || (code === 1 && stdout)) { try { resolveOnce({ - result: JSON.parse(stdout.trim()) as RunResult, + result: parseRunOutput(stdout, `${bin} ${args.join(' ')}`), rawOutput: stdout, }); } catch { diff --git a/vscode-extension/src/types.ts b/vscode-extension/src/types.ts index 5f77885..a493a8f 100644 --- a/vscode-extension/src/types.ts +++ b/vscode-extension/src/types.ts @@ -1,8 +1,6 @@ -// Re-exported from the CLI package — single source of truth. -// These are compile-time only; they do not exist in the bundled CJS output. export type { AssertionResult, TestResult, SuiteResult, RunResult, -} from '../../tat-cli/src/types'; +} from '@tat/shared'; diff --git a/vscode-extension/tests/tatOutput.test.ts b/vscode-extension/tests/tatOutput.test.ts new file mode 100644 index 0000000..ed2a484 --- /dev/null +++ b/vscode-extension/tests/tatOutput.test.ts @@ -0,0 +1,51 @@ +import { describe, expect, it } from 'vitest'; + +import { parseRunOutput } from '../src/tatRunner'; + +describe('parseRunOutput', () => { + it('parses valid CLI JSON using the shared runtime contract', () => { + const parsed = parseRunOutput( + JSON.stringify({ + suites: [ + { + name: 'Users', + tags: [], + tests: [ + { + name: 'Get user', + passed: false, + assertions: [ + { + expr: '$status == 200', + passed: false, + actual: [{ operand: '$status', value: 500 }], + }, + ], + durationMs: 12, + error: 'Request failed', + }, + ], + }, + ], + total: 1, + passed: 0, + failed: 1, + skipped: 0, + durationMs: 12, + }), + 'tat run file.tat.json --output json', + ); + + expect(parsed.failed).toBe(1); + expect(parsed.suites[0].tests[0].assertions[0].actual?.[0]).toEqual({ + operand: '$status', + value: 500, + }); + }); + + it('throws a helpful error for invalid CLI JSON output', () => { + expect(() => parseRunOutput('{"failed":"nope"}', 'tat run broken.tat.json --output json')).toThrow( + 'tat output was not valid JSON.', + ); + }); +}); From 97bce78f6492d670cff2a2a8f65001d6556fd047 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 13:48:54 +0800 Subject: [PATCH 02/10] fix: tighten PR review follow-ups --- package.json | 2 +- vscode-extension/src/tatRunner.ts | 33 +++++++++++++++++------- vscode-extension/tests/tatOutput.test.ts | 6 +++++ 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 94600e0..0dec45b 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,7 @@ "lint": "npm --prefix tat-cli run lint && npm --prefix vscode-extension run lint && npm run lint:shared", "lint:shared": "npm exec --workspace tat-cli -- tsc -p ../packages/tat-shared/tsconfig.json --noEmit", "test": "npm --prefix tat-cli test && npm --prefix tat-cli exec vitest run vscode-extension/tests packages/tat-shared/tests --config tat-cli/vitest.config.ts", - "test:contracts": "npm --prefix tat-cli exec vitest run tests/contracts --config tat-cli/vitest.config.ts", + "test:contracts": "npm --prefix tat-cli run build && npm --prefix tat-cli exec vitest run tests/contracts --config tat-cli/vitest.config.ts", "verify": "npm run lint && npm run test && npm run build && npm run test:contracts", "smoke:packaged-cli": "node scripts/smoke-packaged-cli.mjs" } diff --git a/vscode-extension/src/tatRunner.ts b/vscode-extension/src/tatRunner.ts index c8e457c..7d6d103 100644 --- a/vscode-extension/src/tatRunner.ts +++ b/vscode-extension/src/tatRunner.ts @@ -3,6 +3,7 @@ import { promisify } from 'util'; import * as path from 'path'; import * as fs from 'fs'; import { RunResultSchema } from '@tat/shared'; +import { ZodError } from 'zod'; import type { RunResult } from './types'; const execFileAsync = promisify(execFile); @@ -55,10 +56,28 @@ export interface ActiveRunFileHandle { export function parseRunOutput(stdout: string, command: string): RunResult { try { - return RunResultSchema.parse(JSON.parse(stdout.trim())); - } catch { + const parsedJson = JSON.parse(stdout.trim()); + return RunResultSchema.parse(parsedJson); + } catch (error) { + if (error instanceof SyntaxError) { + throw new Error( + `tat output was not valid JSON.\n` + + `Command: ${command}\n` + + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, + ); + } + + if (error instanceof ZodError) { + throw new Error( + `tat output did not match the expected RunResult schema.\n` + + `Command: ${command}\n` + + `Schema issues:\n${error.issues.map((issue) => `- ${issue.path.join('.') || ''}: ${issue.message}`).join('\n')}\n` + + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, + ); + } + throw new Error( - `tat output was not valid JSON.\n` + + `tat output could not be parsed.\n` + `Command: ${command}\n` + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, ); @@ -218,12 +237,8 @@ export function startRunFile( result: parseRunOutput(stdout, `${bin} ${args.join(' ')}`), rawOutput: stdout, }); - } catch { - rejectOnce(new Error( - `tat output was not valid JSON.\n` + - `Command: ${bin} ${args.join(' ')}\n` + - `Output (first 800 chars):\n${stdout.slice(0, 800)}`, - )); + } catch (error) { + rejectOnce(error instanceof Error ? error : new Error(String(error))); } return; } diff --git a/vscode-extension/tests/tatOutput.test.ts b/vscode-extension/tests/tatOutput.test.ts index ed2a484..dec6d89 100644 --- a/vscode-extension/tests/tatOutput.test.ts +++ b/vscode-extension/tests/tatOutput.test.ts @@ -45,6 +45,12 @@ describe('parseRunOutput', () => { it('throws a helpful error for invalid CLI JSON output', () => { expect(() => parseRunOutput('{"failed":"nope"}', 'tat run broken.tat.json --output json')).toThrow( + 'tat output did not match the expected RunResult schema.', + ); + }); + + it('distinguishes malformed JSON from schema validation errors', () => { + expect(() => parseRunOutput('{not-json', 'tat run broken.tat.json --output json')).toThrow( 'tat output was not valid JSON.', ); }); From 78a28a66f7327b75264b61dc6c55089c02dd7b68 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 16:21:15 +0800 Subject: [PATCH 03/10] fix: preserve shared file parser errors --- vscode-extension/src/fileParser.ts | 13 +++------- vscode-extension/tests/fileParser.test.ts | 30 +++++++++++++++++++++++ 2 files changed, 34 insertions(+), 9 deletions(-) create mode 100644 vscode-extension/tests/fileParser.test.ts diff --git a/vscode-extension/src/fileParser.ts b/vscode-extension/src/fileParser.ts index 7a6e0de..ce7a98b 100644 --- a/vscode-extension/src/fileParser.ts +++ b/vscode-extension/src/fileParser.ts @@ -29,17 +29,12 @@ type TatFile = { /** * Parse a .tat.json / .tat.yml / .tat.yaml file and return suite/test names - * with their line positions. Uses JSON.parse or YAML.parse for structure + - * line scanning for positions. No external deps beyond the yaml package. + * with their line positions. Shared helpers from `@tat/shared` handle the + * JSON/YAML structure parsing while this module adds VS Code-specific range + * mapping for suites and tests. */ export function parseTestFile(text: string, fileName = '.tat.json'): ParsedFile { - let data: TatFile; - try { - data = parseTatFileContent(fileName, text) as TatFile; - } catch { - const format = isYamlTatFile(fileName) ? 'YAML' : 'JSON'; - throw new Error(`${format} parse error in test file`); - } + const data = parseTatFileContent(fileName, text) as TatFile; const lines = text.split('\n'); diff --git a/vscode-extension/tests/fileParser.test.ts b/vscode-extension/tests/fileParser.test.ts new file mode 100644 index 0000000..ce16a1f --- /dev/null +++ b/vscode-extension/tests/fileParser.test.ts @@ -0,0 +1,30 @@ +import { beforeEach, describe, expect, it, vi } from 'vitest'; + +vi.mock('vscode', () => ({ + Range: class Range { + constructor( + public startLineNumber: number, + public startColumn: number, + public endLineNumber: number, + public endColumn: number, + ) {} + }, +})); + +describe('parseTestFile', () => { + beforeEach(() => { + vi.resetModules(); + }); + + it('includes the underlying parse failure details for invalid JSON', async () => { + const { parseTestFile } = await import('../src/fileParser'); + + expect(() => parseTestFile('{', 'broken.tat.json')).toThrow(/Invalid JSON in broken\.tat\.json:/); + }); + + it('preserves unsupported-format errors from the shared parser', async () => { + const { parseTestFile } = await import('../src/fileParser'); + + expect(() => parseTestFile('{}', 'broken.json')).toThrow('Unsupported file format: broken.json'); + }); +}); From 66d849f07b5dd1da1322c61fdb1d45bf3f04fd2d Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 16:38:59 +0800 Subject: [PATCH 04/10] Address latest PR review feedback --- tat-cli/src/types.ts | 5 ++--- vscode-extension/src/promptVariables.ts | 11 ++--------- vscode-extension/tests/promptVariables.test.ts | 9 +++++++++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/tat-cli/src/types.ts b/tat-cli/src/types.ts index 2e8447c..facda1a 100644 --- a/tat-cli/src/types.ts +++ b/tat-cli/src/types.ts @@ -1,3 +1,5 @@ +import type { RunResult } from '@tat/shared'; + export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD'; export type { @@ -31,9 +33,6 @@ export interface Test { skip?: boolean; timeout?: number; } - -import type { RunResult } from '@tat/shared'; - export interface FileRunResult { file: string; result: RunResult; diff --git a/vscode-extension/src/promptVariables.ts b/vscode-extension/src/promptVariables.ts index d83aca3..3dcd4af 100644 --- a/vscode-extension/src/promptVariables.ts +++ b/vscode-extension/src/promptVariables.ts @@ -1,6 +1,6 @@ import { readFile } from 'fs/promises'; import * as path from 'path'; -import { isYamlTatFile, parseTatFileContent } from '@tat/shared'; +import { parseTatFileContent } from '@tat/shared'; interface PromptTest { name: string; @@ -29,14 +29,7 @@ export interface PromptVariable { } function parseTatFile(text: string, filePath: string): PromptTatFile { - let parsed: unknown; - try { - parsed = parseTatFileContent(filePath, text); - } catch (error) { - const format = isYamlTatFile(filePath) ? 'YAML' : 'JSON'; - const message = error instanceof Error ? error.message : String(error); - throw new Error(`${format} parse error in test file ${filePath}: ${message}`); - } + const parsed = parseTatFileContent(filePath, text); if ( parsed === null || diff --git a/vscode-extension/tests/promptVariables.test.ts b/vscode-extension/tests/promptVariables.test.ts index 07aca8f..6b0b703 100644 --- a/vscode-extension/tests/promptVariables.test.ts +++ b/vscode-extension/tests/promptVariables.test.ts @@ -175,4 +175,13 @@ describe('findPromptVariables', () => { `Invalid test file ${filePath}: expected an object with a suites array.`, ); }); + + it('preserves unsupported file format errors from the shared parser', async () => { + tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'tat-prompt-vars-')); + const filePath = writeTextFile(tmpDir, 'sample.json', '{"suites":[]}'); + + await expect(findPromptVariables(filePath, 'Workspace flow', 'Create project')).rejects.toThrow( + `Unsupported file format: ${filePath}`, + ); + }); }); From ec67e26657288c1fb2d94ddf2e963e0918487d27 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 16:53:13 +0800 Subject: [PATCH 05/10] Address remaining PR review feedback --- package-lock.json | 3 - packages/tat-shared/src/fileFormat.ts | 6 +- packages/tat-shared/tests/contracts.test.ts | 32 +- vscode-extension/CLAUDE.md | 2 +- vscode-extension/package-lock.json | 1004 ++++++++++++++++++- vscode-extension/package.json | 3 - 6 files changed, 1012 insertions(+), 38 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1876770..2bb47a9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2432,9 +2432,6 @@ "name": "tat-test-runner", "version": "1.0.5", "license": "MIT", - "dependencies": { - "yaml": "^2.7.0" - }, "devDependencies": { "@tat/shared": "file:../packages/tat-shared", "@types/node": "^20.0.0", diff --git a/packages/tat-shared/src/fileFormat.ts b/packages/tat-shared/src/fileFormat.ts index d95b77e..e36b51d 100644 --- a/packages/tat-shared/src/fileFormat.ts +++ b/packages/tat-shared/src/fileFormat.ts @@ -15,7 +15,8 @@ export function parseTatFileContent(filePath: string, raw: string): unknown { try { return JSON.parse(raw); } catch (error) { - throw new Error(`Invalid JSON in ${filePath}: ${(error as Error).message}`); + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Invalid JSON in ${filePath}: ${message}`); } } @@ -23,7 +24,8 @@ export function parseTatFileContent(filePath: string, raw: string): unknown { try { return parseYaml(raw); } catch (error) { - throw new Error(`Invalid YAML in ${filePath}: ${(error as Error).message}`); + const message = error instanceof Error ? error.message : String(error); + throw new Error(`Invalid YAML in ${filePath}: ${message}`); } } diff --git a/packages/tat-shared/tests/contracts.test.ts b/packages/tat-shared/tests/contracts.test.ts index 30f8f74..fd35544 100644 --- a/packages/tat-shared/tests/contracts.test.ts +++ b/packages/tat-shared/tests/contracts.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it } from 'vitest'; +import { describe, expect, it, vi, afterEach } from 'vitest'; import { AssertionResultSchema, @@ -50,6 +50,12 @@ describe('tat shared result contracts', () => { }); describe('tat shared file format helpers', () => { + afterEach(() => { + vi.restoreAllMocks(); + vi.doUnmock('yaml'); + vi.resetModules(); + }); + it('tracks the supported tat extensions', () => { expect(TAT_EXTENSIONS).toEqual(['.tat.json', '.tat.yml', '.tat.yaml']); }); @@ -83,4 +89,28 @@ describe('tat shared file format helpers', () => { 'Unsupported file format: users.json', ); }); + + it('preserves non-Error JSON parser failures', () => { + vi.spyOn(JSON, 'parse').mockImplementationOnce(() => { + throw 'bad json payload'; + }); + + expect(() => parseTatFileContent('users.tat.json', '{')).toThrow( + 'Invalid JSON in users.tat.json: bad json payload', + ); + }); + + it('preserves non-Error YAML parser failures', async () => { + vi.doMock('yaml', () => ({ + parse: () => { + throw 'bad yaml payload'; + }, + })); + + const { parseTatFileContent: parseTatFileContentWithMockedYaml } = await import('../src/fileFormat.ts'); + + expect(() => parseTatFileContentWithMockedYaml('users.tat.yml', 'suites: [')).toThrow( + 'Invalid YAML in users.tat.yml: bad yaml payload', + ); + }); }); diff --git a/vscode-extension/CLAUDE.md b/vscode-extension/CLAUDE.md index 51dbfec..22f6a2f 100644 --- a/vscode-extension/CLAUDE.md +++ b/vscode-extension/CLAUDE.md @@ -23,7 +23,7 @@ This is a VS Code extension that integrates the `tat` CLI into the Test Explorer esbuild bundles everything into a single `dist/extension.js`. Key constraints: - `format: 'cjs'` — VS Code extension host uses `require()`, not ESM. - `external: ['vscode']` — `vscode` is provided by the host; never bundle it. -- All other deps (currently `yaml` at runtime) are bundled in. +- All other non-`vscode` deps are bundled in, including the shared parser/runtime helpers pulled in through `@tat/shared`. ### Source files diff --git a/vscode-extension/package-lock.json b/vscode-extension/package-lock.json index fd48254..0df48f8 100644 --- a/vscode-extension/package-lock.json +++ b/vscode-extension/package-lock.json @@ -8,20 +8,28 @@ "name": "tat-test-runner", "version": "1.0.5", "license": "MIT", - "dependencies": { - "yaml": "^2.7.0" - }, "devDependencies": { + "@tat/shared": "file:../packages/tat-shared", "@types/node": "^20.0.0", "@types/vscode": "^1.87.0", "@vscode/vsce": "^2.24.0", "esbuild": "^0.21.0", - "typescript": "^5.4.0" + "typescript": "^5.4.0", + "vitest": "^2.0.0" }, "engines": { "vscode": "^1.87.0" } }, + "../packages/tat-shared": { + "name": "@tat/shared", + "version": "0.0.0", + "dev": true, + "dependencies": { + "yaml": "^2.7.0", + "zod": "^3.22.0" + } + }, "node_modules/@azure/abort-controller": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/@azure/abort-controller/-/abort-controller-2.1.2.tgz", @@ -582,6 +590,374 @@ "node": ">=12" } }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.5.5", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", + "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", + "dev": true, + "license": "MIT" + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.2.tgz", + "integrity": "sha512-dnlp69efPPg6Uaw2dVqzWRfAWRnYVb1XJ8CyyhIbZeaq4CA5/mLeZ1IEt9QqQxmbdvagjLIm2ZL8BxXv5lH4Yw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.2.tgz", + "integrity": "sha512-OqZTwDRDchGRHHm/hwLOL7uVPB9aUvI0am/eQuWMNyFHf5PSEQmyEeYYheA0EPPKUO/l0uigCp+iaTjoLjVoHg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.2.tgz", + "integrity": "sha512-UwRE7CGpvSVEQS8gUMBe1uADWjNnVgP3Iusyda1nSRwNDCsRjnGc7w6El6WLQsXmZTbLZx9cecegumcitNfpmA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.2.tgz", + "integrity": "sha512-gjEtURKLCC5VXm1I+2i1u9OhxFsKAQJKTVB8WvDAHF+oZlq0GTVFOlTlO1q3AlCTE/DF32c16ESvfgqR7343/g==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-freebsd-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.2.tgz", + "integrity": "sha512-Bcl6CYDeAgE70cqZaMojOi/eK63h5Me97ZqAQoh77VPjMysA/4ORQBRGo3rRy45x4MzVlU9uZxs8Uwy7ZaKnBw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-freebsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.2.tgz", + "integrity": "sha512-LU+TPda3mAE2QB0/Hp5VyeKJivpC6+tlOXd1VMoXV/YFMvk/MNk5iXeBfB4MQGRWyOYVJ01625vjkr0Az98OJQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.2.tgz", + "integrity": "sha512-2QxQrM+KQ7DAW4o22j+XZ6RKdxjLD7BOWTP0Bv0tmjdyhXSsr2Ul1oJDQqh9Zf5qOwTuTc7Ek83mOFaKnodPjg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.2.tgz", + "integrity": "sha512-TbziEu2DVsTEOPif2mKWkMeDMLoYjx95oESa9fkQQK7r/Orta0gnkcDpzwufEcAO2BLBsD7mZkXGFqEdMRRwfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.2.tgz", + "integrity": "sha512-bO/rVDiDUuM2YfuCUwZ1t1cP+/yqjqz+Xf2VtkdppefuOFS2OSeAfgafaHNkFn0t02hEyXngZkxtGqXcXwO8Rg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.2.tgz", + "integrity": "sha512-hr26p7e93Rl0Za+JwW7EAnwAvKkehh12BU1Llm9Ykiibg4uIr2rbpxG9WCf56GuvidlTG9KiiQT/TXT1yAWxTA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.2.tgz", + "integrity": "sha512-pOjB/uSIyDt+ow3k/RcLvUAOGpysT2phDn7TTUB3n75SlIgZzM6NKAqlErPhoFU+npgY3/n+2HYIQVbF70P9/A==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.2.tgz", + "integrity": "sha512-2/w+q8jszv9Ww1c+6uJT3OwqhdmGP2/4T17cu8WuwyUuuaCDDJ2ojdyYwZzCxx0GcsZBhzi3HmH+J5pZNXnd+Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.2.tgz", + "integrity": "sha512-11+aL5vKheYgczxtPVVRhdptAM2H7fcDR5Gw4/bTcteuZBlH4oP9f5s9zYO9aGZvoGeBpqXI/9TZZihZ609wKw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.2.tgz", + "integrity": "sha512-i16fokAGK46IVZuV8LIIwMdtqhin9hfYkCh8pf8iC3QU3LpwL+1FSFGej+O7l3E/AoknL6Dclh2oTdnRMpTzFQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.2.tgz", + "integrity": "sha512-49FkKS6RGQoriDSK/6E2GkAsAuU5kETFCh7pG4yD/ylj9rKhTmO3elsnmBvRD4PgJPds5W2PkhC82aVwmUcJ7A==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.2.tgz", + "integrity": "sha512-mjYNkHPfGpUR00DuM1ZZIgs64Hpf4bWcz9Z41+4Q+pgDx73UwWdAYyf6EG/lRFldmdHHzgrYyge5akFUW0D3mQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.2.tgz", + "integrity": "sha512-ALyvJz965BQk8E9Al/JDKKDLH2kfKFLTGMlgkAbbYtZuJt9LU8DW3ZoDMCtQpXAltZxwBHevXz5u+gf0yA0YoA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.2.tgz", + "integrity": "sha512-UQjrkIdWrKI626Du8lCQ6MJp/6V1LAo2bOK9OTu4mSn8GGXIkPXk/Vsp4bLHCd9Z9Iz2OTEaokUE90VweJgIYQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.2.tgz", + "integrity": "sha512-bTsRGj6VlSdn/XD4CGyzMnzaBs9bsRxy79eTqTCBsA8TMIEky7qg48aPkvJvFe1HyzQ5oMZdg7AnVlWQSKLTnw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.2.tgz", + "integrity": "sha512-6d4Z3534xitaA1FcMWP7mQPq5zGwBmGbhphh2DwaA1aNIXUu3KTOfwrWpbwI4/Gr0uANo7NTtaykFyO2hPuFLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.2.tgz", + "integrity": "sha512-NetAg5iO2uN7eB8zE5qrZ3CSil+7IJt4WDFLcC75Ymywq1VZVD6qJ6EvNLjZ3rEm6gB7XW5JdT60c6MN35Z85Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.2.tgz", + "integrity": "sha512-NCYhOotpgWZ5kdxCZsv6Iudx0wX8980Q/oW4pNFNihpBKsDbEA1zpkfxJGC0yugsUuyDZ7gL37dbzwhR0VI7pQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.2.tgz", + "integrity": "sha512-RXsaOqXxfoUBQoOgvmmijVxJnW2IGB0eoMO7F8FAjaj0UTywUO/luSqimWBJn04WNgUkeNhh7fs7pESXajWmkg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.2.tgz", + "integrity": "sha512-qdAzEULD+/hzObedtmV6iBpdL5TIbKVztGiK7O3/KYSf+HIzU257+MX1EXJcyIiDbMAqmbwaufcYPvyRryeZtA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.2.tgz", + "integrity": "sha512-Nd/SgG27WoA9e+/TdK74KnHz852TLa94ovOYySo/yMPuTmpckK/jIF2jSwS3g7ELSKXK13/cVdmg1Z/DaCWKxA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@tat/shared": { + "resolved": "../packages/tat-shared", + "link": true + }, + "node_modules/@types/estree": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", + "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/node": { "version": "20.19.37", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.37.tgz", @@ -599,19 +975,132 @@ "dev": true, "license": "MIT" }, - "node_modules/@typespec/ts-http-runtime": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.4.tgz", - "integrity": "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ==", + "node_modules/@typespec/ts-http-runtime": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@typespec/ts-http-runtime/-/ts-http-runtime-0.3.4.tgz", + "integrity": "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@vitest/expect": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-2.1.9.tgz", + "integrity": "sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/mocker": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-2.1.9.tgz", + "integrity": "sha512-tVL6uJgoUdi6icpxmdrn5YNo3g3Dxv+IHJBr0GXHaEdTcw3F+cPKnsXFhli6nO+f/6SDKPHEK1UN+k+TQv0Ehg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/spy": "2.1.9", + "estree-walker": "^3.0.3", + "magic-string": "^0.30.12" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "msw": "^2.4.9", + "vite": "^5.0.0" + }, + "peerDependenciesMeta": { + "msw": { + "optional": true + }, + "vite": { + "optional": true + } + } + }, + "node_modules/@vitest/pretty-format": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-2.1.9.tgz", + "integrity": "sha512-KhRIdGV2U9HOUzxfiHmY8IFHTdqtOhIzCpd8WRdJiE7D/HUcZVD0EgQCVjm+Q9gkUXWgBvMmTtZgIG48wq7sOQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyrainbow": "^1.2.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/runner": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-2.1.9.tgz", + "integrity": "sha512-ZXSSqTFIrzduD63btIfEyOmNcBmQvgOVsPNPe0jYtESiXkhd8u2erDLnMxmGrDCwHCCHE7hxwRDCT3pt0esT4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/utils": "2.1.9", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/snapshot": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-2.1.9.tgz", + "integrity": "sha512-oBO82rEjsxLNJincVhLhaxxZdEtV0EFHMK5Kmx5sJ6H9L183dHECjiefOAdnqpIgT5eZwT04PoggUnW88vOBNQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/pretty-format": "2.1.9", + "magic-string": "^0.30.12", + "pathe": "^1.1.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/spy": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-2.1.9.tgz", + "integrity": "sha512-E1B35FwzXXTs9FHNK6bDszs7mtydNi5MIfUWpceJ8Xbfb1gBMscAnwLbEu+B44ed6W3XjL9/ehLPHR1fkf1KLQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinyspy": "^3.0.2" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/@vitest/utils": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-2.1.9.tgz", + "integrity": "sha512-v0psaMSkNJ3A2NMrUEHFRzJtDPFn+/VWZ5WxImB21T9fjucJRmS7xCS3ppEnARb9y11OAzaD+P2Ps+b+BGX5iQ==", "dev": true, "license": "MIT", "dependencies": { - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.0", - "tslib": "^2.6.2" + "@vitest/pretty-format": "2.1.9", + "loupe": "^3.1.2", + "tinyrainbow": "^1.2.0" }, - "engines": { - "node": ">=20.0.0" + "funding": { + "url": "https://opencollective.com/vitest" } }, "node_modules/@vscode/vsce": { @@ -831,6 +1320,16 @@ "dev": true, "license": "Python-2.0" }, + "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", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -968,6 +1467,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/cac": { + "version": "6.7.14", + "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", + "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", @@ -999,6 +1508,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/chai": { + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", + "dev": true, + "license": "MIT", + "dependencies": { + "assertion-error": "^2.0.1", + "check-error": "^2.1.1", + "deep-eql": "^5.0.1", + "loupe": "^3.1.0", + "pathval": "^2.0.0" + }, + "engines": { + "node": ">=18" + } + }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -1014,6 +1540,16 @@ "node": ">=4" } }, + "node_modules/check-error": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 16" + } + }, "node_modules/cheerio": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz", @@ -1188,6 +1724,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/deep-eql": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz", + "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/deep-extend": { "version": "0.6.0", "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", @@ -1405,6 +1951,13 @@ "node": ">= 0.4" } }, + "node_modules/es-module-lexer": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz", + "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==", + "dev": true, + "license": "MIT" + }, "node_modules/es-object-atoms": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", @@ -1483,6 +2036,16 @@ "node": ">=0.8.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/expand-template": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", @@ -1494,6 +2057,16 @@ "node": ">=6" } }, + "node_modules/expect-type": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", @@ -1536,6 +2109,21 @@ "dev": true, "license": "ISC" }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -2002,6 +2590,13 @@ "dev": true, "license": "MIT" }, + "node_modules/loupe": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", + "dev": true, + "license": "MIT" + }, "node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2015,6 +2610,16 @@ "node": ">=10" } }, + "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/markdown-it": { "version": "12.3.2", "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", @@ -2155,6 +2760,25 @@ "dev": true, "license": "ISC" }, + "node_modules/nanoid": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", + "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, "node_modules/napi-build-utils": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", @@ -2323,6 +2947,23 @@ "node": ">=0.10.0" } }, + "node_modules/pathe": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/pathe/-/pathe-1.1.2.tgz", + "integrity": "sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/pathval": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz", + "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 14.16" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -2330,6 +2971,42 @@ "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/postcss": { + "version": "8.5.10", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.10.tgz", + "integrity": "sha512-pMMHxBOZKFU6HgAZ4eyGnwXF/EvPGGqUr0MnZ5+99485wwW41kW91A4LOGxSHhgugZmSChL5AlElNdwlNgcnLQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.11", + "picocolors": "^1.1.1", + "source-map-js": "^1.2.1" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, "node_modules/prebuild-install": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", @@ -2433,6 +3110,51 @@ "node": ">= 6" } }, + "node_modules/rollup": { + "version": "4.60.2", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.2.tgz", + "integrity": "sha512-J9qZyW++QK/09NyN/zeO0dG/1GdGfyp9lV8ajHnRVLfo/uFsbji5mHnDgn/qYdUHyCkM2N+8VyspgZclfAh0eQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.8" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.60.2", + "@rollup/rollup-android-arm64": "4.60.2", + "@rollup/rollup-darwin-arm64": "4.60.2", + "@rollup/rollup-darwin-x64": "4.60.2", + "@rollup/rollup-freebsd-arm64": "4.60.2", + "@rollup/rollup-freebsd-x64": "4.60.2", + "@rollup/rollup-linux-arm-gnueabihf": "4.60.2", + "@rollup/rollup-linux-arm-musleabihf": "4.60.2", + "@rollup/rollup-linux-arm64-gnu": "4.60.2", + "@rollup/rollup-linux-arm64-musl": "4.60.2", + "@rollup/rollup-linux-loong64-gnu": "4.60.2", + "@rollup/rollup-linux-loong64-musl": "4.60.2", + "@rollup/rollup-linux-ppc64-gnu": "4.60.2", + "@rollup/rollup-linux-ppc64-musl": "4.60.2", + "@rollup/rollup-linux-riscv64-gnu": "4.60.2", + "@rollup/rollup-linux-riscv64-musl": "4.60.2", + "@rollup/rollup-linux-s390x-gnu": "4.60.2", + "@rollup/rollup-linux-x64-gnu": "4.60.2", + "@rollup/rollup-linux-x64-musl": "4.60.2", + "@rollup/rollup-openbsd-x64": "4.60.2", + "@rollup/rollup-openharmony-arm64": "4.60.2", + "@rollup/rollup-win32-arm64-msvc": "4.60.2", + "@rollup/rollup-win32-ia32-msvc": "4.60.2", + "@rollup/rollup-win32-x64-gnu": "4.60.2", + "@rollup/rollup-win32-x64-msvc": "4.60.2", + "fsevents": "~2.3.2" + } + }, "node_modules/run-applescript": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.1.0.tgz", @@ -2573,6 +3295,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/simple-concat": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", @@ -2622,6 +3351,30 @@ "simple-concat": "^1.0.0" } }, + "node_modules/source-map-js": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", + "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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/std-env": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", + "dev": true, + "license": "MIT" + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -2689,6 +3442,50 @@ "node": ">=6" } }, + "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": "0.3.2", + "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", + "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==", + "dev": true, + "license": "MIT" + }, + "node_modules/tinypool": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz", + "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^18.0.0 || >=20.0.0" + } + }, + "node_modules/tinyrainbow": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-1.2.0.tgz", + "integrity": "sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/tinyspy": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-3.0.2.tgz", + "integrity": "sha512-n1cw8k1k0x4pgA2+9XrOkFydTerNcJ1zWCO5Nn9scWHTD+5tp8dghT2x1uduQePZTZgd3Tupf+x9BxJjeJi77Q==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.0.0" + } + }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -2812,6 +3609,155 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/vite": { + "version": "5.4.21", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.21.tgz", + "integrity": "sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.43", + "rollup": "^4.20.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } + }, + "node_modules/vite-node": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-2.1.9.tgz", + "integrity": "sha512-AM9aQ/IPrW/6ENLQg3AGY4K1N2TGZdR5e4gu/MmmR2xR3Ll1+dib+nook92g4TV3PXVyeyxdWwtaCAiUL0hMxA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cac": "^6.7.14", + "debug": "^4.3.7", + "es-module-lexer": "^1.5.4", + "pathe": "^1.1.2", + "vite": "^5.0.0" + }, + "bin": { + "vite-node": "vite-node.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + } + }, + "node_modules/vitest": { + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/vitest/-/vitest-2.1.9.tgz", + "integrity": "sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@vitest/expect": "2.1.9", + "@vitest/mocker": "2.1.9", + "@vitest/pretty-format": "^2.1.9", + "@vitest/runner": "2.1.9", + "@vitest/snapshot": "2.1.9", + "@vitest/spy": "2.1.9", + "@vitest/utils": "2.1.9", + "chai": "^5.1.2", + "debug": "^4.3.7", + "expect-type": "^1.1.0", + "magic-string": "^0.30.12", + "pathe": "^1.1.2", + "std-env": "^3.8.0", + "tinybench": "^2.9.0", + "tinyexec": "^0.3.1", + "tinypool": "^1.0.1", + "tinyrainbow": "^1.2.0", + "vite": "^5.0.0", + "vite-node": "2.1.9", + "why-is-node-running": "^2.3.0" + }, + "bin": { + "vitest": "vitest.mjs" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://opencollective.com/vitest" + }, + "peerDependencies": { + "@edge-runtime/vm": "*", + "@types/node": "^18.0.0 || >=20.0.0", + "@vitest/browser": "2.1.9", + "@vitest/ui": "2.1.9", + "happy-dom": "*", + "jsdom": "*" + }, + "peerDependenciesMeta": { + "@edge-runtime/vm": { + "optional": true + }, + "@types/node": { + "optional": true + }, + "@vitest/browser": { + "optional": true + }, + "@vitest/ui": { + "optional": true + }, + "happy-dom": { + "optional": true + }, + "jsdom": { + "optional": true + } + } + }, "node_modules/whatwg-encoding": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", @@ -2836,6 +3782,23 @@ "node": ">=18" } }, + "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/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -2890,21 +3853,6 @@ "dev": true, "license": "ISC" }, - "node_modules/yaml": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz", - "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==", - "license": "ISC", - "bin": { - "yaml": "bin.mjs" - }, - "engines": { - "node": ">= 14.6" - }, - "funding": { - "url": "https://github.com/sponsors/eemeli" - } - }, "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", diff --git a/vscode-extension/package.json b/vscode-extension/package.json index 0af4d61..4d19bcf 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -106,9 +106,6 @@ "test": "vitest run tests --config ../tat-cli/vitest.config.ts", "package": "vsce package --no-dependencies" }, - "dependencies": { - "yaml": "^2.7.0" - }, "devDependencies": { "@tat/shared": "file:../packages/tat-shared", "@types/node": "^20.0.0", From 81067879ec2ab1c958a518690ecd5ff97c3f91f2 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 16:55:45 +0800 Subject: [PATCH 06/10] Fix shared test import for CI lint --- packages/tat-shared/tests/contracts.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/tat-shared/tests/contracts.test.ts b/packages/tat-shared/tests/contracts.test.ts index fd35544..507f9a0 100644 --- a/packages/tat-shared/tests/contracts.test.ts +++ b/packages/tat-shared/tests/contracts.test.ts @@ -107,7 +107,7 @@ describe('tat shared file format helpers', () => { }, })); - const { parseTatFileContent: parseTatFileContentWithMockedYaml } = await import('../src/fileFormat.ts'); + const { parseTatFileContent: parseTatFileContentWithMockedYaml } = await import('../src/fileFormat.js'); expect(() => parseTatFileContentWithMockedYaml('users.tat.yml', 'suites: [')).toThrow( 'Invalid YAML in users.tat.yml: bad yaml payload', From d524f1360ad0d57371fc777537c886c873e27539 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 18:26:22 +0800 Subject: [PATCH 07/10] Make shared CLI bundling explicit --- tat-cli/tsup.config.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/tat-cli/tsup.config.ts b/tat-cli/tsup.config.ts index c02fd76..878d86d 100644 --- a/tat-cli/tsup.config.ts +++ b/tat-cli/tsup.config.ts @@ -8,6 +8,7 @@ export default defineConfig({ format: ['esm'], clean: true, sourcemap: true, + noExternal: ['@tat/shared'], banner: { js: '#!/usr/bin/env node', }, From 49fb1b9fbbe8adedea18eeeead104d0a07185402 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 18:39:58 +0800 Subject: [PATCH 08/10] Harden extension run output diagnostics --- vscode-extension/src/tatRunner.ts | 55 +++++++++++++++++------- vscode-extension/tests/tatRunner.test.ts | 23 ++++++++++ 2 files changed, 63 insertions(+), 15 deletions(-) diff --git a/vscode-extension/src/tatRunner.ts b/vscode-extension/src/tatRunner.ts index 7d6d103..20a46e2 100644 --- a/vscode-extension/src/tatRunner.ts +++ b/vscode-extension/src/tatRunner.ts @@ -3,7 +3,6 @@ import { promisify } from 'util'; import * as path from 'path'; import * as fs from 'fs'; import { RunResultSchema } from '@tat/shared'; -import { ZodError } from 'zod'; import type { RunResult } from './types'; const execFileAsync = promisify(execFile); @@ -57,7 +56,17 @@ export interface ActiveRunFileHandle { export function parseRunOutput(stdout: string, command: string): RunResult { try { const parsedJson = JSON.parse(stdout.trim()); - return RunResultSchema.parse(parsedJson); + const result = RunResultSchema.safeParse(parsedJson); + if (result.success) { + return result.data; + } + + throw new Error( + `tat output did not match the expected RunResult schema.\n` + + `Command: ${command}\n` + + `Schema issues:\n${result.error.issues.map((issue) => `- ${issue.path.join('.') || ''}: ${issue.message}`).join('\n')}\n` + + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, + ); } catch (error) { if (error instanceof SyntaxError) { throw new Error( @@ -67,23 +76,39 @@ export function parseRunOutput(stdout: string, command: string): RunResult { ); } - if (error instanceof ZodError) { - throw new Error( - `tat output did not match the expected RunResult schema.\n` + - `Command: ${command}\n` + - `Schema issues:\n${error.issues.map((issue) => `- ${issue.path.join('.') || ''}: ${issue.message}`).join('\n')}\n` + - `Output (first 800 chars):\n${stdout.slice(0, 800)}`, - ); - } - throw new Error( - `tat output could not be parsed.\n` + - `Command: ${command}\n` + - `Output (first 800 chars):\n${stdout.slice(0, 800)}`, + error instanceof Error + ? error.message + : `tat output could not be parsed.\n` + + `Command: ${command}\n` + + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, ); } } +function formatDiagnosticCommand(bin: string, args: string[]): string { + const redactedArgs: string[] = []; + + for (let i = 0; i < args.length; i += 1) { + const arg = args[i]; + if (arg === '--variables') { + redactedArgs.push(arg); + const assignment = args[i + 1]; + if (assignment) { + const eqIndex = assignment.indexOf('='); + const key = eqIndex >= 0 ? assignment.slice(0, eqIndex) : assignment; + redactedArgs.push(`${key}=***`); + i += 1; + } + continue; + } + + redactedArgs.push(arg); + } + + return `${bin} ${redactedArgs.join(' ')}`; +} + export class TatNotFoundError extends Error { constructor(message: string) { super(message); @@ -234,7 +259,7 @@ export function startRunFile( if (code === 0 || (code === 1 && stdout)) { try { resolveOnce({ - result: parseRunOutput(stdout, `${bin} ${args.join(' ')}`), + result: parseRunOutput(stdout, formatDiagnosticCommand(bin, args)), rawOutput: stdout, }); } catch (error) { diff --git a/vscode-extension/tests/tatRunner.test.ts b/vscode-extension/tests/tatRunner.test.ts index c53ae3f..70fff4e 100644 --- a/vscode-extension/tests/tatRunner.test.ts +++ b/vscode-extension/tests/tatRunner.test.ts @@ -89,6 +89,29 @@ describe('startRunFile', () => { await expect(handle.result).rejects.toBeInstanceOf(TatRunCancelledError); expect(child.kill).toHaveBeenCalledTimes(1); }); + + it('redacts variable values from diagnostic command output', async () => { + const child = new FakeChildProcess(); + spawnMock.mockReturnValue(child); + execSyncMock.mockImplementation(() => { + throw new Error('tat not on PATH'); + }); + + const { startRunFile } = await import('../src/tatRunner'); + const handle = startRunFile('/workspace/sample.tat.json', [], { + variables: { + apiKey: 'secret-token', + username: 'alice', + }, + }); + + child.stdout.emit('data', Buffer.from('{"failed":"nope"}')); + child.emit('close', 1); + + await expect(handle.result).rejects.toThrow(/--variables apiKey=\*\*\* --variables username=\*\*\*/); + await expect(handle.result).rejects.not.toThrow('secret-token'); + await expect(handle.result).rejects.not.toThrow('alice'); + }); }); describe('resolveTatBinary', () => { From 199c58d42937ba2527c3977b1385ed3461c71836 Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 18:52:40 +0800 Subject: [PATCH 09/10] Preserve extension parse error metadata --- vscode-extension/src/tatRunner.ts | 12 +++++--- vscode-extension/tests/tatOutput.test.ts | 39 +++++++++++++++++++++++- 2 files changed, 45 insertions(+), 6 deletions(-) diff --git a/vscode-extension/src/tatRunner.ts b/vscode-extension/src/tatRunner.ts index 20a46e2..4a7d41b 100644 --- a/vscode-extension/src/tatRunner.ts +++ b/vscode-extension/src/tatRunner.ts @@ -76,12 +76,14 @@ export function parseRunOutput(stdout: string, command: string): RunResult { ); } + if (error instanceof Error) { + throw error; + } + throw new Error( - error instanceof Error - ? error.message - : `tat output could not be parsed.\n` + - `Command: ${command}\n` + - `Output (first 800 chars):\n${stdout.slice(0, 800)}`, + `tat output could not be parsed.\n` + + `Command: ${command}\n` + + `Output (first 800 chars):\n${stdout.slice(0, 800)}`, ); } } diff --git a/vscode-extension/tests/tatOutput.test.ts b/vscode-extension/tests/tatOutput.test.ts index dec6d89..188c6f2 100644 --- a/vscode-extension/tests/tatOutput.test.ts +++ b/vscode-extension/tests/tatOutput.test.ts @@ -1,8 +1,13 @@ -import { describe, expect, it } from 'vitest'; +import { afterEach, describe, expect, it, vi } from 'vitest'; import { parseRunOutput } from '../src/tatRunner'; describe('parseRunOutput', () => { + afterEach(() => { + vi.doUnmock('@tat/shared'); + vi.resetModules(); + }); + it('parses valid CLI JSON using the shared runtime contract', () => { const parsed = parseRunOutput( JSON.stringify({ @@ -54,4 +59,36 @@ describe('parseRunOutput', () => { 'tat output was not valid JSON.', ); }); + + it('rethrows the original Error when schema parsing throws unexpectedly', async () => { + class SchemaParseError extends Error { + marker = 'schema-parse'; + } + + const schemaError = new SchemaParseError('schema parser exploded'); + + vi.doMock('@tat/shared', async () => { + const actual = await vi.importActual('@tat/shared'); + return { + ...actual, + RunResultSchema: { + safeParse: () => { + throw schemaError; + }, + }, + }; + }); + + const { parseRunOutput: parseRunOutputWithThrowingSchema } = await import('../src/tatRunner'); + + let thrown: unknown; + try { + parseRunOutputWithThrowingSchema('{"total":1}', 'tat run file.tat.json --output json'); + } catch (error) { + thrown = error; + } + + expect(thrown).toBeInstanceOf(SchemaParseError); + expect((thrown as SchemaParseError).marker).toBe('schema-parse'); + }); }); From 0aef2b7a11691919d42d4b310432f3e5e670428d Mon Sep 17 00:00:00 2001 From: joehom Date: Sat, 25 Apr 2026 20:27:45 +0800 Subject: [PATCH 10/10] Keep release bump PR lockfiles in sync --- .github/workflows/publish-npm.yml | 1 + .github/workflows/publish-vscode.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml index 6e82b38..46e4b7d 100644 --- a/.github/workflows/publish-npm.yml +++ b/.github/workflows/publish-npm.yml @@ -68,3 +68,4 @@ jobs: add-paths: | package-lock.json tat-cli/package.json + tat-cli/package-lock.json diff --git a/.github/workflows/publish-vscode.yml b/.github/workflows/publish-vscode.yml index 7018b76..a22c759 100644 --- a/.github/workflows/publish-vscode.yml +++ b/.github/workflows/publish-vscode.yml @@ -64,3 +64,4 @@ jobs: add-paths: | package-lock.json vscode-extension/package.json + vscode-extension/package-lock.json