mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-19 05:26:47 +00:00
14b348581a
Every plugin now runs in its own forked child process with a scrubbed env (no JWT_SECRET, no db path, nothing inherited). It talks to TREK only over a JSON-RPC channel, and the host's capability router registers ONLY the methods a plugin's granted permissions unlock — so an ungranted call is unreachable, not merely refused. The plugin's own data lives in a separate sqlite file it can never open directly; core reads (trips/users) go through membership-checked, column-projected host methods; ws broadcasts are force-namespaced. - protocol/envelope: the wire types + method→permission map (pure, shared by host and the isolated child) - host/rpc-host: the capability router = the enforcement point (dispatch, BAD_PARAMS / PERMISSION_DENIED / RESOURCE_FORBIDDEN / UNKNOWN_METHOD) - host/plugin-data: the per-plugin sqlite file (db:own), guarded against ATTACH/PRAGMA escape, idempotent migrations - host/create-rpc-host: wires the router to the real db/websocket (host-only) - runtime/plugin-sdk + plugin-host-entry: the child bootstrap + definePlugin ctx; turns each ctx call into an RPC, never imports a privileged module - supervisor: spawn on activate, heartbeat/reap, crash backoff + auto-disable, graceful shutdown — a plugin crash/OOM/hang can never reach the Nest loop - paths: code/data layout, dist-vs-tsx child entry resolution Nothing is wired into activation yet (that's the next slice); exercised by unit tests for the router/sdk/data and an integration test that forks a real child.
71 lines
2.8 KiB
TypeScript
71 lines
2.8 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'],
|
|
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',
|
|
reporter: ['lcov', 'text'],
|
|
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. Raised to the DoD's >=80% bar once the first
|
|
// module (weather) landed; ratchet further as more modules are migrated.
|
|
thresholds: {
|
|
'src/nest/**/*.ts': { statements: 80, branches: 80, functions: 80, lines: 80 },
|
|
},
|
|
},
|
|
},
|
|
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,
|
|
},
|
|
},
|
|
}); |