fix(cli): move api-block assertions into a real .ts file

skipLibCheck exempts .d.ts contents from being checked, so assertions
written inside wrnexus.generated.d.ts were never evaluated by tsc.
Emit them into wrnexus.generated.api-checks.ts instead, referencing
the WRNexusGenerated namespace's helper types (which stay in the
.d.ts). Track the new generated file in check:generated-types.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-19 16:01:07 +05:30
co-authored by Claude Opus 5
parent a2698fb51a
commit 785e8a65bd
5 changed files with 45 additions and 9 deletions
+20 -7
View File
@@ -51,15 +51,19 @@ test("emits the ApiInput, ApiOutput and AssertAssignable helpers", () => {
);
});
// The per-block assertions live in a plain .ts file, not the .d.ts: `skipLibCheck: true`
// (set repo-wide) exempts .d.ts *contents* from being checked at all, so a `.d.ts` can
// never actually enforce anything here. A real .ts file under app/ is compiled and
// checked normally.
test("emits one assertion per sectioned block, naming its route and method", () => {
const root = fixture(BLOCK);
generateApplicationTypes(root);
const generated = readFileSync(join(root, "app/types/wrnexus.generated.d.ts"), "utf8");
const checks = readFileSync(join(root, "app/types/wrnexus.generated.api-checks.ts"), "utf8");
expect(generated).toContain("__wrn_api_check_searchUsers");
expect(generated).toContain('ApiInput<"/api/users", "POST">');
expect(generated).toContain("name?: string");
expect(generated).toContain("age?: number");
expect(checks).toContain("__wrn_api_check_searchUsers");
expect(checks).toContain('WRNexusGenerated.ApiInput<"/api/users", "POST">');
expect(checks).toContain("name?: string");
expect(checks).toContain("age?: number");
});
test("a legacy bare-body block produces no assertion", () => {
@@ -67,7 +71,16 @@ test("a legacy bare-body block produces no assertion", () => {
return users.length
}`);
generateApplicationTypes(root);
const generated = readFileSync(join(root, "app/types/wrnexus.generated.d.ts"), "utf8");
const checks = readFileSync(join(root, "app/types/wrnexus.generated.api-checks.ts"), "utf8");
expect(generated).not.toContain("__wrn_api_check_legacyUsers");
expect(checks).not.toContain("__wrn_api_check_legacyUsers");
});
test("the api-checks file has no runtime code and is a module", () => {
const root = fixture(BLOCK);
generateApplicationTypes(root);
const checks = readFileSync(join(root, "app/types/wrnexus.generated.api-checks.ts"), "utf8");
expect(checks).toContain("AUTO-GENERATED");
expect(checks.trim().endsWith("export {};")).toBe(true);
});