@zodapi/codegen 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Alan Christensen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,96 @@
1
+ # @zodapi/codegen
2
+
3
+ Generates a [zodapi](https://github.com/christensena/zodapi) contract — zod schemas plus plain
4
+ `RouteDef` route objects — from an OpenAPI 3.1 document. For backends not written in TypeScript:
5
+ point it at the spec your Python/Go/.NET/... framework emits and consume the result with
6
+ `@zodapi/client`.
7
+
8
+ ```sh
9
+ zodapi-codegen openapi.json -o contract.ts
10
+ ```
11
+
12
+ or programmatically:
13
+
14
+ ```ts
15
+ import { generateContract } from '@zodapi/codegen'
16
+
17
+ const source = generateContract(JSON.parse(await readFile('openapi.json', 'utf8')))
18
+ ```
19
+
20
+ ## What it generates
21
+
22
+ One file, importing only `zod` and `@zodapi/core`:
23
+
24
+ - an exported const per `components/schemas` entry — component name = const name, registered via
25
+ `.meta({ id })` so the schemas re-serialize as the same `$ref` components; recursive schemas use
26
+ zod 4 shape getters
27
+ - an exported const per operation, a plain object `satisfies RouteDef` — `operationId` becomes the
28
+ client `alias` (no alias without one); the spec's declared responses are taken verbatim, nothing
29
+ (like the zodapi `400`) is injected
30
+ - a `routes` tuple ready for `createClient(routes)` from `@zodapi/client`
31
+ - a `problemFlavor` const (`'zodapi' | 'problem-details' | undefined`, detected from the spec's
32
+ error responses — zodapi's `urn:zodapi:validation` problem type, or an ASP.NET-style
33
+ `ValidationProblemDetails`) to feed `decodersFor(problemFlavor)` when creating the client
34
+ - with `exportTypes: true` (CLI `--export-types`), a `type <Name> = z.infer<typeof <Name>>` alias
35
+ alongside each component const (the zodios codegen convention). `z.infer` is the output side —
36
+ use `z.input<typeof <Name>>` where the wire form differs (e.g. date codecs)
37
+
38
+ Query parameters typed `array` are declared with `queryArray(item)` from `@zodapi/core`, matching
39
+ the zodapi `a[]=` convention.
40
+
41
+ Output is unformatted; run your formatter over it.
42
+
43
+ ## Date conversion
44
+
45
+ By default ISO strings stay strings (`z.iso.datetime()` / `z.iso.date()`). Opt in to `Date`
46
+ conversion per format:
47
+
48
+ ```sh
49
+ zodapi-codegen openapi.json -o contract.ts --dates-datetime --dates-date --dates-offset
50
+ ```
51
+
52
+ ```ts
53
+ generateContract(doc, { dates: { datetime: true, date: true, offset: true } })
54
+ ```
55
+
56
+ - `datetime` / `--dates-datetime`: `format: date-time` fields become a bidirectional
57
+ `z.codec(z.iso.datetime(), z.date(), ...)` — responses parse to `Date`, requests encode back to
58
+ the wire string
59
+ - `date` / `--dates-date`: `format: date` fields become a codec decoding to `Date` at UTC midnight
60
+ and encoding back to `YYYY-MM-DD`
61
+ - `offset` / `--dates-offset`: accept UTC offsets in date-time values
62
+ (`z.iso.datetime({ offset: true })`)
63
+
64
+ The codecs are emitted once as shared `isoDatetimeToDate` / `isoDateToDate` consts; a field with
65
+ extra wire-side constraints or a `default` inlines the codec with those applied to its input side.
66
+
67
+ Because codecs change parsed values, `@zodapi/client` refuses calls whose validation mode would
68
+ skip a codec-bearing schema (see the client README); pair a dates contract with
69
+ `validate: 'response'` (the default) or `'both'`, and optionally `encodeRequests: true` to pass
70
+ `Date` objects in requests too.
71
+
72
+ ## Fidelity
73
+
74
+ The converter covers the JSON Schema subset OpenAPI 3.1 uses: objects (required/optional,
75
+ `additionalProperties` as loose objects, catchalls, and records), arrays and tuples, unions
76
+ (`oneOf` is treated as `anyOf`), intersections (`allOf`), nullability in both encodings, enums and
77
+ consts, string formats (`email`, `uuid`, `uri`, `date-time`, ...), numeric/string/array
78
+ constraints, defaults, and `description`/`title`/`examples` metadata.
79
+
80
+ It is enforced by a round-trip test: a comprehensive hand-written contract is serialized to
81
+ OpenAPI, fed through the generator, and the document emitted from the generated contract must
82
+ deep-equal the original.
83
+
84
+ ## Not covered
85
+
86
+ `webhooks`, refs outside `#/components/schemas` (component parameters/responses), response headers,
87
+ and OpenAPI 3.0 documents (3.1 only — 3.1 schemas are real JSON Schema, 3.0's `nullable` dialect is
88
+ not).
89
+
90
+ ## Install
91
+
92
+ ```sh
93
+ pnpm add -D @zodapi/codegen
94
+ ```
95
+
96
+ The generated file needs `zod` and `@zodapi/core` at runtime.
package/dist/cli.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
package/dist/cli.js ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ import { readFileSync, writeFileSync } from 'node:fs';
3
+ import { generateContract } from './generate.js';
4
+ function fail(message) {
5
+ console.error(message);
6
+ process.exit(1);
7
+ }
8
+ const USAGE = 'Usage: zodapi-codegen <openapi.json> [-o contract.ts] [--export-types] [--dates-datetime] [--dates-date] [--dates-offset]';
9
+ const args = process.argv.slice(2);
10
+ let input;
11
+ let output;
12
+ let exportTypes = false;
13
+ const dates = {};
14
+ for (let i = 0; i < args.length; i++) {
15
+ const arg = args[i];
16
+ if (arg === '-o' || arg === '--output') {
17
+ output = args[++i] ?? fail(`${arg} requires a value`);
18
+ }
19
+ else if (arg === '--export-types') {
20
+ exportTypes = true;
21
+ }
22
+ else if (arg === '--dates-datetime') {
23
+ dates.datetime = true;
24
+ }
25
+ else if (arg === '--dates-date') {
26
+ dates.date = true;
27
+ }
28
+ else if (arg === '--dates-offset') {
29
+ dates.offset = true;
30
+ }
31
+ else if (arg === '-h' || arg === '--help') {
32
+ console.log(USAGE);
33
+ process.exit(0);
34
+ }
35
+ else if (input === undefined) {
36
+ input = arg;
37
+ }
38
+ else {
39
+ fail(`unexpected argument: ${arg}`);
40
+ }
41
+ }
42
+ if (input === undefined)
43
+ fail(USAGE);
44
+ const options = {
45
+ ...(Object.keys(dates).length > 0 && { dates }),
46
+ ...(exportTypes && { exportTypes: true }),
47
+ };
48
+ const doc = JSON.parse(readFileSync(input, 'utf8'));
49
+ const source = generateContract(doc, options);
50
+ if (output === undefined) {
51
+ process.stdout.write(source);
52
+ }
53
+ else {
54
+ writeFileSync(output, source);
55
+ }
56
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAErD,OAAO,EAAE,gBAAgB,EAAwB,MAAM,eAAe,CAAA;AAGtE,SAAS,IAAI,CAAC,OAAe;IAC3B,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAA;IACtB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC;AAED,MAAM,KAAK,GACT,2HAA2H,CAAA;AAE7H,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAA;AAClC,IAAI,KAAyB,CAAA;AAC7B,IAAI,MAA0B,CAAA;AAC9B,IAAI,WAAW,GAAG,KAAK,CAAA;AACvB,MAAM,KAAK,GAAiB,EAAE,CAAA;AAC9B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;IACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAA;IACnB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;QACvC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,GAAG,GAAG,mBAAmB,CAAC,CAAA;IACvD,CAAC;SAAM,IAAI,GAAG,KAAK,gBAAgB,EAAE,CAAC;QACpC,WAAW,GAAG,IAAI,CAAA;IACpB,CAAC;SAAM,IAAI,GAAG,KAAK,kBAAkB,EAAE,CAAC;QACtC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAA;IACvB,CAAC;SAAM,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAA;IACnB,CAAC;SAAM,IAAI,GAAG,KAAK,gBAAgB,EAAE,CAAC;QACpC,KAAK,CAAC,MAAM,GAAG,IAAI,CAAA;IACrB,CAAC;SAAM,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAA;QAClB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;SAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,KAAK,GAAG,GAAG,CAAA;IACb,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAA;IACrC,CAAC;AACH,CAAC;AACD,IAAI,KAAK,KAAK,SAAS;IAAE,IAAI,CAAC,KAAK,CAAC,CAAA;AAEpC,MAAM,OAAO,GAAoB;IAC/B,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,CAAC;IAC/C,GAAG,CAAC,WAAW,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;CAC1C,CAAA;AACD,MAAM,GAAG,GAAY,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAA;AAC5D,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AAC7C,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;IACzB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAA;AAC9B,CAAC;KAAM,CAAC;IACN,aAAa,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;AAC/B,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { type DatesOptions } from './schema-to-zod.js';
2
+ export type ProblemFlavor = 'zodapi' | 'problem-details';
3
+ /**
4
+ * Detect which problem-details flavor a spec's error responses use, so
5
+ * generated contracts can carry a `problemFlavor` hint for
6
+ * `decodersFor(...)` on the client.
7
+ */
8
+ export declare function detectProblemFlavor(doc: unknown): ProblemFlavor | undefined;
9
+ export interface GenerateOptions {
10
+ /** Convert ISO date/time strings to `Date` objects via `z.codec`s. */
11
+ dates?: DatesOptions | undefined;
12
+ /**
13
+ * Also export a `type <Name> = z.infer<typeof <Name>>` alias per component
14
+ * schema (the zodios codegen convention). `z.infer` is the output side; use
15
+ * `z.input<typeof <Name>>` where the wire form differs (e.g. date codecs).
16
+ */
17
+ exportTypes?: boolean | undefined;
18
+ }
19
+ /**
20
+ * Generate zodapi contract source (zod schemas + `RouteDef` route objects) from
21
+ * a parsed OpenAPI 3.1 document. The result imports only `zod` and
22
+ * `@zodapi/core`, and exports one const per component schema, one per
23
+ * operation, and a `routes` tuple for `createClient(routes)`.
24
+ */
25
+ export declare function generateContract(doc: unknown, options?: GenerateOptions): string;
26
+ //# sourceMappingURL=generate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"AACA,OAAO,EAML,KAAK,YAAY,EAElB,MAAM,oBAAoB,CAAA;AAuD3B,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,iBAAiB,CAAA;AA2BxD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,OAAO,GAAG,aAAa,GAAG,SAAS,CAkC3E;AAUD,MAAM,WAAW,eAAe;IAC9B,sEAAsE;IACtE,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;IAChC;;;;OAIG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CAClC;AAyQD;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,MAAM,CAGhF"}
@@ -0,0 +1,378 @@
1
+ import { NameAllocator, routeNameFromPath } from './names.js';
2
+ import { DATE_CODEC_FNS, convertSchema, dateCodecInput, } from './schema-to-zod.js';
3
+ const METHODS = ['get', 'put', 'post', 'delete', 'options', 'head', 'patch', 'trace'];
4
+ const REF_PREFIX = '#/components/schemas/';
5
+ function isObject(value) {
6
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
7
+ }
8
+ function json(value) {
9
+ return JSON.stringify(value);
10
+ }
11
+ /** All `#/components/schemas/*` names referenced anywhere inside `value`. */
12
+ function collectRefs(value, into) {
13
+ if (Array.isArray(value)) {
14
+ for (const item of value)
15
+ collectRefs(item, into);
16
+ return;
17
+ }
18
+ if (!isObject(value))
19
+ return;
20
+ const ref = value['$ref'];
21
+ if (typeof ref === 'string' && ref.startsWith(REF_PREFIX)) {
22
+ into.add(ref.slice(REF_PREFIX.length));
23
+ }
24
+ for (const item of Object.values(value))
25
+ collectRefs(item, into);
26
+ }
27
+ /** DFS postorder so dependencies come before dependents; cycles resolve via object getters. */
28
+ function orderComponents(schemas) {
29
+ const order = [];
30
+ const visited = new Set();
31
+ const visit = (name) => {
32
+ if (visited.has(name) || !(name in schemas))
33
+ return;
34
+ visited.add(name);
35
+ const deps = new Set();
36
+ collectRefs(schemas[name], deps);
37
+ for (const dep of deps)
38
+ visit(dep);
39
+ order.push(name);
40
+ };
41
+ for (const name of Object.keys(schemas))
42
+ visit(name);
43
+ return order;
44
+ }
45
+ /** Splices extra entries into a trailing `.meta({ ... })` call, or appends one. */
46
+ function withMeta(code, entries) {
47
+ if (entries.length === 0)
48
+ return code;
49
+ const tail = /^([\s\S]*)\.meta\(\{ ([\s\S]*) \}\)$/.exec(code);
50
+ if (tail)
51
+ return `${tail[1]}.meta({ ${entries.join(', ')}, ${tail[2]} })`;
52
+ return `${code}.meta({ ${entries.join(', ')} })`;
53
+ }
54
+ // Mirrors ZODAPI_VALIDATION_TYPE from @zodapi/core (codegen only reads specs).
55
+ const ZODAPI_VALIDATION_TYPE = 'urn:zodapi:validation';
56
+ function isZodapiValidationSchema(schema) {
57
+ const properties = isObject(schema['properties']) ? schema['properties'] : {};
58
+ const type = properties['type'];
59
+ if (!isObject(type))
60
+ return false;
61
+ // zod literals serialize as one-element enums; accept const too.
62
+ const values = Array.isArray(type['enum']) ? type['enum'] : [type['const']];
63
+ return values.includes(ZODAPI_VALIDATION_TYPE);
64
+ }
65
+ /** ASP.NET-style `ValidationProblemDetails`: an `errors` map of string arrays plus problem members. */
66
+ function isValidationProblemSchema(schema) {
67
+ const properties = isObject(schema['properties']) ? schema['properties'] : {};
68
+ const errors = properties['errors'];
69
+ if (!isObject(errors))
70
+ return false;
71
+ const additional = errors['additionalProperties'];
72
+ const items = isObject(additional) ? additional['items'] : undefined;
73
+ const errorsAreStringArrays = isObject(additional) &&
74
+ additional['type'] === 'array' &&
75
+ isObject(items) &&
76
+ items['type'] === 'string';
77
+ const hasProblemMember = ['type', 'title', 'status', 'detail'].some((m) => m in properties);
78
+ return errorsAreStringArrays && hasProblemMember;
79
+ }
80
+ /**
81
+ * Detect which problem-details flavor a spec's error responses use, so
82
+ * generated contracts can carry a `problemFlavor` hint for
83
+ * `decodersFor(...)` on the client.
84
+ */
85
+ export function detectProblemFlavor(doc) {
86
+ if (!isObject(doc))
87
+ return undefined;
88
+ const components = isObject(doc['components']) ? doc['components'] : {};
89
+ const schemas = isObject(components['schemas']) ? components['schemas'] : {};
90
+ const resolve = (schema) => {
91
+ if (!isObject(schema))
92
+ return undefined;
93
+ const ref = schema['$ref'];
94
+ if (typeof ref === 'string' && ref.startsWith(REF_PREFIX)) {
95
+ const target = schemas[ref.slice(REF_PREFIX.length)];
96
+ return isObject(target) ? target : undefined;
97
+ }
98
+ return schema;
99
+ };
100
+ let flavor;
101
+ const paths = isObject(doc['paths']) ? doc['paths'] : {};
102
+ for (const pathItem of Object.values(paths)) {
103
+ if (!isObject(pathItem))
104
+ continue;
105
+ for (const method of METHODS) {
106
+ const op = pathItem[method];
107
+ if (!isObject(op) || !isObject(op['responses']))
108
+ continue;
109
+ for (const [status, response] of Object.entries(op['responses'])) {
110
+ if (!/^[45]|^default$/.test(status))
111
+ continue;
112
+ if (!isObject(response) || !isObject(response['content']))
113
+ continue;
114
+ for (const mediaDef of Object.values(response['content'])) {
115
+ const schema = resolve(isObject(mediaDef) ? mediaDef['schema'] : undefined);
116
+ if (!schema)
117
+ continue;
118
+ if (isZodapiValidationSchema(schema))
119
+ return 'zodapi';
120
+ if (isValidationProblemSchema(schema))
121
+ flavor = 'problem-details';
122
+ }
123
+ }
124
+ }
125
+ }
126
+ return flavor;
127
+ }
128
+ const DATE_CODEC_NAMES = {
129
+ datetime: 'isoDatetimeToDate',
130
+ date: 'isoDateToDate',
131
+ };
132
+ class Generator {
133
+ doc;
134
+ names = new NameAllocator();
135
+ declared = new Set();
136
+ usesQueryArray = false;
137
+ dateCodecs = new Map();
138
+ schemas;
139
+ ctx = {
140
+ dates: undefined,
141
+ dateCodec: (kind) => {
142
+ const existing = this.dateCodecs.get(kind);
143
+ if (existing !== undefined)
144
+ return existing;
145
+ // Distinct allocator key so a component named like the helper still wins its name.
146
+ const ident = this.names.allocate(`date-codec:${kind}`, DATE_CODEC_NAMES[kind]);
147
+ this.dateCodecs.set(kind, ident);
148
+ return ident;
149
+ },
150
+ resolveRef: (ref) => {
151
+ if (!ref.startsWith(REF_PREFIX))
152
+ throw new Error(`unsupported $ref: ${ref}`);
153
+ const original = ref.slice(REF_PREFIX.length);
154
+ const ident = this.names.lookup(original);
155
+ if (ident === undefined)
156
+ throw new Error(`$ref to unknown component: ${ref}`);
157
+ return { ident, forward: !this.declared.has(original) };
158
+ },
159
+ resolveComponentSchema: (ref) => {
160
+ if (!ref.startsWith(REF_PREFIX))
161
+ return undefined;
162
+ const target = this.schemas[ref.slice(REF_PREFIX.length)];
163
+ return isObject(target) ? target : undefined;
164
+ },
165
+ };
166
+ exportTypes;
167
+ constructor(doc, options) {
168
+ this.doc = doc;
169
+ const components = isObject(doc['components']) ? doc['components'] : {};
170
+ this.schemas = isObject(components['schemas']) ? components['schemas'] : {};
171
+ this.ctx.dates = options?.dates;
172
+ this.exportTypes = options?.exportTypes === true;
173
+ }
174
+ generate() {
175
+ const openapi = this.doc['openapi'];
176
+ if (typeof openapi !== 'string' || !openapi.startsWith('3.1')) {
177
+ throw new Error(`expected an OpenAPI 3.1 document, got openapi: ${json(openapi)}`);
178
+ }
179
+ const schemas = this.schemas;
180
+ const order = orderComponents(schemas);
181
+ // Allocate all component names first so refs resolve regardless of order.
182
+ for (const name of Object.keys(schemas))
183
+ this.names.allocate(name);
184
+ const componentDecls = order.map((name) => {
185
+ const expr = convertSchema(schemas[name], this.ctx);
186
+ const code = withMeta(expr.code, [`id: ${json(name)}`]);
187
+ this.declared.add(name);
188
+ const ident = this.names.lookup(name);
189
+ const constDecl = `export const ${ident} = ${code}\n`;
190
+ return this.exportTypes
191
+ ? `${constDecl}export type ${ident} = z.infer<typeof ${ident}>\n`
192
+ : constDecl;
193
+ });
194
+ const routeDecls = [];
195
+ const routeIdents = [];
196
+ const paths = isObject(this.doc['paths']) ? this.doc['paths'] : {};
197
+ for (const [path, pathItem] of Object.entries(paths)) {
198
+ if (!isObject(pathItem))
199
+ continue;
200
+ for (const method of METHODS) {
201
+ const op = pathItem[method];
202
+ if (!isObject(op))
203
+ continue;
204
+ const ident = this.emitRoute(method, path, op, pathItem, routeDecls);
205
+ routeIdents.push(ident);
206
+ }
207
+ }
208
+ const imports = [
209
+ `import type { RouteDef } from '@zodapi/core'`,
210
+ ...(this.usesQueryArray ? [`import { queryArray } from '@zodapi/core'`] : []),
211
+ `import { z } from 'zod'`,
212
+ ];
213
+ // RouteDef plus the documentation fields OpenAPI operations carry.
214
+ const routeType = 'type GeneratedRoute = RouteDef & {\n' +
215
+ ' operationId?: string\n' +
216
+ ' summary?: string\n' +
217
+ ' description?: string\n' +
218
+ ' tags?: readonly string[]\n' +
219
+ '}\n';
220
+ const routesArray = routeIdents.length === 0
221
+ ? 'export const routes = [] as const\n'
222
+ : `export const routes = [\n${routeIdents.map((r) => ` ${r},`).join('\n')}\n] as const\n`;
223
+ // Problem flavor of the spec's error responses; pair with decodersFor()
224
+ // from @zodapi/client when creating a client for this contract.
225
+ const flavor = detectProblemFlavor(this.doc);
226
+ const flavorDecl = `export const problemFlavor: 'zodapi' | 'problem-details' | undefined = ${flavor === undefined ? 'undefined' : json(flavor)}\n`;
227
+ const dateCodecDecls = [...this.dateCodecs.entries()].map(([kind, ident]) => {
228
+ const fns = DATE_CODEC_FNS[kind];
229
+ const input = dateCodecInput(kind, this.ctx.dates ?? {});
230
+ return (`export const ${ident} = z.codec(${input}, z.date(), {\n` +
231
+ ` decode: ${fns.decode},\n` +
232
+ ` encode: ${fns.encode},\n` +
233
+ `})\n`);
234
+ });
235
+ return [
236
+ '// Generated by @zodapi/codegen. Do not edit.',
237
+ imports.join('\n'),
238
+ ...(routeDecls.length > 0 ? [routeType] : []),
239
+ ...dateCodecDecls,
240
+ ...componentDecls,
241
+ ...routeDecls,
242
+ routesArray,
243
+ flavorDecl,
244
+ ].join('\n');
245
+ }
246
+ emitRoute(method, path, op, pathItem, out) {
247
+ const operationId = typeof op['operationId'] === 'string' ? op['operationId'] : undefined;
248
+ const ident = this.names.allocate(operationId ?? routeNameFromPath(method, path));
249
+ const lines = [`export const ${ident} = {`];
250
+ lines.push(` method: ${json(method)},`);
251
+ lines.push(` path: ${json(path)},`);
252
+ if (operationId !== undefined) {
253
+ lines.push(` alias: ${json(operationId)},`);
254
+ lines.push(` operationId: ${json(operationId)},`);
255
+ }
256
+ if (typeof op['summary'] === 'string')
257
+ lines.push(` summary: ${json(op['summary'])},`);
258
+ if (typeof op['description'] === 'string') {
259
+ lines.push(` description: ${json(op['description'])},`);
260
+ }
261
+ if (Array.isArray(op['tags']))
262
+ lines.push(` tags: ${json(op['tags'])},`);
263
+ const requestLines = this.requestLines(op, pathItem);
264
+ if (requestLines.length > 0) {
265
+ lines.push(' request: {', ...requestLines, ' },');
266
+ }
267
+ lines.push(' responses: {');
268
+ const responses = isObject(op['responses']) ? op['responses'] : {};
269
+ for (const [status, response] of Object.entries(responses)) {
270
+ if (!isObject(response))
271
+ continue;
272
+ const key = /^[0-9]+$/.test(status) ? status : json(status);
273
+ lines.push(` ${key}: {`);
274
+ if (typeof response['description'] === 'string') {
275
+ lines.push(` description: ${json(response['description'])},`);
276
+ }
277
+ if (isObject(response['content'])) {
278
+ lines.push(...this.contentLines(response['content'], ' '));
279
+ }
280
+ lines.push(' },');
281
+ }
282
+ lines.push(' },');
283
+ lines.push('} as const satisfies GeneratedRoute');
284
+ out.push(`${lines.join('\n')}\n`);
285
+ return ident;
286
+ }
287
+ requestLines(op, pathItem) {
288
+ const lines = [];
289
+ const parameters = [
290
+ ...(Array.isArray(pathItem['parameters']) ? pathItem['parameters'] : []),
291
+ ...(Array.isArray(op['parameters']) ? op['parameters'] : []),
292
+ ].filter((p) => {
293
+ if (!isObject(p))
294
+ return false;
295
+ if (typeof p['$ref'] === 'string')
296
+ throw new Error(`unsupported $ref parameter: ${p['$ref']}`);
297
+ return typeof p['name'] === 'string' && typeof p['in'] === 'string';
298
+ });
299
+ const groups = [
300
+ { key: 'params', in: 'path' },
301
+ { key: 'query', in: 'query' },
302
+ { key: 'headers', in: 'header' },
303
+ { key: 'cookies', in: 'cookie' },
304
+ ];
305
+ for (const group of groups) {
306
+ const members = parameters.filter((p) => p.in === group.in);
307
+ if (members.length === 0)
308
+ continue;
309
+ const entries = members.map((p) => {
310
+ let code = this.parameterExpr(p);
311
+ if (p.required !== true && group.in !== 'path')
312
+ code += '.optional()';
313
+ const name = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(p.name) ? p.name : json(p.name);
314
+ return ` ${name}: ${code},`;
315
+ });
316
+ lines.push(` ${group.key}: z.object({`, ...entries, ' }),');
317
+ }
318
+ const body = op['requestBody'];
319
+ if (isObject(body)) {
320
+ lines.push(' body: {');
321
+ if (typeof body['description'] === 'string') {
322
+ lines.push(` description: ${json(body['description'])},`);
323
+ }
324
+ if (isObject(body['content']))
325
+ lines.push(...this.contentLines(body['content'], ' '));
326
+ if (typeof body['required'] === 'boolean') {
327
+ lines.push(` required: ${body['required']},`);
328
+ }
329
+ lines.push(' },');
330
+ }
331
+ return lines;
332
+ }
333
+ parameterExpr(p) {
334
+ const schema = p.schema ?? {};
335
+ if (p.in === 'query' && isObject(schema) && schema['type'] === 'array') {
336
+ this.usesQueryArray = true;
337
+ const items = schema['items'] === undefined ? 'z.unknown()' : this.expr(schema['items'], ' ');
338
+ const description = typeof p.description === 'string' ? `.meta({ description: ${json(p.description)} })` : '';
339
+ return `queryArray(${items})${description}`;
340
+ }
341
+ let code = this.expr(schema, ' ');
342
+ if (typeof p.description === 'string' && !(isObject(schema) && 'description' in schema)) {
343
+ code = withMeta(code, [`description: ${json(p.description)}`]);
344
+ }
345
+ return code;
346
+ }
347
+ contentLines(content, indent) {
348
+ const lines = [`${indent}content: {`];
349
+ for (const [media, mediaDef] of Object.entries(content)) {
350
+ if (!isObject(mediaDef))
351
+ continue;
352
+ if (mediaDef['schema'] === undefined) {
353
+ lines.push(`${indent} ${json(media)}: {},`);
354
+ }
355
+ else {
356
+ const schema = this.expr(mediaDef['schema'], `${indent} `);
357
+ lines.push(`${indent} ${json(media)}: {`, `${indent} schema: ${schema},`, `${indent} },`);
358
+ }
359
+ }
360
+ lines.push(`${indent}},`);
361
+ return lines;
362
+ }
363
+ expr(schema, indent) {
364
+ return convertSchema(schema, this.ctx, indent).code;
365
+ }
366
+ }
367
+ /**
368
+ * Generate zodapi contract source (zod schemas + `RouteDef` route objects) from
369
+ * a parsed OpenAPI 3.1 document. The result imports only `zod` and
370
+ * `@zodapi/core`, and exports one const per component schema, one per
371
+ * operation, and a `routes` tuple for `createClient(routes)`.
372
+ */
373
+ export function generateContract(doc, options) {
374
+ if (!isObject(doc))
375
+ throw new Error('expected a parsed OpenAPI document object');
376
+ return new Generator(doc, options).generate();
377
+ }
378
+ //# sourceMappingURL=generate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate.js","sourceRoot":"","sources":["../src/generate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { detectProblemFlavor, generateContract, type GenerateOptions, type ProblemFlavor, } from './generate.js';
2
+ export { convertSchema, type ConvertContext, type DateCodecKind, type DatesOptions, type Expr, type JsonSchema, } from './schema-to-zod.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,gBAAgB,EAChB,KAAK,eAAe,EACpB,KAAK,aAAa,GACnB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,aAAa,EACb,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,IAAI,EACT,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export { detectProblemFlavor, generateContract, } from './generate.js';
2
+ export { convertSchema, } from './schema-to-zod.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,gBAAgB,GAGjB,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,aAAa,GAMd,MAAM,oBAAoB,CAAA"}
@@ -0,0 +1,10 @@
1
+ /** Allocates unique, valid TS identifiers, remembering the mapping from original names. */
2
+ export declare class NameAllocator {
3
+ private readonly used;
4
+ private readonly byOriginal;
5
+ allocate(original: string, preferred?: string): string;
6
+ lookup(original: string): string | undefined;
7
+ }
8
+ /** `get` + '/things/{id}' → 'getThingsId' — fallback route name when there is no operationId. */
9
+ export declare function routeNameFromPath(method: string, path: string): string;
10
+ //# sourceMappingURL=names.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.d.ts","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"AAwDA,2FAA2F;AAC3F,qBAAa,aAAa;IACxB,OAAO,CAAC,QAAQ,CAAC,IAAI,CAA4B;IACjD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA4B;IAEvD,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,SAAW,GAAG,MAAM,CAWvD;IAED,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAE3C;CACF;AAED,iGAAiG;AACjG,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtE"}
package/dist/names.js ADDED
@@ -0,0 +1,86 @@
1
+ const RESERVED = new Set([
2
+ // generated-file imports and exports
3
+ 'z',
4
+ 'RouteDef',
5
+ 'GeneratedRoute',
6
+ 'queryArray',
7
+ 'routes',
8
+ // JS reserved words that survive sanitization
9
+ 'break',
10
+ 'case',
11
+ 'catch',
12
+ 'class',
13
+ 'const',
14
+ 'continue',
15
+ 'debugger',
16
+ 'default',
17
+ 'delete',
18
+ 'do',
19
+ 'else',
20
+ 'enum',
21
+ 'export',
22
+ 'extends',
23
+ 'false',
24
+ 'finally',
25
+ 'for',
26
+ 'function',
27
+ 'if',
28
+ 'import',
29
+ 'in',
30
+ 'instanceof',
31
+ 'new',
32
+ 'null',
33
+ 'return',
34
+ 'super',
35
+ 'switch',
36
+ 'this',
37
+ 'throw',
38
+ 'true',
39
+ 'try',
40
+ 'typeof',
41
+ 'var',
42
+ 'void',
43
+ 'while',
44
+ 'with',
45
+ 'yield',
46
+ 'let',
47
+ 'static',
48
+ 'await',
49
+ ]);
50
+ function sanitize(name) {
51
+ const cleaned = name.replace(/[^A-Za-z0-9_$]/g, '_');
52
+ const prefixed = /^[0-9]/.test(cleaned) ? `_${cleaned}` : cleaned;
53
+ return prefixed === '' ? '_' : prefixed;
54
+ }
55
+ /** Allocates unique, valid TS identifiers, remembering the mapping from original names. */
56
+ export class NameAllocator {
57
+ used = new Set(RESERVED);
58
+ byOriginal = new Map();
59
+ allocate(original, preferred = original) {
60
+ const existing = this.byOriginal.get(original);
61
+ if (existing !== undefined)
62
+ return existing;
63
+ const base = sanitize(preferred);
64
+ let candidate = base;
65
+ for (let i = 2; this.used.has(candidate); i++) {
66
+ candidate = `${base}${i}`;
67
+ }
68
+ this.used.add(candidate);
69
+ this.byOriginal.set(original, candidate);
70
+ return candidate;
71
+ }
72
+ lookup(original) {
73
+ return this.byOriginal.get(original);
74
+ }
75
+ }
76
+ /** `get` + '/things/{id}' → 'getThingsId' — fallback route name when there is no operationId. */
77
+ export function routeNameFromPath(method, path) {
78
+ const segments = path
79
+ .split('/')
80
+ .map((s) => s.replace(/[{}]/g, ''))
81
+ .flatMap((s) => s.split(/[^A-Za-z0-9]+/))
82
+ .filter(Boolean);
83
+ const camel = segments.map((s) => s.charAt(0).toUpperCase() + s.slice(1)).join('');
84
+ return `${method}${camel || 'Root'}`;
85
+ }
86
+ //# sourceMappingURL=names.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"names.js","sourceRoot":"","sources":["../src/names.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Converts an OpenAPI 3.1 (JSON Schema) subschema into zod source code.
3
+ *
4
+ * Coverage is deliberately the subset zod itself can express and re-serialize
5
+ * via `z.toJSONSchema` — the round-trip test in this package is the contract:
6
+ * fixture zod → OpenAPI → this converter → zod → OpenAPI must be identical.
7
+ */
8
+ export type JsonSchema = Record<string, unknown>;
9
+ /** Convert ISO date/time strings to `Date` objects via bidirectional `z.codec`s. */
10
+ export interface DatesOptions {
11
+ /** `format: date-time` → `z.codec(z.iso.datetime(), z.date(), ...)`. */
12
+ datetime?: boolean;
13
+ /** `format: date` → a codec decoding to `Date` at UTC midnight. */
14
+ date?: boolean;
15
+ /** Accept UTC offsets in date-time values (`z.iso.datetime({ offset: true })`). */
16
+ offset?: boolean;
17
+ }
18
+ export type DateCodecKind = 'datetime' | 'date';
19
+ export interface ConvertContext {
20
+ /** Resolve a `$ref` to a generated identifier; `forward` when the target is not yet declared. */
21
+ resolveRef(ref: string): {
22
+ ident: string;
23
+ forward: boolean;
24
+ };
25
+ /** Resolve a `$ref` to its raw component schema, for structural checks; `undefined` when unknown. */
26
+ resolveComponentSchema(ref: string): JsonSchema | undefined;
27
+ /** Date-codec conversion options; absent → ISO strings stay strings. */
28
+ dates?: DatesOptions | undefined;
29
+ /** Identifier of the shared date codec for `kind`, registering it as used. */
30
+ dateCodec?: ((kind: DateCodecKind) => string) | undefined;
31
+ }
32
+ /** A zod expression plus whether it references an identifier declared later in the file. */
33
+ export interface Expr {
34
+ code: string;
35
+ forward: boolean;
36
+ /** Set when the schema's `default` was folded into the expression already. */
37
+ defaultHandled?: boolean;
38
+ }
39
+ /** The input-side (wire) schema of a date codec. */
40
+ export declare function dateCodecInput(kind: DateCodecKind, dates: DatesOptions): string;
41
+ /** decode/encode function source for each date codec kind. */
42
+ export declare const DATE_CODEC_FNS: Record<DateCodecKind, {
43
+ decode: string;
44
+ encode: string;
45
+ }>;
46
+ export declare function convertSchema(schema: unknown, ctx: ConvertContext, indent?: string): Expr;
47
+ //# sourceMappingURL=schema-to-zod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-to-zod.d.ts","sourceRoot":"","sources":["../src/schema-to-zod.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;AAEhD,oFAAoF;AACpF,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mEAAmE;IACnE,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,mFAAmF;IACnF,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,MAAM,CAAA;AAE/C,MAAM,WAAW,cAAc;IAC7B,iGAAiG;IACjG,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;IAC5D,qGAAqG;IACrG,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CAAA;IAC3D,wEAAwE;IACxE,KAAK,CAAC,EAAE,YAAY,GAAG,SAAS,CAAA;IAChC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,CAAC,CAAC,IAAI,EAAE,aAAa,KAAK,MAAM,CAAC,GAAG,SAAS,CAAA;CAC1D;AAED,4FAA4F;AAC5F,MAAM,WAAW,IAAI;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,OAAO,CAAA;IAChB,8EAA8E;IAC9E,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AA2BD,oDAAoD;AACpD,wBAAgB,cAAc,CAAC,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,YAAY,GAAG,MAAM,CAI/E;AAED,8DAA8D;AAC9D,eAAO,MAAM,cAAc,EAAE,MAAM,CAAC,aAAa,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CASpF,CAAA;AAmSD,wBAAgB,aAAa,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,MAAM,SAAK,GAAG,IAAI,CASrF"}
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Converts an OpenAPI 3.1 (JSON Schema) subschema into zod source code.
3
+ *
4
+ * Coverage is deliberately the subset zod itself can express and re-serialize
5
+ * via `z.toJSONSchema` — the round-trip test in this package is the contract:
6
+ * fixture zod → OpenAPI → this converter → zod → OpenAPI must be identical.
7
+ */
8
+ function lit(code) {
9
+ return { code, forward: false };
10
+ }
11
+ function isSchemaObject(s) {
12
+ return typeof s === 'object' && s !== null && !Array.isArray(s);
13
+ }
14
+ function json(value) {
15
+ return JSON.stringify(value);
16
+ }
17
+ const STRING_FORMATS = {
18
+ email: 'z.email()',
19
+ uuid: 'z.uuid()',
20
+ url: 'z.url()',
21
+ uri: 'z.url()',
22
+ 'date-time': 'z.iso.datetime()',
23
+ date: 'z.iso.date()',
24
+ time: 'z.iso.time()',
25
+ duration: 'z.iso.duration()',
26
+ ipv4: 'z.ipv4()',
27
+ ipv6: 'z.ipv6()',
28
+ };
29
+ /** The input-side (wire) schema of a date codec. */
30
+ export function dateCodecInput(kind, dates) {
31
+ return kind === 'datetime'
32
+ ? `z.iso.datetime(${dates.offset ? '{ offset: true }' : ''})`
33
+ : 'z.iso.date()';
34
+ }
35
+ /** decode/encode function source for each date codec kind. */
36
+ export const DATE_CODEC_FNS = {
37
+ datetime: {
38
+ decode: '(value) => new Date(value)',
39
+ encode: '(date) => date.toISOString()',
40
+ },
41
+ date: {
42
+ decode: '(value) => new Date(`${value}T00:00:00Z`)',
43
+ encode: '(date) => date.toISOString().slice(0, 10)',
44
+ },
45
+ };
46
+ function dateCodecExpr(kind, input) {
47
+ const fns = DATE_CODEC_FNS[kind];
48
+ return `z.codec(${input}, z.date(), { decode: ${fns.decode}, encode: ${fns.encode} })`;
49
+ }
50
+ function stringExpr(schema, ctx) {
51
+ const format = typeof schema['format'] === 'string' ? schema['format'] : undefined;
52
+ const kind = format === 'date-time' && ctx.dates?.datetime === true
53
+ ? 'datetime'
54
+ : format === 'date' && ctx.dates?.date === true
55
+ ? 'date'
56
+ : undefined;
57
+ if (kind !== undefined && ctx.dateCodec !== undefined) {
58
+ // Constraints and `default` belong to the codec's input (wire) side; the
59
+ // shared helper covers the bare case, anything else inlines the codec.
60
+ const bare = dateCodecInput(kind, ctx.dates ?? {});
61
+ let input = bare;
62
+ if (typeof schema['minLength'] === 'number')
63
+ input += `.min(${schema['minLength']})`;
64
+ if (typeof schema['maxLength'] === 'number')
65
+ input += `.max(${schema['maxLength']})`;
66
+ let defaultHandled = false;
67
+ if ('default' in schema) {
68
+ input += `.default(${json(schema['default'])})`;
69
+ defaultHandled = true;
70
+ }
71
+ if (input === bare)
72
+ return { code: ctx.dateCodec(kind), forward: false };
73
+ return { code: dateCodecExpr(kind, input), forward: false, defaultHandled };
74
+ }
75
+ let code = (format !== undefined && STRING_FORMATS[format]) || 'z.string()';
76
+ if (typeof schema['minLength'] === 'number')
77
+ code += `.min(${schema['minLength']})`;
78
+ if (typeof schema['maxLength'] === 'number')
79
+ code += `.max(${schema['maxLength']})`;
80
+ if (typeof schema['pattern'] === 'string' && (format === undefined || !STRING_FORMATS[format])) {
81
+ code += `.regex(new RegExp(${json(schema['pattern'])}))`;
82
+ }
83
+ return lit(code);
84
+ }
85
+ function numberExpr(schema, integer) {
86
+ let code = integer ? 'z.int()' : 'z.number()';
87
+ if (typeof schema['minimum'] === 'number')
88
+ code += `.min(${schema['minimum']})`;
89
+ if (typeof schema['maximum'] === 'number')
90
+ code += `.max(${schema['maximum']})`;
91
+ if (typeof schema['exclusiveMinimum'] === 'number')
92
+ code += `.gt(${schema['exclusiveMinimum']})`;
93
+ if (typeof schema['exclusiveMaximum'] === 'number')
94
+ code += `.lt(${schema['exclusiveMaximum']})`;
95
+ if (typeof schema['multipleOf'] === 'number')
96
+ code += `.multipleOf(${schema['multipleOf']})`;
97
+ return code;
98
+ }
99
+ function enumExpr(values) {
100
+ if (values.length > 0 && values.every((v) => typeof v === 'string')) {
101
+ return `z.enum([${values.map(json).join(', ')}])`;
102
+ }
103
+ if (values.length === 1)
104
+ return `z.literal(${json(values[0])})`;
105
+ return `z.union([${values.map((v) => `z.literal(${json(v)})`).join(', ')}])`;
106
+ }
107
+ function objectExpr(schema, ctx, indent) {
108
+ const properties = isSchemaObject(schema['properties']) ? schema['properties'] : undefined;
109
+ const required = new Set(Array.isArray(schema['required']) ? schema['required'] : []);
110
+ const additional = schema['additionalProperties'];
111
+ // A pure map type: no declared properties, values constrained by additionalProperties.
112
+ if (properties === undefined && isSchemaObject(additional)) {
113
+ const value = convertSchema(additional, ctx, indent);
114
+ return { code: `z.record(z.string(), ${value.code})`, forward: value.forward };
115
+ }
116
+ const inner = `${indent} `;
117
+ const entries = [];
118
+ let forward = false;
119
+ for (const [key, propSchema] of Object.entries(properties ?? {})) {
120
+ const prop = convertSchema(propSchema, ctx, inner);
121
+ const withOptional = required.has(key) ? prop.code : `${prop.code}.optional()`;
122
+ const name = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : json(key);
123
+ // Forward references must be deferred; zod object shapes support getters for this.
124
+ entries.push(prop.forward
125
+ ? `${inner}get ${name}() {\n${inner} return ${withOptional}\n${inner}},`
126
+ : `${inner}${name}: ${withOptional},`);
127
+ forward ||= prop.forward;
128
+ }
129
+ const shape = entries.length === 0 ? '{}' : `{\n${entries.join('\n')}\n${indent}}`;
130
+ let code;
131
+ if (additional === true || (isSchemaObject(additional) && Object.keys(additional).length === 0)) {
132
+ code = `z.looseObject(${shape})`;
133
+ }
134
+ else if (isSchemaObject(additional)) {
135
+ const catchall = convertSchema(additional, ctx, indent);
136
+ forward ||= catchall.forward;
137
+ code = `z.object(${shape}).catchall(${catchall.code})`;
138
+ }
139
+ else {
140
+ code = `z.object(${shape})`;
141
+ }
142
+ return { code, forward };
143
+ }
144
+ function arrayExpr(schema, ctx, indent) {
145
+ const prefixItems = schema['prefixItems'];
146
+ if (Array.isArray(prefixItems)) {
147
+ const members = prefixItems.map((m) => convertSchema(m, ctx, indent));
148
+ const rest = isSchemaObject(schema['items'])
149
+ ? convertSchema(schema['items'], ctx, indent)
150
+ : undefined;
151
+ const args = `[${members.map((m) => m.code).join(', ')}]${rest ? `, ${rest.code}` : ''}`;
152
+ return {
153
+ code: `z.tuple(${args})`,
154
+ forward: members.some((m) => m.forward) || (rest?.forward ?? false),
155
+ };
156
+ }
157
+ const items = schema['items'] === undefined ? lit('z.unknown()') : convertSchema(schema['items'], ctx, indent);
158
+ let code = `z.array(${items.code})`;
159
+ if (typeof schema['minItems'] === 'number')
160
+ code += `.min(${schema['minItems']})`;
161
+ if (typeof schema['maxItems'] === 'number')
162
+ code += `.max(${schema['maxItems']})`;
163
+ return { code, forward: items.forward };
164
+ }
165
+ function unionExpr(members, ctx, indent) {
166
+ // X | null → X.nullable()
167
+ if (members.length === 2) {
168
+ const nullIdx = members.findIndex((m) => isSchemaObject(m) && m['type'] === 'null');
169
+ if (nullIdx !== -1) {
170
+ const other = convertSchema(members[1 - nullIdx], ctx, indent);
171
+ return { code: `${other.code}.nullable()`, forward: other.forward };
172
+ }
173
+ }
174
+ const exprs = members.map((m) => convertSchema(m, ctx, indent));
175
+ return {
176
+ code: `z.union([${exprs.map((e) => e.code).join(', ')}])`,
177
+ forward: exprs.some((e) => e.forward),
178
+ };
179
+ }
180
+ /** The string values `properties[propertyName]` pins a member to, or `undefined` if unusable. */
181
+ function discriminatorValues(component, propertyName) {
182
+ const properties = isSchemaObject(component['properties']) ? component['properties'] : undefined;
183
+ const property = properties?.[propertyName];
184
+ if (!isSchemaObject(property))
185
+ return undefined;
186
+ if (typeof property['const'] === 'string')
187
+ return [property['const']];
188
+ const values = property['enum'];
189
+ if (Array.isArray(values) && values.length > 0 && values.every((v) => typeof v === 'string')) {
190
+ return values;
191
+ }
192
+ return undefined;
193
+ }
194
+ /**
195
+ * `oneOf`/`anyOf` with a `discriminator` → `z.discriminatedUnion(...)`, or `undefined` to fall
196
+ * back to a plain union. zod validates lazily at parse time, so a member the guards cannot prove
197
+ * safe (non-`$ref`, forward reference, or no `const`/string-enum discriminator property) would
198
+ * make the generated contract throw in userland — fall back instead. A `{type: "null"}` member is
199
+ * excluded from the union and restored with `.nullable()`.
200
+ */
201
+ function discriminatedUnionExpr(schema, members, ctx) {
202
+ const discriminator = schema['discriminator'];
203
+ if (!isSchemaObject(discriminator))
204
+ return undefined;
205
+ const propertyName = discriminator['propertyName'];
206
+ if (typeof propertyName !== 'string')
207
+ return undefined;
208
+ const refs = [];
209
+ let nullable = false;
210
+ for (const member of members) {
211
+ if (!isSchemaObject(member))
212
+ return undefined;
213
+ if (member['type'] === 'null') {
214
+ nullable = true;
215
+ continue;
216
+ }
217
+ if (typeof member['$ref'] !== 'string' || Object.keys(member).length !== 1)
218
+ return undefined;
219
+ refs.push(member['$ref']);
220
+ }
221
+ if (refs.length < 2)
222
+ return undefined;
223
+ const idents = [];
224
+ const valuesByRef = new Map();
225
+ for (const ref of refs) {
226
+ const component = ctx.resolveComponentSchema(ref);
227
+ if (component === undefined)
228
+ return undefined;
229
+ const values = discriminatorValues(component, propertyName);
230
+ if (values === undefined)
231
+ return undefined;
232
+ const { ident, forward } = ctx.resolveRef(ref);
233
+ if (forward)
234
+ return undefined;
235
+ idents.push(ident);
236
+ valuesByRef.set(ref, values);
237
+ }
238
+ // `mapping` is redundant (zod reads the values off each member) but when present it must agree
239
+ // with the members: every entry must target a member whose discriminator values include the key.
240
+ const mapping = discriminator['mapping'];
241
+ if (mapping !== undefined) {
242
+ if (!isSchemaObject(mapping))
243
+ return undefined;
244
+ for (const [value, target] of Object.entries(mapping)) {
245
+ if (typeof target !== 'string')
246
+ return undefined;
247
+ // Mapping values may be a full `$ref` or a bare component name.
248
+ const ref = refs.find((r) => r === target || r.endsWith(`/${target}`));
249
+ if (ref === undefined || !valuesByRef.get(ref)?.includes(value))
250
+ return undefined;
251
+ }
252
+ }
253
+ let code = `z.discriminatedUnion(${json(propertyName)}, [${idents.join(', ')}])`;
254
+ if (nullable)
255
+ code += '.nullable()';
256
+ return { code, forward: false };
257
+ }
258
+ function baseExpr(schema, ctx, indent) {
259
+ const ref = schema['$ref'];
260
+ if (typeof ref === 'string') {
261
+ const { ident, forward } = ctx.resolveRef(ref);
262
+ return { code: ident, forward };
263
+ }
264
+ if ('const' in schema)
265
+ return lit(`z.literal(${json(schema['const'])})`);
266
+ if (Array.isArray(schema['enum']))
267
+ return lit(enumExpr(schema['enum']));
268
+ const anyOf = schema['anyOf'] ?? schema['oneOf'];
269
+ if (Array.isArray(anyOf)) {
270
+ return discriminatedUnionExpr(schema, anyOf, ctx) ?? unionExpr(anyOf, ctx, indent);
271
+ }
272
+ if (Array.isArray(schema['allOf'])) {
273
+ const members = schema['allOf'].map((m) => convertSchema(m, ctx, indent));
274
+ const code = members
275
+ .map((m) => m.code)
276
+ .reduce((acc, next) => (acc === '' ? next : `z.intersection(${acc}, ${next})`), '');
277
+ return { code: code || 'z.unknown()', forward: members.some((m) => m.forward) };
278
+ }
279
+ const type = schema['type'];
280
+ if (Array.isArray(type)) {
281
+ if (type.length === 2 && type.includes('null')) {
282
+ const other = baseExpr({ ...schema, type: type.find((t) => t !== 'null') }, ctx, indent);
283
+ return {
284
+ code: `${other.code}.nullable()`,
285
+ forward: other.forward,
286
+ ...(other.defaultHandled !== undefined && { defaultHandled: other.defaultHandled }),
287
+ };
288
+ }
289
+ return unionExpr(type.map((t) => ({ ...schema, type: t })), ctx, indent);
290
+ }
291
+ switch (type) {
292
+ case 'string':
293
+ return stringExpr(schema, ctx);
294
+ case 'number':
295
+ return lit(numberExpr(schema, false));
296
+ case 'integer':
297
+ return lit(numberExpr(schema, true));
298
+ case 'boolean':
299
+ return lit('z.boolean()');
300
+ case 'null':
301
+ return lit('z.null()');
302
+ case 'object':
303
+ return objectExpr(schema, ctx, indent);
304
+ case 'array':
305
+ return arrayExpr(schema, ctx, indent);
306
+ case undefined:
307
+ // Untyped but with object/array keywords still convert structurally.
308
+ if ('properties' in schema || 'additionalProperties' in schema) {
309
+ return objectExpr(schema, ctx, indent);
310
+ }
311
+ if ('items' in schema || 'prefixItems' in schema)
312
+ return arrayExpr(schema, ctx, indent);
313
+ return lit('z.unknown()');
314
+ default:
315
+ throw new Error(`unsupported schema type: ${json(type)}`);
316
+ }
317
+ }
318
+ /** Metadata keywords carried through `.meta()` / `.default()` rather than validation. */
319
+ function metaSuffix(schema, skipDefault) {
320
+ let code = '';
321
+ if (!skipDefault && 'default' in schema)
322
+ code += `.default(${json(schema['default'])})`;
323
+ const meta = [];
324
+ if (typeof schema['title'] === 'string')
325
+ meta.push(`title: ${json(schema['title'])}`);
326
+ if (typeof schema['description'] === 'string') {
327
+ meta.push(`description: ${json(schema['description'])}`);
328
+ }
329
+ if (Array.isArray(schema['examples']))
330
+ meta.push(`examples: ${json(schema['examples'])}`);
331
+ if (schema['deprecated'] === true)
332
+ meta.push('deprecated: true');
333
+ if (meta.length > 0)
334
+ code += `.meta({ ${meta.join(', ')} })`;
335
+ return code;
336
+ }
337
+ export function convertSchema(schema, ctx, indent = '') {
338
+ if (schema === true)
339
+ return lit('z.unknown()');
340
+ if (schema === false)
341
+ return lit('z.never()');
342
+ if (!isSchemaObject(schema))
343
+ throw new Error(`expected a schema object, got ${json(schema)}`);
344
+ const base = baseExpr(schema, ctx, indent);
345
+ return {
346
+ code: base.code + metaSuffix(schema, base.defaultHandled === true),
347
+ forward: base.forward,
348
+ };
349
+ }
350
+ //# sourceMappingURL=schema-to-zod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-to-zod.js","sourceRoot":"","sources":["../src/schema-to-zod.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,36 @@
1
+ {
2
+ "name": "@zodapi/codegen",
3
+ "version": "0.2.0",
4
+ "description": "Generate a zodapi contract (zod schemas + route defs) from an OpenAPI 3.1 document",
5
+ "license": "MIT",
6
+ "bin": {
7
+ "zodapi-codegen": "./dist/cli.js"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "type": "module",
13
+ "sideEffects": false,
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
22
+ "devDependencies": {
23
+ "@hono/zod-openapi": "^1.6.1",
24
+ "@types/node": "^26.4.0",
25
+ "@zodapi/core": "0.2.0",
26
+ "@zodapi/hono": "0.2.0",
27
+ "hono": "^4.13.5",
28
+ "tsx": "^4.23.12",
29
+ "zod": "^4.4.3"
30
+ },
31
+ "scripts": {
32
+ "build": "tsc -p tsconfig.build.json",
33
+ "typecheck": "tsc --noEmit",
34
+ "generate:fixture": "tsx scripts/generate-fixture.ts"
35
+ }
36
+ }