diff --git a/packages/rest/src/analytics-read-scope-refusal-envelope.test.ts b/packages/rest/src/analytics-read-scope-refusal-envelope.test.ts index 5596876ab3..6058105940 100644 --- a/packages/rest/src/analytics-read-scope-refusal-envelope.test.ts +++ b/packages/rest/src/analytics-read-scope-refusal-envelope.test.ts @@ -222,7 +222,7 @@ describe('[#5367] POST /analytics/dataset/query — a read-scope failure is a 50 // …and it is in the LOG, which is now its only destination. Asserted rather // than assumed: "withheld" is only acceptable because the operator still // has the whole thing. - const logged = logSpy.mock.calls.map((args) => args.map(String).join(' ')).join('\n'); + const logged = logSpy.mock.calls.map((args: unknown[]) => args.map(String).join(' ')).join('\n'); expect(logged).toMatch(/Analytics dataset query error/); expect(logged).toContain('read-scope-sql'); expect(logged).toContain(c.secret); diff --git a/packages/rest/src/export-integration.test.ts b/packages/rest/src/export-integration.test.ts index a743115955..3673495f35 100644 --- a/packages/rest/src/export-integration.test.ts +++ b/packages/rest/src/export-integration.test.ts @@ -144,9 +144,17 @@ async function boot() { const rest = new RestServer(createMockServer() as any, protocol as any, { api: { requireAuth: false } } as any); (rest as any).resolveExecCtx = async () => ({ userId: 'test-user' }); rest.registerRoutes(); + // [#12573] `Array.prototype.find` is `Route | undefined`, so every + // `route.handler(...)` below read as possibly-undefined (TS18048 x13). + // Asserted non-null HERE, once, rather than at each call site: the + // lookup either finds the registered route or the boot is broken, and + // `registerRoutes()` two lines up is what guarantees it. Same form the + // green siblings in this package already use (e.g. + // `analytics-dataset-where-gate.test.ts`). Type-level only — `!` erases, + // so no call below receives a different value than it did before. const route = rest.getRoutes().find( (r: any) => r.method === 'GET' && r.path === '/api/v1/data/:object/export', - ); + )!; return { engine, protocol, route }; } @@ -394,9 +402,10 @@ describe('export route — FLS column projection via getReadableFields (#3547)', ); (rest as any).resolveExecCtx = async () => ({ userId: 'test-user' }); rest.registerRoutes(); + // [#12573] Non-null for the same reason as `boot()` above. const route = rest.getRoutes().find( (r: any) => r.method === 'GET' && r.path === '/api/v1/data/:object/export', - ); + )!; return { engine, route }; } diff --git a/packages/rest/src/rest-expected-error-logging.test.ts b/packages/rest/src/rest-expected-error-logging.test.ts index 58f322dcea..f923766850 100644 --- a/packages/rest/src/rest-expected-error-logging.test.ts +++ b/packages/rest/src/rest-expected-error-logging.test.ts @@ -110,7 +110,7 @@ async function callDataList(rest: any, object: string) { let errorSpy: ReturnType; /** Only the "[REST] Unhandled error" channel — other console.error noise is not this test's business. */ -const unhandledLogs = () => errorSpy.mock.calls.filter((c) => c[0] === '[REST] Unhandled error:'); +const unhandledLogs = () => errorSpy.mock.calls.filter((c: unknown[]) => c[0] === '[REST] Unhandled error:'); beforeEach(() => { errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); }); afterEach(() => { errorSpy.mockRestore(); }); diff --git a/packages/rest/src/rest-meta-outage-vs-miss.test.ts b/packages/rest/src/rest-meta-outage-vs-miss.test.ts index 259864803c..c0ba44c133 100644 --- a/packages/rest/src/rest-meta-outage-vs-miss.test.ts +++ b/packages/rest/src/rest-meta-outage-vs-miss.test.ts @@ -95,7 +95,7 @@ let errorSpy: ReturnType; beforeEach(() => { errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {}); }); afterEach(() => { errorSpy.mockRestore(); }); -const loggedText = () => errorSpy.mock.calls.map((c) => JSON.stringify(c.map(String))).join('\n'); +const loggedText = () => errorSpy.mock.calls.map((c: unknown[]) => JSON.stringify(c.map(String))).join('\n'); describe('[#5532] an unreadable metadata store reaches the client as a retryable 503', () => { it('503 + SERVICE_UNAVAILABLE, and the prose is withheld', async () => { diff --git a/packages/rest/src/rest-unclassified-fault-status.test.ts b/packages/rest/src/rest-unclassified-fault-status.test.ts index 3d2c0e3c3a..a46e4c50e6 100644 --- a/packages/rest/src/rest-unclassified-fault-status.test.ts +++ b/packages/rest/src/rest-unclassified-fault-status.test.ts @@ -118,7 +118,7 @@ beforeEach(() => { errorSpy = vi.spyOn(console, 'error').mockImplementation(() = afterEach(() => { errorSpy.mockRestore(); }); /** Everything the error channel printed, flattened for substring searching. */ -const loggedText = () => errorSpy.mock.calls.map((c) => JSON.stringify(c.map(String))).join('\n'); +const loggedText = () => errorSpy.mock.calls.map((c: unknown[]) => JSON.stringify(c.map(String))).join('\n'); // --------------------------------------------------------------------------- // The unit: mapDataError's terminal branch diff --git a/packages/rest/test-typecheck-debt.json b/packages/rest/test-typecheck-debt.json index ee248d0c1a..685eb62539 100644 --- a/packages/rest/test-typecheck-debt.json +++ b/packages/rest/test-typecheck-debt.json @@ -1,17 +1,13 @@ { "_comment": "Per-file tsc error debt of the @objectstack/rest TEST layer (#5286). `tsconfig.test.json` compiles `src/**/*.test.ts` — which `tsconfig.json` excludes and therefore no gate ever read — and every file below still carries errors from before that gate existed, almost all of them fixture literals annotated with a schema OUTPUT type (`z.infer`) while holding an authored INPUT literal. EXACT ratchet, judged by re-running tsc: a file that gains errors is red, a file that loses them is red until its number is re-recorded, a file that reaches zero is red until its entry is deleted, and a file NOT listed here may have no errors at all. Regenerate with: pnpm --filter @objectstack/rest gen:test-typecheck-debt", "entries": { - "src/analytics-read-scope-refusal-envelope.test.ts": 1, - "src/export-integration.test.ts": 17, + "src/export-integration.test.ts": 4, "src/import-dryrun-parity.test.ts": 1, "src/import-integration.test.ts": 3, "src/import-job-integration.test.ts": 2, "src/meta-public-book-grant.test.ts": 1, "src/rest-batch-size-cap.test.ts": 1, - "src/rest-expected-error-logging.test.ts": 1, - "src/rest-meta-outage-vs-miss.test.ts": 1, "src/rest-meta-save-receipt-envelope.test.ts": 3, - "src/rest-unclassified-fault-status.test.ts": 1, "src/rest-write-response-formula.test.ts": 1, "src/rest.test.ts": 4 }