mirror of
https://github.com/diegosouzapw/OmniRoute.git
synced 2026-09-21 14:22:14 +03:00
Landed with the design call resolved per the owner's pick — **option 1**: the synced store is now endpoint-agnostic (persistDiscoveredModels and managedModelImport no longer drop non-chat models at write time), and chat selectability moved to read time (auto-pool expansion in autoStrategy applies filterChatSelectableModels; the models-route projection already had its chatOnly filter). Your discovery test now passes end-to-end (3/3): /api/show capabilities persist per connection and image/embedding requests route through the advertising host. Reconciliation notes: conflicted areas merged onto the current tip (adobe discovery import, requestedModel preflight signature, resolvedProvider fast-path coexists with the synced-route override — explicit resolution wins); carried base-red drains (#10055 memoization, #11071 test variants) dropped as already-landed; the managed-model-import exclusion test was propagated to the new contract (image/video models persist; the read filter still hides them from chat pickers — pinned by a new assertion). Full battery: 205/206 focused (the one red is a confirmed periodic-timer timing flake on the loaded devbox — 20/20 isolated), autoCombo vitest 30/30, combo suites 46/46, gates + typecheck clean. Thank you @yourspraveen — the capability probe + routing design was right; it just needed the store contract opened up. Fixes #11087.
55 lines
2.0 KiB
TypeScript
55 lines
2.0 KiB
TypeScript
/**
|
|
* Guard for the t06:route-validation gate (Hard Rule #7 — always validate inputs
|
|
* with Zod schemas).
|
|
*
|
|
* The gate (scripts/check/check-route-validation.mjs) is a source scan: any
|
|
* `route.ts` under src/app/api that calls `request.json()` must also call
|
|
* `validateBody()` or `.safeParse()`. It has NO allowlist, so a route that
|
|
* hand-rolls `typeof x === "string"` checks passes review but fails CI — which
|
|
* is exactly how four routes (#9445 marketplace install, #8523's three Dario
|
|
* admin routes) landed on release/v3.8.50 and kept the branch out of
|
|
* release-green (#9737).
|
|
*
|
|
* This test runs the same rule inside the unit suite so the violation surfaces
|
|
* on the PR that introduces it, instead of on the next base-red sweep.
|
|
*/
|
|
import test from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import fs from "node:fs";
|
|
import path from "node:path";
|
|
|
|
const REPO_ROOT = path.resolve(import.meta.dirname, "..", "..");
|
|
const API_ROOT = path.join(REPO_ROOT, "src", "app", "api");
|
|
|
|
function collectRouteFiles(dir: string): string[] {
|
|
const files: string[] = [];
|
|
for (const entry of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
const full = path.join(dir, entry.name);
|
|
if (entry.isDirectory()) {
|
|
files.push(...collectRouteFiles(full));
|
|
} else if (entry.isFile() && entry.name === "route.ts") {
|
|
files.push(full);
|
|
}
|
|
}
|
|
return files;
|
|
}
|
|
|
|
test("every API route reading request.json() validates it with Zod (t06)", () => {
|
|
const offenders: string[] = [];
|
|
|
|
for (const file of collectRouteFiles(API_ROOT)) {
|
|
const source = fs.readFileSync(file, "utf8");
|
|
if (!/request\.json\s*\(/.test(source)) continue;
|
|
if (/\bvalidateBody\s*\(/.test(source) || /\.safeParse\s*\(/.test(source)) continue;
|
|
offenders.push(path.relative(REPO_ROOT, file));
|
|
}
|
|
|
|
assert.deepEqual(
|
|
offenders,
|
|
[],
|
|
`routes call request.json() without validateBody()/.safeParse() — hand-rolled ` +
|
|
`typeof checks do not satisfy Hard Rule #7 and fail the t06 CI gate:\n ` +
|
|
offenders.join("\n ")
|
|
);
|
|
});
|