mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
ba7d55f999
BODY_CONTRACT_ALLOW_LIST is empty. The last seventeen handlers type their
body with a createZodDto class, so the fail-closed boot gate has nothing left
to forgive; it still refuses a boot for a new handler that reads @Body()
without one.
Several of those contracts describe rather than constrain, and that is the
whole care in this change. The pipe runs before the handler, so a schema
stricter than the handler moves a user-visible answer:
- TagsController.create answers { error: 'Tag name is required' }, pinned
byte-for-byte in two tests, and the pipe formats as `field: message`. The
DTO leaves name optional and the handler keeps the check that owns the
message. Same shape for the booking-import confirm body, which additionally
gains per-item validation the handler never did.
- PluginsController.activate and install answer 503 when plugins are disabled,
and check that BEFORE looking at the body. A schema that rejected first
would turn that into a 400 for an operator whose server has plugins off.
- setEgressHosts reads a non-array `hosts` as "clear the list", which is the
documented reset. Typing it as string[] would have removed a working admin
action rather than tightened anything.
- PluginRoutesController.route answers { route: null } at 200 for everything
it dislikes, so the client falls back to straight lines. A 400 there would
turn a graceful degradation into a visible error.
files.bridge is gone. The multer options are built by
MulterModule.registerAsync from an AllowedFileTypesService leaf, so the
fileFilter reads the operator's extension list from the container instead of
from a second FilesService built outside it. Nest injects
MULTER_MODULE_OPTIONS with @Optional(), so a token that fails to resolve is
not a boot error: it silently falls back to defaults, with no filter and no
size cap. FILE-020 already proved that for trip files by uploading an .svg
over HTTP and expecting 400; journey uploads had no such case, and now do.
VIDEO_UPLOAD is untouched, including the filename callback that forces .jpg
regardless of what the client sends, which guards the public share proxy.
PluginFrame gets an onError. A frame whose document fails to load left a
blank element at full height, which reads as a hung app rather than as a
plugin that is gone.
typecheck:tests runs in CI now, with the test tree at zero errors. tz-lookup
is left as it is: the build puts it in a lazy helpers chunk, not the entry
chunk, and the remaining split would trade a synchronous render for an async
one to move 172 kB that is already off the critical path.
117 lines
3.6 KiB
JSON
117 lines
3.6 KiB
JSON
{
|
|
"name": "@trek/server",
|
|
"version": "3.4.1",
|
|
"main": "src/index.ts",
|
|
"scripts": {
|
|
"start": "node --require tsconfig-paths/register dist/index.js",
|
|
"dev": "node scripts/dev.mjs",
|
|
"build": "node scripts/build.mjs",
|
|
"start:prod": "node --require tsconfig-paths/register dist/index.js",
|
|
"reset-admin": "node reset-admin.js",
|
|
"typecheck": "tsc --noEmit",
|
|
"typecheck:tests": "tsc -p tsconfig.tests.json --noEmit",
|
|
"gen:plugin-facts": "node --import tsx scripts/gen-plugin-facts.ts",
|
|
"check:plugin-facts": "node --import tsx scripts/gen-plugin-facts.ts --check",
|
|
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
"format:check": "prettier --check \"src/**/*.ts\" \"test/**/*.ts\"",
|
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
|
"lint:check": "eslint .",
|
|
"test": "vitest run",
|
|
"test:watch": "vitest",
|
|
"test:unit": "vitest run tests/unit",
|
|
"test:integration": "vitest run tests/integration",
|
|
"test:ws": "vitest run tests/websocket",
|
|
"test:e2e": "vitest run tests/e2e",
|
|
"test:coverage": "vitest run --coverage"
|
|
},
|
|
"dependencies": {
|
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
"@nestjs/common": "^11.1.24",
|
|
"@nestjs/config": "^4.0.4",
|
|
"@nestjs/core": "^11.1.24",
|
|
"@nestjs/platform-express": "^11.1.24",
|
|
"@nestjs/swagger": "^11.4.5",
|
|
"@simplewebauthn/server": "^13.1.2",
|
|
"@trek/nest-mcp": "*",
|
|
"@trek/shared": "*",
|
|
"archiver": "^6.0.1",
|
|
"bcryptjs": "^2.4.3",
|
|
"better-sqlite3": "^12.8.0",
|
|
"compression": "^1.8.0",
|
|
"cookie-parser": "^1.4.7",
|
|
"cors": "^2.8.5",
|
|
"dotenv": "^16.4.1",
|
|
"express": "^4.18.3",
|
|
"fast-xml-parser": "^5.5.10",
|
|
"helmet": "^8.1.0",
|
|
"jimp": "^1.6.1",
|
|
"json5": "^2.2.3",
|
|
"jsonwebtoken": "^9.0.2",
|
|
"nestjs-zod": "^5.5.0",
|
|
"node-cron": "^4.2.1",
|
|
"nodemailer": "^9.0.1",
|
|
"otplib": "^12.0.1",
|
|
"pdf-parse": "^2.4.5",
|
|
"qrcode": "^1.5.4",
|
|
"reflect-metadata": "^0.2.2",
|
|
"rxjs": "^7.8.2",
|
|
"semver": "^7.7.4",
|
|
"tsconfig-paths": "^4.2.0",
|
|
"tsx": "^4.21.0",
|
|
"typescript": "^6.0.2",
|
|
"tz-lookup": "^6.1.25",
|
|
"undici": "^7.29.0",
|
|
"unzipper": "^0.12.3",
|
|
"uuid": "^14.0.0",
|
|
"ws": "^8.21.0",
|
|
"zod": "^4.3.6"
|
|
},
|
|
"overrides": {
|
|
"hono": "^4.12.16",
|
|
"@hono/node-server": "^1.19.13",
|
|
"picomatch": "^4.0.4",
|
|
"ip-address": "^10.1.1",
|
|
"multer": "^2.2.0",
|
|
"ws": "^8.21.0",
|
|
"qs": "^6.15.2",
|
|
"file-type": "^21.3.4"
|
|
},
|
|
"devDependencies": {
|
|
"@eslint/js": "^10.0.1",
|
|
"@nestjs/testing": "^11.1.24",
|
|
"@swc/core": "^1.15.40",
|
|
"@trivago/prettier-plugin-sort-imports": "^6.0.2",
|
|
"@types/archiver": "^7.0.0",
|
|
"@types/bcryptjs": "^2.4.6",
|
|
"@types/better-sqlite3": "^7.6.13",
|
|
"@types/compression": "^1.8.0",
|
|
"@types/cookie-parser": "^1.4.10",
|
|
"@types/cors": "^2.8.19",
|
|
"@types/express": "^4.17.25",
|
|
"@types/jsonwebtoken": "^9.0.10",
|
|
"@types/multer": "^2.1.0",
|
|
"@types/node": "^25.5.0",
|
|
"@types/node-cron": "^3.0.11",
|
|
"@types/nodemailer": "^8.0.1",
|
|
"@types/qrcode": "^1.5.5",
|
|
"@types/semver": "^7.7.1",
|
|
"@types/supertest": "^6.0.3",
|
|
"@types/unzipper": "^0.10.11",
|
|
"@types/uuid": "^10.0.0",
|
|
"@types/ws": "^8.18.1",
|
|
"@vitest/coverage-istanbul": "^4.1.9",
|
|
"@vitest/coverage-v8": "^4.1.9",
|
|
"eslint": "^9.18.0",
|
|
"eslint-config-flat-gitignore": "^2.3.0",
|
|
"eslint-config-prettier": "^10.0.1",
|
|
"eslint-plugin-prettier": "^5.2.2",
|
|
"nodemon": "^3.1.0",
|
|
"prettier": "^3.8.3",
|
|
"prettier-plugin-organize-imports": "^4.3.0",
|
|
"supertest": "^7.2.2",
|
|
"typescript-eslint": "^8.58.2",
|
|
"unplugin-swc": "^1.5.9",
|
|
"vitest": "^4.1.9"
|
|
}
|
|
}
|