mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
77dddd5e8a
Release branch for 4.0.0.
178 lines
12 KiB
TypeScript
178 lines
12 KiB
TypeScript
import { defineConfig } from 'vitest/config';
|
|
import swc from 'unplugin-swc';
|
|
|
|
export default defineConfig({
|
|
// SWC transform so NestJS decorator metadata is emitted in tests
|
|
// (vitest's default esbuild does not emit it -> type-based DI would break).
|
|
plugins: [
|
|
swc.vite({
|
|
jsc: {
|
|
parser: { syntax: 'typescript', decorators: true },
|
|
transform: { legacyDecorator: true, decoratorMetadata: true },
|
|
keepClassNames: true,
|
|
},
|
|
}),
|
|
],
|
|
test: {
|
|
root: '.',
|
|
include: ['tests/**/*.test.ts'],
|
|
globals: true,
|
|
setupFiles: ['tests/setup.ts', 'tests/setup.console-noise.ts'],
|
|
testTimeout: 15000,
|
|
hookTimeout: 15000,
|
|
pool: 'forks',
|
|
silent: false,
|
|
reporters: ['verbose'],
|
|
coverage: {
|
|
// Vite 8 + Vitest 4 made the sourcemap-based `v8` provider under-report branch
|
|
// coverage on the SWC/decorator-transformed output (it dropped to ~68% even
|
|
// though every test passes). `istanbul` instruments the source directly, so
|
|
// coverage is measured independently of the transform pipeline.
|
|
provider: 'istanbul',
|
|
// json-summary is what the per-domain ratchet below is derived from: the text
|
|
// reporter prints one row per DIRECTORY, not a recursive total, so reading the
|
|
// thresholds off it silently understates any domain with subdirectories.
|
|
reporter: ['lcov', 'text', 'json-summary'],
|
|
reportsDirectory: './coverage',
|
|
include: ['src/**/*.ts'],
|
|
// The plugin child bootstrap runs in a forked subprocess via tsx, so the
|
|
// parent's instrumentation can't measure it; it's exercised end-to-end by
|
|
// the supervisor integration test instead. Everything else in the plugin
|
|
// module runs in-process and is unit-tested.
|
|
exclude: ['src/nest/plugins/runtime/plugin-host-entry.ts'],
|
|
// Coverage gate scoped to the new NestJS code only — the legacy codebase is
|
|
// intentionally ungated.
|
|
//
|
|
// The bar is PER DOMAIN and works as a ratchet: each entry is that domain's
|
|
// measured coverage at the time it was set, minus one point of slack. Regenerate
|
|
// with `node scripts/coverage-thresholds.mjs` after a run that RAISED coverage. A single
|
|
// repo-wide 80% let a well-covered domain subsidise a thin one, so a domain could
|
|
// lose ten points and the build stayed green. Now it cannot: the only way past a
|
|
// number here is to raise it, which makes the ratchet visible in the diff.
|
|
//
|
|
// Raise an entry when you improve a domain. Never lower one to make a build pass —
|
|
// that is the whole point of the mechanism.
|
|
//
|
|
// Regenerate from a LINUX run if you can: CI runs on Linux, and a few branches are
|
|
// platform-specific (the drive-letter half of the backup zip-slip guard is only
|
|
// reachable on win32). Numbers taken on Windows can therefore sit a hair above what
|
|
// CI measures, which shows up as a threshold failure that reproduces nowhere local.
|
|
//
|
|
// A file matched by a glob below is EXCLUDED from the catch-all, so the last entry
|
|
// only covers what sits directly under src/nest (app.module.ts and the like).
|
|
thresholds: {
|
|
'src/nest/accommodations/**/*.ts': { statements: 92, branches: 87, functions: 99, lines: 97 },
|
|
'src/nest/addons/**/*.ts': { statements: 99, branches: 89, functions: 99, lines: 99 },
|
|
'src/nest/admin/**/*.ts': { statements: 86, branches: 70, functions: 89, lines: 88 },
|
|
'src/nest/airports/**/*.ts': { statements: 68, branches: 60, functions: 93, lines: 73 },
|
|
'src/nest/app-config/**/*.ts': { statements: 79, branches: 100, functions: 65, lines: 71 },
|
|
'src/nest/assignments/**/*.ts': { statements: 90, branches: 80, functions: 97, lines: 96 },
|
|
'src/nest/atlas/**/*.ts': { statements: 92, branches: 82, functions: 96, lines: 94 },
|
|
'src/nest/audit/**/*.ts': { statements: 93, branches: 80, functions: 99, lines: 96 },
|
|
'src/nest/auth/**/*.ts': { statements: 93, branches: 85, functions: 95, lines: 96 },
|
|
'src/nest/backup/**/*.ts': { statements: 97, branches: 93, functions: 99, lines: 98 },
|
|
'src/nest/booking-import/**/*.ts': { statements: 50, branches: 28, functions: 64, lines: 53 },
|
|
'src/nest/budget/**/*.ts': { statements: 91, branches: 77, functions: 97, lines: 95 },
|
|
'src/nest/calendar/**/*.ts': { statements: 96, branches: 93, functions: 99, lines: 99 },
|
|
'src/nest/categories/**/*.ts': { statements: 99, branches: 80, functions: 99, lines: 99 },
|
|
'src/nest/collab/**/*.ts': { statements: 92, branches: 85, functions: 95, lines: 97 },
|
|
'src/nest/collections/**/*.ts': { statements: 86, branches: 75, functions: 95, lines: 95 },
|
|
'src/nest/common/**/*.ts': { statements: 95, branches: 89, functions: 99, lines: 97 },
|
|
'src/nest/config/**/*.ts': { statements: 99, branches: 100, functions: 99, lines: 99 },
|
|
'src/nest/database/**/*.ts': { statements: 99, branches: 100, functions: 99, lines: 99 },
|
|
'src/nest/day-notes/**/*.ts': { statements: 92, branches: 83, functions: 99, lines: 99 },
|
|
'src/nest/days/**/*.ts': { statements: 92, branches: 82, functions: 98, lines: 97 },
|
|
'src/nest/feeds/**/*.ts': { statements: 91, branches: 83, functions: 83, lines: 91 },
|
|
'src/nest/files/**/*.ts': { statements: 97, branches: 95, functions: 99, lines: 98 },
|
|
'src/nest/geo/**/*.ts': { statements: 99, branches: 95, functions: 99, lines: 99 },
|
|
'src/nest/health/**/*.ts': { statements: 99, branches: 65, functions: 99, lines: 99 },
|
|
'src/nest/help/**/*.ts': { statements: 81, branches: 70, functions: 99, lines: 86 },
|
|
'src/nest/integrations/**/*.ts': { statements: 72, branches: 56, functions: 76, lines: 74 },
|
|
'src/nest/journey/**/*.ts': { statements: 91, branches: 84, functions: 88, lines: 93 },
|
|
'src/nest/llm-parse/**/*.ts': { statements: 91, branches: 85, functions: 85, lines: 94 },
|
|
'src/nest/maps/**/*.ts': { statements: 93, branches: 86, functions: 97, lines: 96 },
|
|
'src/nest/memories/**/*.ts': { statements: 92, branches: 83, functions: 97, lines: 94 },
|
|
'src/nest/notifications/**/*.ts': { statements: 83, branches: 72, functions: 85, lines: 87 },
|
|
'src/nest/oauth/**/*.ts': { statements: 96, branches: 95, functions: 97, lines: 97 },
|
|
'src/nest/oidc/**/*.ts': { statements: 88, branches: 83, functions: 91, lines: 92 },
|
|
'src/nest/packing/**/*.ts': { statements: 92, branches: 83, functions: 99, lines: 97 },
|
|
'src/nest/permissions/**/*.ts': { statements: 97, branches: 92, functions: 99, lines: 97 },
|
|
'src/nest/photos/**/*.ts': { statements: 96, branches: 92, functions: 92, lines: 96 },
|
|
// Landed on dev without an entry, so it sat on the 80 catch-all while
|
|
// measuring 99.5/99.0/97.4/100 — the gap the per-domain ratchet exists to
|
|
// close. Set with a few points of slack against the Linux/Windows drift.
|
|
'src/nest/place-enrichment/**/*.ts': { statements: 96, branches: 95, functions: 94, lines: 97 },
|
|
'src/nest/place-photos/**/*.ts': { statements: 87, branches: 79, functions: 72, lines: 89 },
|
|
'src/nest/places/**/*.ts': { statements: 91, branches: 82, functions: 96, lines: 94 },
|
|
'src/nest/platform/**/*.ts': { statements: 99, branches: 99, functions: 99, lines: 99 },
|
|
'src/nest/plugins/**/*.ts': { statements: 86, branches: 81, functions: 78, lines: 89 },
|
|
'src/nest/query-helpers/**/*.ts': { statements: 90, branches: 75, functions: 99, lines: 92 },
|
|
'src/nest/realtime/**/*.ts': { statements: 99, branches: 100, functions: 99, lines: 99 },
|
|
'src/nest/reservation-import/**/*.ts': { statements: 61, branches: 55, functions: 41, lines: 61 },
|
|
'src/nest/reservations/**/*.ts': { statements: 92, branches: 83, functions: 96, lines: 96 },
|
|
'src/nest/settings/**/*.ts': { statements: 87, branches: 71, functions: 99, lines: 88 },
|
|
'src/nest/share/**/*.ts': { statements: 97, branches: 87, functions: 99, lines: 99 },
|
|
'src/nest/storage/**/*.ts': { statements: 94, branches: 84, functions: 97, lines: 94 },
|
|
'src/nest/system-notices/**/*.ts': { statements: 99, branches: 99, functions: 99, lines: 99 },
|
|
'src/nest/tags/**/*.ts': { statements: 97, branches: 89, functions: 99, lines: 99 },
|
|
'src/nest/todo/**/*.ts': { statements: 90, branches: 82, functions: 99, lines: 99 },
|
|
'src/nest/transit/**/*.ts': { statements: 92, branches: 83, functions: 97, lines: 94 },
|
|
'src/nest/trip-invite/**/*.ts': { statements: 91, branches: 93, functions: 93, lines: 89 },
|
|
'src/nest/trip-membership/**/*.ts': { statements: 99, branches: 86, functions: 99, lines: 99 },
|
|
'src/nest/trip-members/**/*.ts': { statements: 95, branches: 91, functions: 99, lines: 95 },
|
|
'src/nest/trip-read-model/**/*.ts': { statements: 97, branches: 96, functions: 99, lines: 97 },
|
|
'src/nest/trips/**/*.ts': { statements: 95, branches: 86, functions: 95, lines: 96 },
|
|
'src/nest/unsplash/**/*.ts': { statements: 99, branches: 88, functions: 99, lines: 99 },
|
|
'src/nest/vacay/**/*.ts': { statements: 82, branches: 66, functions: 90, lines: 86 },
|
|
'src/nest/weather/**/*.ts': { statements: 93, branches: 78, functions: 91, lines: 97 },
|
|
'src/nest/**/*.ts': { statements: 80, branches: 80, functions: 80, lines: 80 },
|
|
|
|
// Outside the container. Coverage MEASURES src/**, but until now only
|
|
// src/nest/** was gated, so the boot path, the scheduler, the MCP
|
|
// handler and the migrations sat under no floor at all — which is
|
|
// exactly where the worst finding of the last audit lived (a swallowed
|
|
// EADDRINUSE that no test could have caught). These entries pin what is
|
|
// measured today so it cannot slide; they are floors to raise, not
|
|
// targets that have been met.
|
|
//
|
|
// src/demo/** is deliberately absent: it measures 0%, and a floor of
|
|
// zero asserts nothing. It needs tests before it needs a threshold.
|
|
'src/app-config/**/*.ts': { statements: 99, branches: 95, functions: 99, lines: 99 },
|
|
'src/db/**/*.ts': { statements: 73, branches: 38, functions: 59, lines: 80 },
|
|
'src/mcp/**/*.ts': { statements: 58, branches: 43, functions: 63, lines: 60 },
|
|
'src/middleware/**/*.ts': { statements: 91, branches: 89, functions: 87, lines: 94 },
|
|
// The folded-in nest-mcp decorator/registry layer keeps the 80% floor
|
|
// its own workspace gate enforced (tests/unit/nest-mcp/).
|
|
'src/nest-mcp/**/*.ts': { statements: 80, branches: 80, functions: 80, lines: 80 },
|
|
'src/systemNotices/**/*.ts': { statements: 84, branches: 67, functions: 93, lines: 85 },
|
|
'src/utils/**/*.ts': { statements: 92, branches: 87, functions: 89, lines: 96 },
|
|
// index.ts, bootstrap.ts, scheduler.ts, config.ts, websocket.ts and the
|
|
// small top-level modules beside them.
|
|
'src/*.ts': { statements: 39, branches: 36, functions: 36, lines: 42 },
|
|
},
|
|
},
|
|
},
|
|
resolve: {
|
|
alias: {
|
|
// MCP SDK's exports map uses extension-less wildcard targets that neither
|
|
// Node nor Vite can resolve. Point directly at the CJS dist files.
|
|
// Paths are relative to the monorepo root (packages are hoisted there).
|
|
'@modelcontextprotocol/sdk/server/mcp': new URL(
|
|
'../node_modules/@modelcontextprotocol/sdk/dist/cjs/server/mcp.js',
|
|
import.meta.url
|
|
).pathname,
|
|
'@modelcontextprotocol/sdk/server/streamableHttp': new URL(
|
|
'../node_modules/@modelcontextprotocol/sdk/dist/cjs/server/streamableHttp.js',
|
|
import.meta.url
|
|
).pathname,
|
|
'@modelcontextprotocol/sdk/inMemory': new URL(
|
|
'../node_modules/@modelcontextprotocol/sdk/dist/cjs/inMemory.js',
|
|
import.meta.url
|
|
).pathname,
|
|
'@modelcontextprotocol/sdk/client/index': new URL(
|
|
'../node_modules/@modelcontextprotocol/sdk/dist/cjs/client/index.js',
|
|
import.meta.url
|
|
).pathname,
|
|
},
|
|
},
|
|
}); |