diff --git a/.gitignore b/.gitignore index bfa5480a32..ebb52e4887 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,6 @@ packages/cli-*/bin/ # Turbo .turbo/ + +# Vitest 5 artifact directory (blob reports, attachments, html/json output) +.vitest/ diff --git a/AGENTS.md b/AGENTS.md index 9e313dc366..b84e38962c 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -47,6 +47,17 @@ Expected exceptions: } ``` +**vitest.config.ts:** + +Package configs build on the repo-root `vitest.shared.ts` preset. `definePackageConfig` merges the +shared defaults (bun export-condition resolution for workspace packages, istanbul coverage, +`passWithNoTests`, console output only from failing tests), and `testProject("unit" | "integration" | +"e2e" | "live", overrides)` declares one inline project per test kind with the repo's file-suffix +convention baked in. Package-specific settings such as timeouts, setup files, serial execution, or +Vite plugins go in the overrides. The root `vitest.config.mts` loads every package config as a nested +project group, so `bun --bun vitest run --project '*(unit)'` from the repo root runs one kind across +all workspaces while `pnpm test:unit` inside a package still works standalone. + ## Config Naming Vocabulary `@supabase/config` and its CLI consumer use three settled names: diff --git a/apps/cli-e2e/vitest.config.ts b/apps/cli-e2e/vitest.config.ts index bb87f884aa..337992723e 100644 --- a/apps/cli-e2e/vitest.config.ts +++ b/apps/cli-e2e/vitest.config.ts @@ -1,16 +1,12 @@ -import { defineConfig } from "vitest/config"; import { BaseSequencer, type TestSpecification } from "vitest/node"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; -export default defineConfig({ +export default definePackageConfig({ test: { - passWithNoTests: true, - include: ["**/*.e2e.test.ts"], - exclude: ["**/node_modules/**"], - fileParallelism: false, - maxWorkers: 1, - globalSetup: ["tests/setup.ts"], - testTimeout: 60_000, - hookTimeout: 30_000, + // Replay fixtures are shared across files, so run them in a deterministic + // lexicographic order. `sequence.sequencer` is a run-level option: it + // applies to standalone runs of this package, not when the repo root loads + // this config as a project. sequence: { sequencer: class extends BaseSequencer { override async sort(files: TestSpecification[]) { @@ -18,5 +14,16 @@ export default defineConfig({ } }, }, + projects: [ + testProject("e2e", { + test: { + fileParallelism: false, + maxWorkers: 1, + globalSetup: ["tests/setup.ts"], + testTimeout: 60_000, + hookTimeout: 30_000, + }, + }), + ], }, }); diff --git a/apps/cli/vitest.config.ts b/apps/cli/vitest.config.ts index 4c75c1eef2..7dfc698bcd 100644 --- a/apps/cli/vitest.config.ts +++ b/apps/cli/vitest.config.ts @@ -1,7 +1,8 @@ import { readFileSync } from "node:fs"; -import { defaultClientConditions, defaultServerConditions } from "vite"; -import { defineConfig } from "vitest/config"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; +// `src/shared/services/dockerfile-images.ts` imports the Go CLI's Dockerfile +// with Bun's `{ type: "text" }` import attribute; Vite needs a loader for it. function dockerfileTextPlugin() { return { name: "dockerfile-text-loader", @@ -16,31 +17,10 @@ function dockerfileTextPlugin() { }; } -// Workspace packages such as @supabase/config publish a `bun` export -// condition pointing at their TypeScript source (see -// packages/config/package.json's `exports` map); without it, Vite's resolver -// falls through to the `default` condition and loads the built `dist/*.js` -// output instead — which is stale, or missing entirely on a fresh clone -// before the package has been built. Extending (not replacing) Vite's -// default condition lists keeps every other package's exports resolution -// unchanged. Required on every inline `test.projects` entry below too: -// Vitest builds a separate Vite config per project and does not inherit -// these from the root config (see PR #6366 finding 0). -const workspacePackageResolve = { conditions: [...defaultClientConditions, "bun"] }; -const workspacePackageSsrResolve = { conditions: [...defaultServerConditions, "bun"] }; - -export default defineConfig({ - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, +export default definePackageConfig({ plugins: [dockerfileTextPlugin()], test: { - passWithNoTests: true, coverage: { - enabled: false, - provider: "istanbul", - include: ["src/**/*.ts"], - reporter: ["text", "lcov"], - reportsDirectory: "coverage", exclude: [ "tests/**", "scripts/**", @@ -56,29 +36,10 @@ export default defineConfig({ ], }, projects: [ - { - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, - test: { - name: "unit", - include: ["**/*.unit.test.ts"], - env: { FORCE_COLOR: "1" }, - }, - }, - { - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, - test: { - name: "integration", - include: ["**/*.integration.test.ts"], - }, - }, - { - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, + testProject("unit", { test: { env: { FORCE_COLOR: "1" } } }), + testProject("integration"), + testProject("e2e", { test: { - name: "e2e", - include: ["**/*.e2e.test.ts"], fileParallelism: false, maxWorkers: 1, globalSetup: ["tests/e2e-global-setup.ts"], @@ -86,23 +47,19 @@ export default defineConfig({ testTimeout: 120_000, hookTimeout: 120_000, }, - }, - { - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, + }), + // Live tests run against one provisioned project on the configured + // platform. They are never part of the default unit/integration/e2e + // loop; an explicit run fails fast when required configuration is absent. + testProject("live", { test: { - // Live tests run against one provisioned project on the configured - // platform. They are never part of the default unit/integration/e2e - // loop; an explicit run fails fast when required configuration is absent. - name: "live", - include: ["**/*.live.test.ts"], fileParallelism: false, maxWorkers: 1, globalSetup: ["tests/live-global-setup.ts"], testTimeout: 300_000, hookTimeout: 300_000, }, - }, + }), ], }, }); diff --git a/knip.json b/knip.json index 43305fb407..d96b3fffcc 100644 --- a/knip.json +++ b/knip.json @@ -3,10 +3,11 @@ "exclude": ["catalogReferences"], "workspaces": { ".": { - "entry": [".github/scripts/**/*.ts", "tools/*.ts", "tools/release/*.ts"], + "entry": [".github/scripts/**/*.ts", "tools/*.ts", "tools/release/*.ts", "vitest.config.mts"], "ignore": [".repos/**", "apps/cli-go/**"], "ignoreBinaries": ["go"], - "ignoreDependencies": ["verdaccio"] + "ignoreDependencies": ["verdaccio"], + "vitest": false }, "apps/cli": { "entry": [ diff --git a/package.json b/package.json index b112a01c81..d8d412777d 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "turbo": "catalog:", "typescript": "catalog:", "verdaccio": "^6.10.0", + "vite": "catalog:", "vitest": "catalog:" }, "devEngines": { diff --git a/packages/api/vitest.config.ts b/packages/api/vitest.config.ts index 7a35ffa8d7..62fffebcfa 100644 --- a/packages/api/vitest.config.ts +++ b/packages/api/vitest.config.ts @@ -1,23 +1,5 @@ -import { defineConfig } from "vitest/config"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; -export default defineConfig({ - test: { - passWithNoTests: true, - coverage: { - enabled: false, - provider: "istanbul", - clean: false, - include: ["src/**/*.ts"], - reporter: ["text", "lcov"], - reportsDirectory: "coverage", - }, - projects: [ - { - test: { - name: "unit", - include: ["**/*.unit.test.ts"], - }, - }, - ], - }, +export default definePackageConfig({ + test: { projects: [testProject("unit")] }, }); diff --git a/packages/cli-test-helpers/vitest.config.ts b/packages/cli-test-helpers/vitest.config.ts index 7a35ffa8d7..62fffebcfa 100644 --- a/packages/cli-test-helpers/vitest.config.ts +++ b/packages/cli-test-helpers/vitest.config.ts @@ -1,23 +1,5 @@ -import { defineConfig } from "vitest/config"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; -export default defineConfig({ - test: { - passWithNoTests: true, - coverage: { - enabled: false, - provider: "istanbul", - clean: false, - include: ["src/**/*.ts"], - reporter: ["text", "lcov"], - reportsDirectory: "coverage", - }, - projects: [ - { - test: { - name: "unit", - include: ["**/*.unit.test.ts"], - }, - }, - ], - }, +export default definePackageConfig({ + test: { projects: [testProject("unit")] }, }); diff --git a/packages/config/vitest.config.ts b/packages/config/vitest.config.ts index 6c2cb8409a..62fffebcfa 100644 --- a/packages/config/vitest.config.ts +++ b/packages/config/vitest.config.ts @@ -1,40 +1,5 @@ -import { defaultClientConditions, defaultServerConditions } from "vite"; -import { defineConfig } from "vitest/config"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; -// This package publishes a `bun` export condition pointing at its -// TypeScript source (see package.json's `exports` map); without it, Vite's -// resolver falls through to the `default` condition and loads the built -// `dist/*.js` output instead — stale, or missing entirely on a fresh clone -// before the package has been built. Extending (not replacing) Vite's -// default condition lists keeps every other package's exports resolution -// unchanged. Required on every inline `test.projects` entry too: Vitest -// builds a separate Vite config per project and does not inherit these from -// the root config (see PR #6366 finding 0). -const workspacePackageResolve = { conditions: [...defaultClientConditions, "bun"] }; -const workspacePackageSsrResolve = { conditions: [...defaultServerConditions, "bun"] }; - -export default defineConfig({ - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, - test: { - passWithNoTests: true, - coverage: { - enabled: false, - provider: "istanbul", - clean: false, - include: ["src/**/*.ts"], - reporter: ["text", "lcov"], - reportsDirectory: "coverage", - }, - projects: [ - { - resolve: workspacePackageResolve, - ssr: { resolve: workspacePackageSsrResolve }, - test: { - name: "unit", - include: ["**/*.unit.test.ts"], - }, - }, - ], - }, +export default definePackageConfig({ + test: { projects: [testProject("unit")] }, }); diff --git a/packages/process-compose/vitest.config.ts b/packages/process-compose/vitest.config.ts index e10a870951..aefedecbd3 100644 --- a/packages/process-compose/vitest.config.ts +++ b/packages/process-compose/vitest.config.ts @@ -1,29 +1,5 @@ -import { defineConfig } from "vitest/config"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; -export default defineConfig({ - test: { - passWithNoTests: true, - coverage: { - enabled: false, - provider: "istanbul", - clean: false, - include: ["src/**/*.ts"], - reporter: ["text", "lcov"], - reportsDirectory: "coverage", - }, - projects: [ - { - test: { - name: "unit", - include: ["**/*.unit.test.ts"], - }, - }, - { - test: { - name: "integration", - include: ["**/*.integration.test.ts"], - }, - }, - ], - }, +export default definePackageConfig({ + test: { projects: [testProject("unit"), testProject("integration")] }, }); diff --git a/packages/stack/vitest.config.ts b/packages/stack/vitest.config.ts index 3464a66cd4..8b55523c8b 100644 --- a/packages/stack/vitest.config.ts +++ b/packages/stack/vitest.config.ts @@ -1,38 +1,13 @@ -import { defineConfig } from "vitest/config"; +import { definePackageConfig, testProject } from "../../vitest.shared.ts"; -export default defineConfig({ +export default definePackageConfig({ test: { - passWithNoTests: true, - coverage: { - enabled: false, - provider: "istanbul", - clean: false, - include: ["src/**/*.ts"], - reporter: ["text", "lcov"], - reportsDirectory: "coverage", - }, projects: [ - { - test: { - name: "unit", - include: ["**/*.unit.test.ts"], - }, - }, - { - test: { - name: "integration", - include: ["**/*.integration.test.ts"], - testTimeout: 60_000, - }, - }, - { - test: { - name: "e2e", - include: ["**/*.e2e.test.ts"], - fileParallelism: false, - globalSetup: ["./tests/global-setup.ts"], - }, - }, + testProject("unit"), + testProject("integration", { test: { testTimeout: 60_000 } }), + testProject("e2e", { + test: { fileParallelism: false, globalSetup: ["./tests/global-setup.ts"] }, + }), ], }, }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9e83aaef8..3989b58042 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,8 +132,8 @@ catalogs: specifier: ^1.4.0 version: 1.4.0 '@vitest/coverage-istanbul': - specifier: ^4.1.11 - version: 4.1.11 + specifier: ^5.0.0 + version: 5.0.0 effect: specifier: 4.0.0-rc.112 version: 4.0.0-rc.112 @@ -161,6 +161,9 @@ catalogs: typescript: specifier: ^7.0.2 version: 7.0.2 + vite: + specifier: ^8.2.2 + version: 8.2.2 vitest: specifier: ^5.0.0 version: 5.0.0 @@ -210,9 +213,12 @@ importers: verdaccio: specifier: ^6.10.0 version: 6.10.0(supports-color@7.2.0)(typanion@3.14.0) + vite: + specifier: 'catalog:' + version: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0) vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) apps/cli: dependencies: @@ -315,7 +321,7 @@ importers: version: 1.2.5 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) dotenv: specifier: ^17.4.2 version: 17.4.2 @@ -366,7 +372,7 @@ importers: version: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0) vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) yaml: specifier: ^2.9.0 version: 2.9.0 @@ -410,13 +416,13 @@ importers: version: 1.4.0 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) typescript: specifier: 'catalog:' version: 7.0.2 vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) apps/cli-go: {} @@ -480,13 +486,13 @@ importers: version: 1.4.0 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) typescript: specifier: 'catalog:' version: 7.0.2 vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) packages/cli-darwin-arm64: {} @@ -510,13 +516,13 @@ importers: version: 1.4.0 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) typescript: specifier: 'catalog:' version: 7.0.2 vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) packages/cli-windows-arm64: {} @@ -554,7 +560,7 @@ importers: version: 1.4.0 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) effect: specifier: 'catalog:' version: 4.0.0-rc.112 @@ -569,7 +575,7 @@ importers: version: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0) vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) packages/process-compose: dependencies: @@ -591,13 +597,13 @@ importers: version: 1.4.0 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) typescript: specifier: 'catalog:' version: 7.0.2 vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) packages/stack: dependencies: @@ -628,13 +634,13 @@ importers: version: 1.4.0 '@vitest/coverage-istanbul': specifier: 'catalog:' - version: 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + version: 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) typescript: specifier: 'catalog:' version: 7.0.2 vitest: specifier: 'catalog:' - version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + version: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) packages: @@ -719,26 +725,50 @@ packages: resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} + '@babel/code-frame@8.0.0': + resolution: {integrity: sha512-dYYg153EyN2Ekbqw2zAsbd6/JR+9N2SEoC7YV2GyyqMM7x9bLDTjBD6XBhSMLH0wtIVyJj03jWNriQhaN+eoCw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/compat-data@7.29.7': resolution: {integrity: sha512-locTkQyKvwIEgBzVrn8693ebc97F2U8ZHjbXwDXJ5Fn2TCpNwTlKcaKLkdHop5c/icOFE7qt7Q9JC5hnKNa6Gg==} engines: {node: '>=6.9.0'} + '@babel/compat-data@8.0.0': + resolution: {integrity: sha512-DOjnob/cXOUgDOozCDeq/aK2p5y8dUIVdf6tNhEV1HQRd6I8aQ4f4fbtHRVEvb6lP3BGomrKHiS8ICAASSVQSw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/core@7.29.7': resolution: {integrity: sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==} engines: {node: '>=6.9.0'} + '@babel/core@8.0.1': + resolution: {integrity: sha512-5FgxM4dLQpMJHSiVATk8foW263dVHQHBVpXYiimNECVWG01f4nFyEbQixeT6Mwvg7TayREJ2gpKl3o2RoMdnqw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/generator@7.29.8': resolution: {integrity: sha512-gZbepsdh3WDtgZKWL+vTPh71LSBrm/Y4/QDZBVCcYfmeTEEuoOYwlSy+G1StfJg+/Zy550u/3TATbm7qDbbMtg==} engines: {node: '>=6.9.0'} + '@babel/generator@8.0.0': + resolution: {integrity: sha512-NT9NrVwJsbSV6Y2FSstWa71EETOnzrjkL5/wX3D2mYHtKM+qvqB1DvR4D0Setb/gDBsHzRICifwEWMO8CnTF6g==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-compilation-targets@7.29.7': resolution: {integrity: sha512-wem6WaBj4NaVYVdNhLPPVacES6ZJ+KBBfSkTMD3YZxbP3rm3Di85tJU5ljaUNhaOynt+Aj0xruhYuzQBt8n71g==} engines: {node: '>=6.9.0'} + '@babel/helper-compilation-targets@8.0.0': + resolution: {integrity: sha512-JwculLABZvyPvyLBpwU/E/IbH2uM3mnxNtIJpxnIfb24y1PrdVxK5Dqjle4DpgqpGRnwgC7G8IkzPdSXZrO1Ew==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-globals@7.29.7': resolution: {integrity: sha512-3nQVUAtvkKH9zahfWgw96Jc/uFOmjACE1kQz82E2lqWmHBgjzbNlsC22nuQTfahmWeQtTq5nQ/4Nnd2A1wj4zA==} engines: {node: '>=6.9.0'} + '@babel/helper-globals@8.0.0': + resolution: {integrity: sha512-lLozHOM6sWWlxNo8CYqHy4MBZeTvHXNgVPBfPOGsjPKUzHC2Az9QwB6gxdQmpwHl6GlQtbGgS+lj5887guDiLw==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-module-imports@7.29.7': resolution: {integrity: sha512-ejHwrQQYcm9xnTivShn2IDOlIzInN34AXskvq9QicvCtEzq1Vzclu/tKF8Jq1Cg8JG2GL6/EmjgsCT7lXepE3g==} engines: {node: '>=6.9.0'} @@ -753,23 +783,44 @@ packages: resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@8.0.0': + resolution: {integrity: sha512-6mJgmFFFIIO82vvoLt9XtRC7/TkzXfts1t/SpRX4IHSzMgqoPYCWesVu1udUPUWioAE/2fcG6WuI8zrkE1gwrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-identifier@7.29.7': resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-identifier@8.0.4': + resolution: {integrity: sha512-4wFaiLd0bVo4cIoTXI3zKI038NIWE/cr3jvBjejOVYVxV/m8Ltav1USiGzG1fmS5J2RhgEOgXNNK46cRPnRsrg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helper-validator-option@7.29.7': resolution: {integrity: sha512-N9ZErrD+yW5geCDtBqnOoxmR8+tNKiGuxKlDpuJxfsqpa2dFcexaziGAE/qoHLiDDreVNMupxGmSoNlyvsA3gw==} engines: {node: '>=6.9.0'} + '@babel/helper-validator-option@8.0.0': + resolution: {integrity: sha512-U4Dybxh4WESWHt5XhBeExi4DrY0/DNK1aHpQbsrQXCUbFHuMweT0TpLEWKvaraV2Y6fS+ZXunsZ8zIuZIgvF2Q==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/helpers@7.29.7': resolution: {integrity: sha512-1k2lAGRMfHTcwuNYcCNUmaUffmQv8KWMfh2iJUUeRlwlwH4FdNG7mfPI10NPfLHJFThE4Tyr4mv7kTNZOiPuBg==} engines: {node: '>=6.9.0'} + '@babel/helpers@8.0.0': + resolution: {integrity: sha512-wfbi91pM3py96oIiJEz7qIpyXDytgr9zQC1HEWwlGNVRAEmItuU/0a41ZUKu1sJGyhhOIpc4t5vk4PYzt8wpsg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/parser@7.29.8': resolution: {integrity: sha512-E8lTAYNB1KW+FH+VGJuZM1ioAx2E6oVlvQFRrf5P8ZZmsiJXYAD9vTFV7yyEURNzgh1dFqMZuO6tUwcARbqFCA==} engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@8.0.4': + resolution: {integrity: sha512-srpptsAkEbbNIC/q8nT7o+m6CQe8CJUTV/t7MYc9NnWlgYVtHOb7JH6SorxMhN0kuRJjVqXbKClG6xSbPtzz+g==} + engines: {node: ^22.18.0 || >=24.11.0} + hasBin: true + '@babel/runtime@7.29.7': resolution: {integrity: sha512-Nq8OhGWiZIZGV6hLHoyAKLLcJihP/xFeBMGJoUrxTX2psI8dCifzLhZISFb+VWS3wFMRDmCGw5R+dOySCqPLhw==} engines: {node: '>=6.9.0'} @@ -778,6 +829,10 @@ packages: resolution: {integrity: sha512-puq+Gf35oI24FeN11LkoUQFqv9uwNeWpxXZi/Ji3rRIoKAzKnxRaZ+Gkj0vKS9ZCiTESfng1N9LyOyXvo+m+Gg==} engines: {node: '>=6.9.0'} + '@babel/template@8.0.0': + resolution: {integrity: sha512-eAD0QW/AlbamBbw0FeGiwasbCVPq5ncW0HNVyLP3B9czqLyh4gvw+5JTSNt6le9+ziAU7mqDZsKTHf3jTb4chQ==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/traverse@7.28.5': resolution: {integrity: sha512-TCCj4t55U90khlYkVV/0TfkJkAkUg3jZFA3Neb7unZT8CPok7iiRfaX0F+WnqWqt7OxhOn0uBKXCw4lbL8W0aQ==} engines: {node: '>=6.9.0'} @@ -786,6 +841,10 @@ packages: resolution: {integrity: sha512-I5z7H3bf/41ktsNVLtpN0wAa336HkqIHQ5BuPLEhTkt1jVSyZpeNKIzTgEWmlxjdg81R0IgUCcaE+Ok3NvrfZg==} engines: {node: '>=6.9.0'} + '@babel/traverse@8.0.4': + resolution: {integrity: sha512-bZnmqzGG8UZneG1lLxBoWIH0G6Gr1D846Yu4/3XnY6FhCndMR49u26nTY08u/dAxWmLWF9vGQOuC+84FfIUoeg==} + engines: {node: ^22.18.0 || >=24.11.0} + '@babel/types@7.28.5': resolution: {integrity: sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==} engines: {node: '>=6.9.0'} @@ -794,6 +853,10 @@ packages: resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} engines: {node: '>=6.9.0'} + '@babel/types@8.0.4': + resolution: {integrity: sha512-eY+Yn3dCqTGmyiq2QRU66lA5FL8lqqqvecHt0fF3uHONIa7ToYsaCiWV8lOKqAs0Rb2SjixiKFROngnulPtt2g==} + engines: {node: ^22.18.0 || >=24.11.0} + '@clack/core@1.4.3': resolution: {integrity: sha512-/kr3UWNtdJfxZtPgDqUOmG2pvwlmcLGheex5yiZKdwbzZJxhV+HMNR9QNmyY5cGwTNV6LrR7Jtp+KjhUAP1qBQ==} engines: {node: '>= 20.12.0'} @@ -2881,12 +2944,18 @@ packages: '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/gensync@1.0.5': + resolution: {integrity: sha512-MbsRCT7mTikHwKZ0X+LVUTLRrZZRLipTuXEO9qOYO+zmjMVk81axyClMROf6uoPD9MRVu46bx8zoR0Ad9q3NAg==} + '@types/hast@3.0.5': resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} '@types/http-cache-semantics@4.2.0': resolution: {integrity: sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==} + '@types/jsesc@2.5.1': + resolution: {integrity: sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw==} + '@types/mdast@4.0.4': resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} @@ -3130,15 +3199,31 @@ packages: resolution: {integrity: sha512-RWS2h1yXeaF7txXD7jK/v1aecMrTCGFGRMDH3qjcvM0FMXYs5rleGo/MooiXHuOGFC4D7xNqt3hERXQweNlf2Q==} engines: {node: '>=22'} - '@vitest/coverage-istanbul@4.1.11': - resolution: {integrity: sha512-pK9LJtOS534bmUwdwLpGD9qL52DeqVWSInrXFMNqrvWLbbAhuIPAlRup3UbsjFOMqCC/p3MmmX7uXV7ZTkcFfQ==} + '@vitest/coverage-istanbul@5.0.0': + resolution: {integrity: sha512-L0Rh+O61F2FV3+Xc3iGqeW5Tp0fs41VXy0hth84UCcMZGqlTjM1n5PUDqdaJD2xmQ/jZY3SJ9k7A2IKpKZRT8A==} peerDependencies: vite: '*' - vitest: 4.1.11 + vitest: 5.0.0 peerDependenciesMeta: vite: optional: true + '@vitest/istanbul-lib-coverage@1.0.0': + resolution: {integrity: sha512-BScRXlnT3d8tN39mDZuZgS6OmczgyLNO55FGka+CO0LO5458m7hBnEvDm/Dc12f07R4ChdDst66YfKtCr2T8mg==} + engines: {node: '>=22'} + + '@vitest/istanbul-lib-instrument@1.0.0': + resolution: {integrity: sha512-tPdDNnVTB8GxjzV48l2UeUAyqBO5SRCANt2lAooYMIgvVlSm74/aCMNtfNixpoj7Yo/NGSkR8ciRJavWA9X9uw==} + engines: {node: '>=22'} + + '@vitest/istanbul-lib-report@1.0.0': + resolution: {integrity: sha512-NYqaFIc2vKd069hB+oRPf2ckkEq/lYg1W+12l4t0M0c3LYrGgMz8Sj7v+fgONanDsZMBqxQySQkChcwN/ajUBw==} + engines: {node: '>=22'} + + '@vitest/istanbul-lib-source-maps@1.0.0': + resolution: {integrity: sha512-jNgYJE6nUgW6aAd1coIeIdaeqy44ZtqKqcO6i7LaXfBM0hmIuFH0D7jeaPN2iq0usgA3XSxC14vFaGLcjTvPBQ==} + engines: {node: '>=22'} + '@vitest/mocker@5.0.0': resolution: {integrity: sha512-66PGTMIiVJP3t4a5yxU9qPtf7MdTBs8jmToMvy+HVflB3Yy13WJZTtPePdvU+wjRV02SKK5doLbSA6o9pwOmiA==} peerDependencies: @@ -3865,6 +3950,10 @@ packages: emojilib@2.4.0: resolution: {integrity: sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==} + empathic@2.0.1: + resolution: {integrity: sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q==} + engines: {node: '>=14'} + encodeurl@2.0.0: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} @@ -4423,9 +4512,6 @@ packages: resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==} engines: {node: ^20.17.0 || >=22.9.0} - html-escaper@2.0.2: - resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} - html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} @@ -4631,18 +4717,6 @@ packages: resolution: {integrity: sha512-7atWPjhGEIX3JEtMrOYd8TKzboYlq+5sNbdl9POiLYOI14G5HZiQbZP0Xj5EZdrufQVXfJlpTV0hys0CuxwxZw==} engines: {node: ^18.17 || >=20.6.1} - istanbul-lib-coverage@3.2.2: - resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} - engines: {node: '>=8'} - - istanbul-lib-report@3.0.1: - resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} - engines: {node: '>=10'} - - istanbul-reports@3.2.0: - resolution: {integrity: sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==} - engines: {node: '>=8'} - java-properties@1.0.2: resolution: {integrity: sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==} engines: {node: '>= 0.6.0'} @@ -4654,6 +4728,9 @@ packages: jose@6.2.10: resolution: {integrity: sha512-iiW7J9qRFlGxvCOIBDBDxFePQSn7ZMAnrYGhrrOo6siO/MIqwfyilLR27pkfDgUk+raLuzADS8A3S/KLBisc0g==} + js-tokens@10.0.0: + resolution: {integrity: sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -4903,10 +4980,6 @@ packages: resolution: {integrity: sha512-ayF7iT+44LXdxJLTrTd3TLQpFDDvPCBxXxbv+pMUSuHA5Q8zyAfwkRP6aHHwNVFBUFWtxAHqwNJxF8vMZLAbVg==} engines: {node: '>=18'} - make-dir@4.0.0: - resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==} - engines: {node: '>=10'} - markdown-extensions@2.0.0: resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==} engines: {node: '>=16'} @@ -6902,7 +6975,15 @@ snapshots: js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/compat-data@7.29.7': {} + '@babel/code-frame@8.0.0': + dependencies: + '@babel/helper-validator-identifier': 8.0.4 + js-tokens: 10.0.0 + + '@babel/compat-data@7.29.7': + optional: true + + '@babel/compat-data@8.0.0': {} '@babel/core@7.29.7(supports-color@7.2.0)': dependencies: @@ -6923,6 +7004,26 @@ snapshots: semver: 6.3.1 transitivePeerDependencies: - supports-color + optional: true + + '@babel/core@8.0.1': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-compilation-targets': 8.0.0 + '@babel/helpers': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/traverse': 8.0.4 + '@babel/types': 8.0.4 + '@types/gensync': 1.0.5 + convert-source-map: 2.0.0 + empathic: 2.0.1 + gensync: 1.0.0-beta.2 + import-meta-resolve: 4.2.0 + json5: 2.2.3 + obug: 2.1.4 + semver: 7.8.5 '@babel/generator@7.29.8': dependencies: @@ -6932,6 +7033,15 @@ snapshots: '@jridgewell/trace-mapping': 0.3.31 jsesc: 3.1.0 + '@babel/generator@8.0.0': + dependencies: + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 + '@jridgewell/gen-mapping': 0.3.13 + '@jridgewell/trace-mapping': 0.3.31 + '@types/jsesc': 2.5.1 + jsesc: 3.1.0 + '@babel/helper-compilation-targets@7.29.7': dependencies: '@babel/compat-data': 7.29.7 @@ -6939,15 +7049,27 @@ snapshots: browserslist: 4.28.8 lru-cache: 5.1.1 semver: 6.3.1 + optional: true + + '@babel/helper-compilation-targets@8.0.0': + dependencies: + '@babel/compat-data': 8.0.0 + '@babel/helper-validator-option': 8.0.0 + browserslist: 4.28.8 + lru-cache: 11.5.2 + semver: 7.8.5 '@babel/helper-globals@7.29.7': {} + '@babel/helper-globals@8.0.0': {} + '@babel/helper-module-imports@7.29.7(supports-color@7.2.0)': dependencies: '@babel/traverse': 7.29.8(supports-color@7.2.0) '@babel/types': 7.29.8 transitivePeerDependencies: - supports-color + optional: true '@babel/helper-module-transforms@7.29.7(@babel/core@7.29.7(supports-color@7.2.0))(supports-color@7.2.0)': dependencies: @@ -6957,22 +7079,40 @@ snapshots: '@babel/traverse': 7.29.8(supports-color@7.2.0) transitivePeerDependencies: - supports-color + optional: true '@babel/helper-string-parser@7.29.7': {} + '@babel/helper-string-parser@8.0.0': {} + '@babel/helper-validator-identifier@7.29.7': {} - '@babel/helper-validator-option@7.29.7': {} + '@babel/helper-validator-identifier@8.0.4': {} + + '@babel/helper-validator-option@7.29.7': + optional: true + + '@babel/helper-validator-option@8.0.0': {} '@babel/helpers@7.29.7': dependencies: '@babel/template': 7.29.7 '@babel/types': 7.29.8 + optional: true + + '@babel/helpers@8.0.0': + dependencies: + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 '@babel/parser@7.29.8': dependencies: '@babel/types': 7.29.8 + '@babel/parser@8.0.4': + dependencies: + '@babel/types': 8.0.4 + '@babel/runtime@7.29.7': {} '@babel/template@7.29.7': @@ -6981,6 +7121,12 @@ snapshots: '@babel/parser': 7.29.8 '@babel/types': 7.29.8 + '@babel/template@8.0.0': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/types': 8.0.4 + '@babel/traverse@7.28.5(supports-color@7.2.0)': dependencies: '@babel/code-frame': 7.29.7 @@ -7004,6 +7150,17 @@ snapshots: debug: 4.4.3(supports-color@7.2.0) transitivePeerDependencies: - supports-color + optional: true + + '@babel/traverse@8.0.4': + dependencies: + '@babel/code-frame': 8.0.0 + '@babel/generator': 8.0.0 + '@babel/helper-globals': 8.0.0 + '@babel/parser': 8.0.4 + '@babel/template': 8.0.0 + '@babel/types': 8.0.4 + obug: 2.1.4 '@babel/types@7.28.5': dependencies: @@ -7015,6 +7172,11 @@ snapshots: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@babel/types@8.0.4': + dependencies: + '@babel/helper-string-parser': 8.0.0 + '@babel/helper-validator-identifier': 8.0.4 + '@clack/core@1.4.3': dependencies: fast-wrap-ansi: 0.2.2 @@ -7133,7 +7295,7 @@ snapshots: '@effect/vitest@4.0.0-rc.112(effect@4.0.0-rc.112)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0)': dependencies: effect: 4.0.0-rc.112 - vitest: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + vitest: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) optionalDependencies: vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0) @@ -7386,6 +7548,7 @@ snapshots: dependencies: '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 + optional: true '@jridgewell/resolve-uri@3.1.2': {} @@ -8688,12 +8851,16 @@ snapshots: '@types/estree@1.0.9': {} + '@types/gensync@1.0.5': {} + '@types/hast@3.0.5': dependencies: '@types/unist': 3.0.3 '@types/http-cache-semantics@4.2.0': {} + '@types/jsesc@2.5.1': {} + '@types/mdast@4.0.4': dependencies: '@types/unist': 3.0.3 @@ -8966,23 +9133,40 @@ snapshots: lodash: 4.18.1 minimatch: 10.2.6 - '@vitest/coverage-istanbul@4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0)': + '@vitest/coverage-istanbul@5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0)': dependencies: - '@babel/core': 7.29.7(supports-color@7.2.0) - '@istanbuljs/schema': 0.1.6 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.31 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-reports: 3.2.0 + '@vitest/istanbul-lib-coverage': 1.0.0 + '@vitest/istanbul-lib-instrument': 1.0.0 + '@vitest/istanbul-lib-report': 1.0.0 + '@vitest/istanbul-lib-source-maps': 1.0.0 magicast: 0.5.4 obug: 2.1.4 tinyrainbow: 3.1.1 - vitest: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) + vitest: 5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) optionalDependencies: vite: 8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0) - transitivePeerDependencies: - - supports-color + + '@vitest/istanbul-lib-coverage@1.0.0': {} + + '@vitest/istanbul-lib-instrument@1.0.0': + dependencies: + '@babel/core': 8.0.1 + '@babel/parser': 8.0.4 + '@istanbuljs/schema': 0.1.6 + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/istanbul-lib-coverage': 1.0.0 + + '@vitest/istanbul-lib-report@1.0.0': + dependencies: + '@vitest/istanbul-lib-coverage': 1.0.0 + + '@vitest/istanbul-lib-source-maps@1.0.0': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + '@vitest/istanbul-lib-coverage': 1.0.0 + obug: 2.1.4 '@vitest/mocker@5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))': dependencies: @@ -9614,6 +9798,8 @@ snapshots: emojilib@2.4.0: {} + empathic@2.0.1: {} + encodeurl@2.0.0: {} end-of-stream@1.4.5: @@ -10353,8 +10539,6 @@ snapshots: dependencies: lru-cache: 11.5.2 - html-escaper@2.0.2: {} - html-void-elements@3.0.0: {} http-cache-semantics@4.2.0: {} @@ -10555,25 +10739,14 @@ snapshots: lodash.isstring: 4.0.1 lodash.uniqby: 4.7.0 - istanbul-lib-coverage@3.2.2: {} - - istanbul-lib-report@3.0.1: - dependencies: - istanbul-lib-coverage: 3.2.2 - make-dir: 4.0.0 - supports-color: 7.2.0 - - istanbul-reports@3.2.0: - dependencies: - html-escaper: 2.0.2 - istanbul-lib-report: 3.0.1 - java-properties@1.0.2: {} jiti@2.7.0: {} jose@6.2.10: {} + js-tokens@10.0.0: {} + js-tokens@4.0.0: {} js-yaml@4.3.1: @@ -10782,6 +10955,7 @@ snapshots: lru-cache@5.1.1: dependencies: yallist: 3.1.1 + optional: true lru-cache@7.18.3: {} @@ -10805,10 +10979,6 @@ snapshots: type-fest: 4.41.0 web-worker: 1.5.0 - make-dir@4.0.0: - dependencies: - semver: 7.8.5 - markdown-extensions@2.0.0: {} markdown-table@3.0.4: {} @@ -12250,7 +12420,8 @@ snapshots: semver-regex@4.0.5: {} - semver@6.3.1: {} + semver@6.3.1: + optional: true semver@7.8.5: {} @@ -12977,7 +13148,7 @@ snapshots: jiti: 2.7.0 yaml: 2.9.0 - vitest@5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@4.1.11)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)): + vitest@5.0.0(@types/node@26.3.0)(@vitest/coverage-istanbul@5.0.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)): dependencies: '@types/chai': 5.2.3 '@vitest/mocker': 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0)) @@ -12995,7 +13166,7 @@ snapshots: why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 26.3.0 - '@vitest/coverage-istanbul': 4.1.11(supports-color@7.2.0)(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) + '@vitest/coverage-istanbul': 5.0.0(vite@8.2.2(@types/node@26.3.0)(esbuild@0.28.2)(jiti@2.7.0)(yaml@2.9.0))(vitest@5.0.0) transitivePeerDependencies: - msw @@ -13054,7 +13225,8 @@ snapshots: y18n@5.0.8: {} - yallist@3.1.1: {} + yallist@3.1.1: + optional: true yaml@2.9.0: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 3d8b846a30..a88ba905af 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -21,7 +21,7 @@ catalog: "@tsconfig/bun": "^1.0.11" "@types/bun": "^1.4.0" "typescript": "^7.0.2" - "@vitest/coverage-istanbul": "^4.1.11" + "@vitest/coverage-istanbul": "^5.0.0" "effect": "4.0.0-rc.112" "knip": "^6.32.2" "oxfmt": "^0.65.0" @@ -30,6 +30,7 @@ catalog: "semantic-release": "^25.0.9" "tldts": "^7.4.11" "turbo": "2.10.12" + "vite": "^8.2.2" "vitest": ^5.0.0 blockExoticSubdeps: true @@ -91,6 +92,15 @@ packageExtensions: "@oxlint-tsgolint/win32-arm64": *effect-tsgo-patched "@oxlint-tsgolint/win32-x64": *effect-tsgo-patched +# @effect/vitest 4.0.0-rc.x declares a `vitest >=4.1.0 <5.0.0` peer, but it only +# uses the stable `vitest` entrypoint and runs cleanly against Vitest 5 (the +# whole unit/integration suite passes). Upstream has not widened the range yet; +# accept Vitest 5 here so every install stops warning about a known-good pair. +# Drop this rule once @effect/vitest ships a vitest@5-compatible peer range. +peerDependencyRules: + allowedVersions: + "@effect/vitest>vitest": "5" + minimumReleaseAge: 10200 minimumReleaseAgeExclude: - "@turbo/darwin-64@2.10.11" @@ -112,6 +122,7 @@ minimumReleaseAgeExclude: - "effect@4.0.0-rc.111" - tinybench@6.1.4 - "turbo@2.10.11" + - "@vitest/coverage-istanbul@5.0.0" - "@vitest/mocker@5.0.0" - "@vitest/spy@5.0.0" - vitest@5.0.0 diff --git a/vitest.config.mts b/vitest.config.mts index 8082eb0351..5e36ef95a6 100644 --- a/vitest.config.mts +++ b/vitest.config.mts @@ -1,8 +1,15 @@ import { defineConfig } from "vitest/config"; +import { runDefaults } from "./vitest.shared.ts"; +// Every package config becomes a nested project group named after the package, +// so `vitest --project 'supabase (unit)'` or `--project '*(integration)'` selects +// slices of the whole repo from one process. Root-only options such as `silent` +// are not inherited by these file-referenced projects; they come from +// `vitest.shared.ts` through each package config for standalone runs and are +// repeated here for root runs. export default defineConfig({ test: { + ...runDefaults, projects: ["apps/*/vitest.config.ts", "packages/*/vitest.config.ts"], - silent: "passed-only", }, }); diff --git a/vitest.shared.ts b/vitest.shared.ts new file mode 100644 index 0000000000..df8120332e --- /dev/null +++ b/vitest.shared.ts @@ -0,0 +1,85 @@ +import { defaultClientConditions, defaultServerConditions } from "vite"; +import { + defineConfig, + mergeConfig, + type TestProjectInlineConfiguration, + type ViteUserConfig, +} from "vitest/config"; + +/** + * Shared Vitest preset for every TypeScript workspace. + * + * Package configs play two roles: `bun --bun vitest` inside a package treats the + * package config as the root, while the repo-root `vitest.config.mts` loads the + * same file as a nested project group. Vitest only inherits options into + * *inline* projects, never into config files referenced by glob, so anything + * shared across packages has to be merged in here rather than declared once at + * the root. + */ + +/** Test kinds and the colocated file suffix each one owns (see CLAUDE.md, "Testing"). */ +const testKinds = { + unit: "**/*.unit.test.ts", + integration: "**/*.integration.test.ts", + e2e: "**/*.e2e.test.ts", + live: "**/*.live.test.ts", +} as const; + +export type TestKind = keyof typeof testKinds; + +/** + * One inline project per test kind. Nested under a package config, Vitest names + * it ` ()`, so `vitest --project '*(unit)'` from the root + * selects that kind across the whole repo. Project-level overrides (timeouts, + * setup files, parallelism) layer on top. + */ +export function testProject( + kind: TestKind, + overrides: TestProjectInlineConfiguration = {}, +): TestProjectInlineConfiguration { + return { + ...overrides, + test: { ...overrides.test, name: kind, include: [testKinds[kind]] }, + }; +} + +/** + * Run-level options that Vitest applies only from the root config of a run. + * Set on the repo-root config and on every package config (for standalone runs). + */ +export const runDefaults = { + passWithNoTests: true, + // Console output from passing tests is noise; failing tests still print theirs. + silent: "passed-only", +} as const; + +const packageDefaults: ViteUserConfig = defineConfig({ + // Workspace packages such as @supabase/config, @supabase/stack, and + // @supabase/api publish a `bun` export condition pointing at their TypeScript + // source. Without it Vite falls through to the `default` condition and loads + // built `dist/*.js` output, which is stale or missing on a fresh clone. + // Extending (not replacing) Vite's default condition lists leaves every other + // package's exports resolution unchanged. Vitest 5 inherits these into the + // inline projects declared below each package config. + resolve: { conditions: [...defaultClientConditions, "bun"] }, + ssr: { resolve: { conditions: [...defaultServerConditions, "bun"] } }, + test: { + ...runDefaults, + // Coverage is a run-level option too, so this only applies to standalone + // package runs (`pnpm test:unit --coverage.enabled`). Each package's + // `test:*:run` script points `reportsDirectory` at a per-kind subdirectory. + coverage: { + enabled: false, + provider: "istanbul", + clean: false, + include: ["src/**/*.ts"], + reporter: ["text", "lcov"], + reportsDirectory: "coverage", + }, + }, +}); + +/** A package's Vitest config: the shared preset with package-specific options merged on top. */ +export function definePackageConfig(config: ViteUserConfig): ViteUserConfig { + return mergeConfig(packageDefaults, config); +}