From 6d9078de99c07d8e4fdaea13bb49b35e74910987 Mon Sep 17 00:00:00 2001 From: logfox-agent Date: Wed, 26 Aug 2026 15:04:00 -0400 Subject: [PATCH] fix: emit runtyp 2 union syntax in validator codegen Use p.union([...], message) for enum, oneOf, and anyOf preds so generated schemas typecheck against runtyp 2.x. Co-authored-by: Cursor --- src/generateClient.spec.ts | 5 +++++ src/generateValidators.spec.ts | 16 +++++++++++++++- src/generateValidators/schemaToRuntyp.ts | 12 +++++++++--- 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/src/generateClient.spec.ts b/src/generateClient.spec.ts index ed6b528f..7429febb 100644 --- a/src/generateClient.spec.ts +++ b/src/generateClient.spec.ts @@ -211,6 +211,11 @@ test('generateClientSource: string enum exports emit const object and derived ty } as const;`), true, ); + assert.equal( + generated.includes('issueStatus: p.union([p.literal("open"), p.literal("closed"), p.literal("ignored")], \'invalid\'),'), + true, + 'string enum exports must use runtyp 2 p.union([...], message) syntax', + ); assert.equal( generated.includes('export type IssueStatus = (typeof IssueStatus)[keyof typeof IssueStatus];'), true, diff --git a/src/generateValidators.spec.ts b/src/generateValidators.spec.ts index b84536b9..2cbd9fda 100644 --- a/src/generateValidators.spec.ts +++ b/src/generateValidators.spec.ts @@ -33,7 +33,21 @@ test('schemaToRuntyp: union via oneOf', (assert) => { ], }); - assert.equal(expr, 'p.union(p.string(), p.number())'); + assert.equal(expr, 'p.union([p.string(), p.number()], \'invalid\')'); + +}); + +test('schemaToRuntyp: string enum uses runtyp 2 union syntax', (assert) => { + + const expr = schemaToRuntyp({ + type: 'string', + enum: ['open', 'closed'], + }); + + assert.equal( + expr, + 'p.union([p.literal("open"), p.literal("closed")], \'invalid\')', + ); }); diff --git a/src/generateValidators/schemaToRuntyp.ts b/src/generateValidators/schemaToRuntyp.ts index da0f1f52..f9205877 100644 --- a/src/generateValidators/schemaToRuntyp.ts +++ b/src/generateValidators/schemaToRuntyp.ts @@ -12,6 +12,12 @@ function escapeString(value: string): string { } +function unionExpr(parts: string[]): string { + + return `p.union([${parts.join(', ')}], 'invalid')`; + +} + function schemaToRuntypExpr(schema: unknown): string { if (!isRecord(schema)) { @@ -32,7 +38,7 @@ function schemaToRuntypExpr(schema: unknown): string { if (literals.length === 1) return literals[0]; - return `p.union(${literals.join(', ')})`; + return unionExpr(literals); } @@ -48,7 +54,7 @@ function schemaToRuntypExpr(schema: unknown): string { if (parts.length === 1) return parts[0]; - return `p.union(${parts.join(', ')})`; + return unionExpr(parts); } @@ -58,7 +64,7 @@ function schemaToRuntypExpr(schema: unknown): string { if (parts.length === 1) return parts[0]; - return `p.union(${parts.join(', ')})`; + return unionExpr(parts); }