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
+13 -2
View File
@@ -125,7 +125,7 @@ function apiBlockAssertions(pages: { path: string; ast: PageAst }[], apiContract
: "Record<string, never>";
lines.push(
` type __wrn_api_check_${block.name} = __wrn_expect_true<AssertAssignable<${shape}, ApiInput<${JSON.stringify(
`type __wrn_api_check_${block.name} = WRNexusGenerated.__wrn_expect_true<WRNexusGenerated.AssertAssignable<${shape}, WRNexusGenerated.ApiInput<${JSON.stringify(
block.path,
)}, ${JSON.stringify(block.method)}>>>;`,
);
@@ -262,12 +262,23 @@ declare namespace WRNexusGenerated {
type __wrn_expect_true<T extends true> = T;
type ApiInput<P extends ApiRoute, M> = ApiContracts[P][M]["input"];
type ApiOutput<P extends ApiRoute, M> = ApiContracts[P][M]["output"];
${apiBlockAssertions(pageAsts, apiContracts)}
}
`;
mkdirSync(typeDir, { recursive: true });
const output = join(typeDir, "wrnexus.generated.d.ts");
writeFileSync(output, code, "utf8");
// `.d.ts` contents are exempt from checking under `skipLibCheck: true` (set in the
// repo/app tsconfig), so the per-block assertions are written into a real `.ts` file
// instead — only genuine `.ts`/`.tsx` sources are compiled and checked.
const apiChecksCode = `// AUTO-GENERATED by \`wrnexus generate types\` - do not edit.
//
// Type-only assertions for sectioned \`api\` blocks. Kept as a real .ts file (not
// wrnexus.generated.d.ts) because \`skipLibCheck\` exempts .d.ts contents from being
// checked; this file is compiled and checked normally by the project's own tsc.
${apiBlockAssertions(pageAsts, apiContracts)}
export {};
`;
writeFileSync(join(typeDir, "wrnexus.generated.api-checks.ts"), apiChecksCode, "utf8");
writePluginArtifacts(root, pluginContributions);
return {
file: relative(root, output).replace(/\\/g, "/"),