vitest.config.ts
Rama main · réplica de lectura del repositorio original.
import path from 'node:path'
import { cloudflareTest, readD1Migrations } from '@cloudflare/vitest-pool-workers'
import react from '@vitejs/plugin-react-swc'
import { defineConfig } from 'vitest/config'
process.env.CLOUDFLARE_LOAD_DEV_VARS_FROM_DOT_ENV = 'false'
export default defineConfig({
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
'@enbor/runtime-contracts': path.resolve(__dirname, './packages/runtime-contracts/src'),
'@server': path.resolve(__dirname, './server'),
'@shared': path.resolve(__dirname, './shared'),
},
},
test: {
// Coverage gates the layers the fast suites (unit + web) own; the workerd
// integration pool can't be v8-instrumented, so http full-flow / repos /
// composition / worker / auth-jwks / runtime execution are proven by the
// integration + e2e suites and lint:arch, not a %. Business logic (domain +
// usecases) must be provable here without the stack — gated at 95%.
coverage: {
provider: 'v8',
include: [
'server/domain/**',
'server/usecases/**',
'server/adapters/gateways/**',
'src/features/**',
'src/lib/**',
'packages/runtime-contracts/src/bridge-protocol.ts',
'server/contracts/runner-protocol.ts',
],
// shared/ and runtime-contract session transport files are intentionally NOT
// %-gated here: they are imported by BOTH the node unit suite and the jsdom
// web suite, and v8 instruments them with different function maps per
// environment, so the multi-project merge undercounts functions even when
// their dedicated unit suites cover every exported parser/schema branch.
// They are guarded by shared/session-events.test.ts and
// packages/runtime-contracts/src/*.test.ts in the unit suite.
exclude: [
'**/*.test.ts',
'**/*.test.tsx',
'**/*.d.ts',
'**/index.ts',
'src/lib/utils.ts',
'src/lib/query-keys.ts',
// Relocated runtime DATA-PLANE. The clean-arch fold moved this code out of
// server/runtime/ (which was NEVER in the coverage include) into these
// layer dirs, but its correctness posture is unchanged: the turn loop,
// sandbox host, queue/runner bindings, and the runtime rules are proven by
// the server/integration suite, the session-orchestration golden master,
// and lint:arch layer enforcement — not by v8 %. Keeping them gated here
// would re-coverage-gate code that was deliberately exempt pre-fold; these
// entries restore that posture without weakening coverage on the genuine
// REST business logic in server/domain + server/usecases.
'server/domain/runtime/**',
'server/usecases/runtime/**',
'server/adapters/gateways/cloud-turn-queue.ts',
'server/adapters/gateways/runner-channel.ts',
'server/adapters/gateways/session-do-events.ts',
'server/adapters/gateways/runtime-secret-env.ts',
'server/adapters/gateways/mcp-client.ts',
],
thresholds: {
perFile: true,
statements: 90,
branches: 80,
functions: 90,
lines: 90,
'server/domain/**': { statements: 95, branches: 94.9, functions: 95, lines: 95 },
'server/usecases/**': { statements: 95, branches: 95, functions: 95, lines: 95 },
'packages/runtime-contracts/src/bridge-protocol.ts': {
statements: 100,
branches: 100,
functions: 100,
lines: 100,
},
'server/contracts/runner-protocol.ts': { statements: 100, branches: 100, functions: 100, lines: 100 },
},
reporter: ['text', 'text-summary'],
},
projects: [
{
// unit (node): server business layers + shared + runtime bridge. The
// cheapest suite — pure logic and fake-port use cases, no jsdom, no D1.
extends: true,
test: {
name: 'unit',
environment: 'node',
include: [
'server/domain/**/*.test.ts',
'server/usecases/**/*.test.ts',
'server/adapters/**/*.test.ts',
'server/auth/**/*.test.ts',
'server/worker/**/*.test.ts',
'server/*.test.ts',
'shared/**/*.test.ts',
'packages/runtime-bridge/src/**/*.test.ts',
'packages/runtime-contracts/src/**/*.test.ts',
'server/contracts/**/*.test.ts',
],
},
},
{
// web (jsdom): the React SPA — client logic, hooks, components driven
// through the REAL api client with MSW at the network boundary.
extends: true,
plugins: [react()],
test: {
name: 'web',
environment: 'jsdom',
globals: true,
include: ['src/**/*.test.ts', 'src/**/*.test.tsx'],
setupFiles: ['./src/test/setup.ts'],
},
},
{
// integration (workerd + real D1): the assembled server through app.fetch.
extends: true,
plugins: [
cloudflareTest(async () => {
const migrationsPath = path.join(__dirname, './migrations')
const migrations = await readD1Migrations(migrationsPath)
return {
main: './server/worker.ts',
miniflare: {
compatibilityDate: '2026-05-07',
compatibilityFlags: ['nodejs_compat'],
bindings: {
TEST_MIGRATIONS: migrations,
SANDBOX_TRANSPORT: 'rpc',
RUNTIME_MODE: 'test',
OIDC_ISSUER: 'https://identity.alias.test/api/auth/',
OIDC_CLIENT_ID: 'enbor-test',
OIDC_CLIENT_SECRET: 'test-confidential-client-secret',
OIDC_RUNNER_CLIENT_ID: 'enbor-runner-test',
OIDC_RESOURCE: 'https://enbor.realmroot.dev/api',
E2E_TEST_AUTH: 'true',
ALLOWED_ORIGINS: 'https://example.com',
VAULT_ENCRYPTION_KEY: 'test-vault-encryption-key-for-workers-suite-32-bytes',
WEB_SESSION_ENCRYPTION_KEY: 'test-web-session-encryption-key-for-workers-suite',
},
serviceBindings: {
ASSETS: async () => new Response('Not Found', { status: 404 }),
},
d1Databases: ['DB'],
r2Buckets: ['SESSION_EVENTS'],
ratelimits: {
AUTH_CLIENT_RATE_LIMITER: {
namespace_id: '89007',
simple: { limit: 10, period: 60 },
},
AUTH_IP_RATE_LIMITER: {
namespace_id: '89008',
simple: { limit: 100, period: 60 },
},
},
durableObjects: {
SANDBOX: { className: 'Sandbox', useSQLite: true },
SESSION: { className: 'SessionObject', useSQLite: true },
RUNNER_POOL: { className: 'RunnerPoolObject', useSQLite: true },
},
},
}
}),
],
test: {
name: 'integration',
include: ['server/integration/**/*.test.ts'],
setupFiles: ['./server/integration/apply-migrations.ts'],
},
},
],
},
})