zod-openapi 5.0.0-beta.15 → 5.0.0-beta.17
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/README.md +108 -48
- package/dist/api.d.mts +1 -1
- package/dist/api.d.ts +1 -1
- package/dist/api.js +1 -1
- package/dist/api.mjs +1 -1
- package/dist/{components-CtyiAwVj.mjs → components-CncTLZvX.mjs} +11 -9
- package/dist/{components-DNTDGqgA.js → components-D4JjPRqN.js} +11 -9
- package/dist/{components-Ck7iRc2n.d.mts → components-Ds_qyBU9.d.ts} +13 -5
- package/dist/{components-DLKlRo1M.d.ts → components-uNe8arnt.d.mts} +13 -5
- package/dist/index.d.mts +4 -2
- package/dist/index.d.ts +4 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<h1 align="center">zod-openapi</h1>
|
|
4
4
|
</p>
|
|
5
5
|
<p align="center">
|
|
6
|
-
A TypeScript library which uses <a href="https://github.com/colinhacks/zod">Zod</a> schemas to generate OpenAPI v3.
|
|
6
|
+
A TypeScript library which uses <a href="https://github.com/colinhacks/zod">Zod</a> schemas to generate OpenAPI v3.1x documentation.
|
|
7
7
|
</p>
|
|
8
8
|
<div align="center">
|
|
9
9
|
<a href="https://www.npmjs.com/package/zod-openapi"><img src="https://img.shields.io/npm/v/zod-openapi"/></a>
|
|
@@ -31,33 +31,41 @@ pnpm install zod zod-openapi
|
|
|
31
31
|
|
|
32
32
|
### `.meta()`
|
|
33
33
|
|
|
34
|
-
Use the `.meta()` method to add metadata to a Zod schema. It accepts an object with the following options:
|
|
34
|
+
Use the `.meta()` method to add OpenAPI metadata to a Zod schema. It accepts an object with the following options:
|
|
35
35
|
|
|
36
36
|
| Option | Description |
|
|
37
37
|
| ---------- | ---------------------------------------------------------------------------------------------------------------- |
|
|
38
38
|
| `id` | Registers a schema as a reusable OpenAPI component. |
|
|
39
39
|
| `header` | Adds metadata for [response headers](#response-headers). |
|
|
40
40
|
| `param` | Adds metadata for [request parameters](#parameters). |
|
|
41
|
-
| `override` | Allows you to override the rendered OpenAPI schema. This takes either an object or a function
|
|
41
|
+
| `override` | Allows you to override the rendered OpenAPI schema. This takes either an object or a function. |
|
|
42
42
|
| `outputId` | Allows you to set a different ID for the output schema. This is useful when the input and output schemas differ. |
|
|
43
|
-
| `unusedIO` | Allows you to set the `io` for an unused schema added to the components section. Defaults to `output
|
|
43
|
+
| `unusedIO` | Allows you to set the `io` for an unused schema added to the components section. Defaults to `output`. |
|
|
44
|
+
|
|
45
|
+
You can also set standard OpenAPI properties directly in the `.meta()` method, such as:
|
|
46
|
+
|
|
47
|
+
```typescript
|
|
48
|
+
z.string().meta({
|
|
49
|
+
description: 'A text field',
|
|
50
|
+
example: 'Example value',
|
|
51
|
+
});
|
|
52
|
+
```
|
|
44
53
|
|
|
45
54
|
### `createDocument`
|
|
46
55
|
|
|
47
56
|
Generates an OpenAPI documentation object.
|
|
48
57
|
|
|
49
58
|
```typescript
|
|
50
|
-
import 'zod
|
|
51
|
-
import { z } from 'zod/v4';
|
|
59
|
+
import { z } from 'zod';
|
|
52
60
|
import { createDocument } from 'zod-openapi';
|
|
53
61
|
|
|
54
|
-
const jobId = z.string().
|
|
62
|
+
const jobId = z.string().meta({
|
|
55
63
|
description: 'A unique identifier for a job',
|
|
56
64
|
example: '12345',
|
|
57
65
|
id: 'jobId',
|
|
58
66
|
});
|
|
59
67
|
|
|
60
|
-
const title = z.string().
|
|
68
|
+
const title = z.string().meta({
|
|
61
69
|
description: 'Job title',
|
|
62
70
|
example: 'My job',
|
|
63
71
|
});
|
|
@@ -170,37 +178,45 @@ const document = createDocument({
|
|
|
170
178
|
```
|
|
171
179
|
</details>
|
|
172
180
|
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
`createDocument` takes an optional `CreateDocumentOptions` argument which can be used to modify how the document is created.
|
|
181
|
+
`createDocument` takes an optional options argument which can be used to modify how the document is created
|
|
176
182
|
|
|
177
183
|
```typescript
|
|
178
|
-
|
|
179
|
-
override: ({ jsonSchema, zodSchema }) => {
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
184
|
+
createDocument(doc, {
|
|
185
|
+
override: ({ jsonSchema, zodSchema, io }) => {
|
|
186
|
+
// Customize the schema generation
|
|
187
|
+
if (io === 'output') {
|
|
188
|
+
jsonSchema.type = 'string';
|
|
183
189
|
}
|
|
184
190
|
},
|
|
185
191
|
});
|
|
186
192
|
```
|
|
187
193
|
|
|
194
|
+
#### CreateDocumentOptions
|
|
195
|
+
|
|
196
|
+
| Option | Type | Default | Description |
|
|
197
|
+
| ------------------ | ------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------- |
|
|
198
|
+
| `override` | `Function` | `undefined` | Override rendered schema with a function`` |
|
|
199
|
+
| `outputIdSuffix` | `string` | `'Output'` | Suffix for output schema IDs when the schema is used in both a request and response |
|
|
200
|
+
| `allowEmptySchema` | `boolean \| Object` | `false` | Control whether empty schemas are allowed. |
|
|
201
|
+
| `cycles` | `'ref' \| 'throw'` | `'ref'` | How to handle cycles in schemas.<br>- `'ref'` — Break cycles using $defs<br>- `'throw'` — Error on cycles |
|
|
202
|
+
| `reused` | `'ref' \| 'inline'` | `'inline'` | How to handle reused schemas.<br>- `'ref'` — Reused schemas as references<br>- `'inline'` — Inline reused schemas |
|
|
203
|
+
| `schemaRefPath` | `string` | `'#/components/schemas/'` | Path prefix for schema references. Used when generating $ref values. |
|
|
204
|
+
|
|
188
205
|
### `createSchema`
|
|
189
206
|
|
|
190
207
|
Creates an OpenAPI Schema Object along with any registered components. OpenAPI 3.1.0 Schema Objects are fully compatible with JSON Schema.
|
|
191
208
|
|
|
192
209
|
```typescript
|
|
193
|
-
import 'zod
|
|
194
|
-
import { z } from 'zod/v4';
|
|
210
|
+
import { z } from 'zod';
|
|
195
211
|
import { createSchema } from 'zod-openapi';
|
|
196
212
|
|
|
197
|
-
const jobId = z.string().
|
|
213
|
+
const jobId = z.string().meta({
|
|
198
214
|
description: 'A unique identifier for a job',
|
|
199
215
|
example: '12345',
|
|
200
216
|
id: 'jobId',
|
|
201
217
|
});
|
|
202
218
|
|
|
203
|
-
const title = z.string().
|
|
219
|
+
const title = z.string().meta({
|
|
204
220
|
description: 'Job title',
|
|
205
221
|
example: 'My job',
|
|
206
222
|
});
|
|
@@ -245,16 +261,17 @@ const { schema, components } = createSchema(job);
|
|
|
245
261
|
|
|
246
262
|
#### CreateSchemaOptions
|
|
247
263
|
|
|
248
|
-
`createSchema` takes an optional `CreateSchemaOptions` parameter which
|
|
264
|
+
`createSchema` takes an optional `CreateSchemaOptions` parameter which includes all options from [CreateDocumentOptions](#createdocumentoptions) plus the following:
|
|
249
265
|
|
|
250
|
-
|
|
266
|
+
````typescript
|
|
251
267
|
const { schema, components } = createSchema(job, {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
}
|
|
257
|
-
|
|
268
|
+
// Input/Output context - controls how schemas are generated
|
|
269
|
+
io: 'input', // 'input' for request bodies/params, 'output' for responses
|
|
270
|
+
|
|
271
|
+
// Component handling
|
|
272
|
+
schemaComponents: { jobId: z.string() }, // Pre-defined components to use
|
|
273
|
+
schemaComponentRefPath: '#/definitions/', // Custom path prefix for component references
|
|
274
|
+
});
|
|
258
275
|
|
|
259
276
|
### Request Parameters
|
|
260
277
|
|
|
@@ -275,7 +292,7 @@ createDocument({
|
|
|
275
292
|
},
|
|
276
293
|
},
|
|
277
294
|
});
|
|
278
|
-
|
|
295
|
+
````
|
|
279
296
|
|
|
280
297
|
If you would like to declare parameters in a more traditional way you may also declare them using the [parameters](https://swagger.io/docs/specification/describing-parameters/) key. The definitions will then all be combined.
|
|
281
298
|
|
|
@@ -285,7 +302,7 @@ createDocument({
|
|
|
285
302
|
'/jobs/{a}': {
|
|
286
303
|
put: {
|
|
287
304
|
parameters: [
|
|
288
|
-
z.string().
|
|
305
|
+
z.string().meta({
|
|
289
306
|
param: {
|
|
290
307
|
name: 'job-header',
|
|
291
308
|
in: 'header',
|
|
@@ -396,7 +413,7 @@ If we take the example in `createDocument` and instead create `title` as follows
|
|
|
396
413
|
##### Auto Registering Schema
|
|
397
414
|
|
|
398
415
|
```typescript
|
|
399
|
-
const title = z.string().
|
|
416
|
+
const title = z.string().meta({
|
|
400
417
|
description: 'Job title',
|
|
401
418
|
example: 'My job',
|
|
402
419
|
id: 'jobTitle', // <- new field
|
|
@@ -434,14 +451,14 @@ Another way to register schema instead of adding a `ref` is to add it to the com
|
|
|
434
451
|
eg.
|
|
435
452
|
|
|
436
453
|
```typescript
|
|
437
|
-
const title = z.string().
|
|
454
|
+
const title = z.string().meta({
|
|
438
455
|
description: 'Job title',
|
|
439
456
|
example: 'My job',
|
|
440
457
|
});
|
|
441
458
|
createDocument({
|
|
442
459
|
components: {
|
|
443
460
|
schemas: {
|
|
444
|
-
jobTitle: title, // this will register this Zod Schema as jobTitle unless `
|
|
461
|
+
jobTitle: title, // this will register this Zod Schema as jobTitle unless `id` in `.meta()` is specified on the type
|
|
445
462
|
},
|
|
446
463
|
},
|
|
447
464
|
});
|
|
@@ -453,7 +470,7 @@ Query, Path, Header & Cookie parameters can be similarly registered:
|
|
|
453
470
|
|
|
454
471
|
```typescript
|
|
455
472
|
// Easy auto registration
|
|
456
|
-
const jobId = z.string().
|
|
473
|
+
const jobId = z.string().meta({
|
|
457
474
|
description: 'Job ID',
|
|
458
475
|
example: '1234',
|
|
459
476
|
param: { id: 'jobRef' },
|
|
@@ -474,7 +491,7 @@ createDocument({
|
|
|
474
491
|
});
|
|
475
492
|
|
|
476
493
|
// or more verbose auto registration
|
|
477
|
-
const jobId = z.string().
|
|
494
|
+
const jobId = z.string().meta({
|
|
478
495
|
description: 'Job ID',
|
|
479
496
|
example: '1234',
|
|
480
497
|
param: { in: 'header', name: 'jobId', id: 'jobRef' },
|
|
@@ -490,8 +507,8 @@ createDocument({
|
|
|
490
507
|
},
|
|
491
508
|
});
|
|
492
509
|
|
|
493
|
-
// or manual
|
|
494
|
-
const otherJobId = z.string().
|
|
510
|
+
// or manual registration
|
|
511
|
+
const otherJobId = z.string().meta({
|
|
495
512
|
description: 'Job ID',
|
|
496
513
|
example: '1234',
|
|
497
514
|
param: { in: 'header', name: 'jobId' },
|
|
@@ -511,7 +528,7 @@ createDocument({
|
|
|
511
528
|
Response headers can be similarly registered:
|
|
512
529
|
|
|
513
530
|
```typescript
|
|
514
|
-
const header = z.string().
|
|
531
|
+
const header = z.string().meta({
|
|
515
532
|
description: 'Job ID',
|
|
516
533
|
example: '1234',
|
|
517
534
|
header: { id: 'some-header' },
|
|
@@ -519,7 +536,7 @@ const header = z.string().openapi({
|
|
|
519
536
|
|
|
520
537
|
// or
|
|
521
538
|
|
|
522
|
-
const jobIdHeader = z.string().
|
|
539
|
+
const jobIdHeader = z.string().meta({
|
|
523
540
|
description: 'Job ID',
|
|
524
541
|
example: '1234',
|
|
525
542
|
});
|
|
@@ -615,6 +632,40 @@ createDocument({
|
|
|
615
632
|
});
|
|
616
633
|
```
|
|
617
634
|
|
|
635
|
+
#### Path Items
|
|
636
|
+
|
|
637
|
+
Path Items can also be registered
|
|
638
|
+
|
|
639
|
+
````typescript
|
|
640
|
+
const pathItem: ZodOpenApiPathItemObject = {
|
|
641
|
+
id: 'some-path-item',
|
|
642
|
+
get: {
|
|
643
|
+
responses: {
|
|
644
|
+
200: {
|
|
645
|
+
description: '200 OK',
|
|
646
|
+
content: {
|
|
647
|
+
'application/json': {
|
|
648
|
+
schema: z.object({ a: z.string() }),
|
|
649
|
+
},
|
|
650
|
+
},
|
|
651
|
+
},
|
|
652
|
+
},
|
|
653
|
+
},
|
|
654
|
+
};
|
|
655
|
+
|
|
656
|
+
// or
|
|
657
|
+
|
|
658
|
+
createDocument({
|
|
659
|
+
components: {
|
|
660
|
+
pathItems: {
|
|
661
|
+
'some-path-item': pathItem,
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
});
|
|
665
|
+
```
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
|
|
618
669
|
### Zod Types
|
|
619
670
|
|
|
620
671
|
Zod types are composed of two different parts: the input and the output. This library decides which type to create based on if it is used in a request or response context.
|
|
@@ -635,9 +686,9 @@ In general, you want to avoid using a registered input schema in an output conte
|
|
|
635
686
|
const schema = z.object({
|
|
636
687
|
name: z.string(),
|
|
637
688
|
});
|
|
638
|
-
|
|
689
|
+
````
|
|
639
690
|
|
|
640
|
-
Input:
|
|
691
|
+
Input schemas (request bodies, parameters):
|
|
641
692
|
|
|
642
693
|
```json
|
|
643
694
|
{
|
|
@@ -651,7 +702,7 @@ Input:
|
|
|
651
702
|
}
|
|
652
703
|
```
|
|
653
704
|
|
|
654
|
-
Output:
|
|
705
|
+
Output schemas (responses):
|
|
655
706
|
|
|
656
707
|
```json
|
|
657
708
|
{
|
|
@@ -666,25 +717,30 @@ Output:
|
|
|
666
717
|
}
|
|
667
718
|
```
|
|
668
719
|
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
If the schemas are not equal, it will automatically handle this by outputting the `output` schema with an `Output` suffix.
|
|
720
|
+
When the same schema is referenced in both input and output contexts, the library generates two separate component schemas. This happens automatically when a schema with an ID is used in both contexts.
|
|
672
721
|
|
|
673
|
-
You can
|
|
722
|
+
You can customize the output schema name by providing an `outputId`:
|
|
674
723
|
|
|
675
724
|
```ts
|
|
676
725
|
const schema = z
|
|
677
726
|
.object({
|
|
678
727
|
name: z.string(),
|
|
679
728
|
})
|
|
680
|
-
.meta({
|
|
729
|
+
.meta({
|
|
730
|
+
id: 'MyObject',
|
|
731
|
+
outputId: 'MyObjectResponse', // Customize the output schema name
|
|
732
|
+
});
|
|
681
733
|
```
|
|
682
734
|
|
|
735
|
+
You can also set a global suffix for output schemas or use `z.looseObject()` and `z.strictObject()` to have explicit control over the schema behavior.
|
|
736
|
+
|
|
737
|
+
> **⚠️ Note:** If your registered schema contains dynamically created lazy components, they won't be reused between input and output schemas.
|
|
738
|
+
|
|
683
739
|
## Supported OpenAPI Versions
|
|
684
740
|
|
|
685
741
|
Currently the following versions of OpenAPI are supported
|
|
686
742
|
|
|
687
|
-
- `3.1.0`
|
|
743
|
+
- `3.1.0` (minimum version)
|
|
688
744
|
- `3.1.1`
|
|
689
745
|
|
|
690
746
|
Setting the `openapi` field will change how the some of the components are rendered.
|
|
@@ -726,6 +782,10 @@ See the library in use in the [examples](./examples/) folder.
|
|
|
726
782
|
|
|
727
783
|
- [eslint-plugin-zod-openapi](https://github.com/samchungy/eslint-plugin-zod-openapi) - Eslint rules for zod-openapi. This includes features which can autogenerate Typescript comments for your Zod types based on your `description`, `example` and `deprecated` fields.
|
|
728
784
|
|
|
785
|
+
## Version Information
|
|
786
|
+
|
|
787
|
+
For information about changes and migration from v4 to v5, see the [v5 migration guide](./docs/v5.md).
|
|
788
|
+
|
|
729
789
|
## Comparisons
|
|
730
790
|
|
|
731
791
|
### [@asteasolutions/zod-to-openapi](./docs/comparisons.md)
|
package/dist/api.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentRegistry, Override, createComponents, createRegistry } from "./components-
|
|
1
|
+
import { ComponentRegistry, Override, createComponents, createRegistry } from "./components-uNe8arnt.mjs";
|
|
2
2
|
import { $ZodObject, $ZodType, $ZodTypes } from "zod/v4/core";
|
|
3
3
|
import { core } from "zod/v4";
|
|
4
4
|
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ComponentRegistry, Override, createComponents, createRegistry } from "./components-
|
|
1
|
+
import { ComponentRegistry, Override, createComponents, createRegistry } from "./components-Ds_qyBU9.js";
|
|
2
2
|
import { $ZodObject, $ZodType, $ZodTypes } from "zod/v4/core";
|
|
3
3
|
import { core } from "zod/v4";
|
|
4
4
|
|
package/dist/api.js
CHANGED
package/dist/api.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { createComponents, createRegistry, isAnyZodType, unwrapZodObject } from "./components-
|
|
1
|
+
import { createComponents, createRegistry, isAnyZodType, unwrapZodObject } from "./components-CncTLZvX.mjs";
|
|
2
2
|
|
|
3
3
|
export { createComponents, createRegistry, isAnyZodType, unwrapZodObject };
|
|
@@ -260,7 +260,7 @@ const renameComponents = (components, outputIds, ctx, refPath) => {
|
|
|
260
260
|
const registeredComponent = ctx.registry.components.schemas.ids.get(key);
|
|
261
261
|
if (!registeredComponent) continue;
|
|
262
262
|
if (isDependencyPure(componentDependencies, stringifiedComponents, ctx.registry, key)) continue;
|
|
263
|
-
const newName = outputIds.get(key) ?? `${key}Output`;
|
|
263
|
+
const newName = outputIds.get(key) ?? `${key}${ctx.opts.outputIdSuffix ?? "Output"}`;
|
|
264
264
|
componentsToRename.set(key, newName);
|
|
265
265
|
components[newName] = components[key];
|
|
266
266
|
delete components[key];
|
|
@@ -286,19 +286,12 @@ const isDependencyPure = (componentDependencies, stringifiedComponents, registry
|
|
|
286
286
|
|
|
287
287
|
//#endregion
|
|
288
288
|
//#region src/create/schema/schema.ts
|
|
289
|
-
const deleteZodOpenApiMeta = (jsonSchema) => {
|
|
290
|
-
delete jsonSchema.param;
|
|
291
|
-
delete jsonSchema.header;
|
|
292
|
-
delete jsonSchema.unusedIO;
|
|
293
|
-
delete jsonSchema.override;
|
|
294
|
-
delete jsonSchema.outputId;
|
|
295
|
-
};
|
|
296
289
|
const createSchema = (schema, ctx = {
|
|
297
290
|
registry: createRegistry(),
|
|
298
291
|
io: "output",
|
|
299
292
|
opts: {}
|
|
300
293
|
}) => {
|
|
301
|
-
ctx.registry ??= createRegistry();
|
|
294
|
+
ctx.registry ??= createRegistry({ schemas: ctx.opts?.schemaComponents });
|
|
302
295
|
ctx.opts ??= {};
|
|
303
296
|
ctx.io ??= "output";
|
|
304
297
|
const registrySchemas = Object.fromEntries(ctx.registry.components.schemas[ctx.io]);
|
|
@@ -314,6 +307,13 @@ const createSchema = (schema, ctx = {
|
|
|
314
307
|
components: jsonSchemas.components
|
|
315
308
|
};
|
|
316
309
|
};
|
|
310
|
+
const deleteZodOpenApiMeta = (jsonSchema) => {
|
|
311
|
+
delete jsonSchema.param;
|
|
312
|
+
delete jsonSchema.header;
|
|
313
|
+
delete jsonSchema.unusedIO;
|
|
314
|
+
delete jsonSchema.override;
|
|
315
|
+
delete jsonSchema.outputId;
|
|
316
|
+
};
|
|
317
317
|
const createSchemas = (schemas, ctx) => {
|
|
318
318
|
const refPath = ctx.opts.schemaRefPath ?? "#/components/schemas/";
|
|
319
319
|
const entries = {};
|
|
@@ -467,6 +467,7 @@ const createRegistry = (components) => {
|
|
|
467
467
|
const meta = globalRegistry.get(parameter);
|
|
468
468
|
const name = opts?.location?.name ?? meta?.param?.name;
|
|
469
469
|
const inLocation = opts?.location?.in ?? meta?.param?.in;
|
|
470
|
+
if (opts?.location?.name && meta?.param?.name || opts?.location?.in && meta?.param?.in) throw new Error(`Parameter at ${path.join(" > ")} has both \`.meta({ param: { name, in } })\` and \`.meta({ param: { location: { in, name } } })\` information`);
|
|
470
471
|
if (!name || !inLocation) throw new Error(`Parameter at ${path.join(" > ")} is missing \`.meta({ param: { name, in } })\` information`);
|
|
471
472
|
const schemaObject = registry$1.addSchema(parameter, [
|
|
472
473
|
...path,
|
|
@@ -500,6 +501,7 @@ const createRegistry = (components) => {
|
|
|
500
501
|
registry$1.components.parameters.ids.set(id, parameterObject);
|
|
501
502
|
return ref;
|
|
502
503
|
}
|
|
504
|
+
if (opts?.location?.name || opts?.location?.in) return parameterObject;
|
|
503
505
|
registry$1.components.parameters.seen.set(parameter, parameterObject);
|
|
504
506
|
return parameterObject;
|
|
505
507
|
},
|
|
@@ -283,7 +283,7 @@ const renameComponents = (components, outputIds, ctx, refPath) => {
|
|
|
283
283
|
const registeredComponent = ctx.registry.components.schemas.ids.get(key);
|
|
284
284
|
if (!registeredComponent) continue;
|
|
285
285
|
if (isDependencyPure(componentDependencies, stringifiedComponents, ctx.registry, key)) continue;
|
|
286
|
-
const newName = outputIds.get(key) ?? `${key}Output`;
|
|
286
|
+
const newName = outputIds.get(key) ?? `${key}${ctx.opts.outputIdSuffix ?? "Output"}`;
|
|
287
287
|
componentsToRename.set(key, newName);
|
|
288
288
|
components[newName] = components[key];
|
|
289
289
|
delete components[key];
|
|
@@ -309,19 +309,12 @@ const isDependencyPure = (componentDependencies, stringifiedComponents, registry
|
|
|
309
309
|
|
|
310
310
|
//#endregion
|
|
311
311
|
//#region src/create/schema/schema.ts
|
|
312
|
-
const deleteZodOpenApiMeta = (jsonSchema) => {
|
|
313
|
-
delete jsonSchema.param;
|
|
314
|
-
delete jsonSchema.header;
|
|
315
|
-
delete jsonSchema.unusedIO;
|
|
316
|
-
delete jsonSchema.override;
|
|
317
|
-
delete jsonSchema.outputId;
|
|
318
|
-
};
|
|
319
312
|
const createSchema = (schema, ctx = {
|
|
320
313
|
registry: createRegistry(),
|
|
321
314
|
io: "output",
|
|
322
315
|
opts: {}
|
|
323
316
|
}) => {
|
|
324
|
-
ctx.registry ??= createRegistry();
|
|
317
|
+
ctx.registry ??= createRegistry({ schemas: ctx.opts?.schemaComponents });
|
|
325
318
|
ctx.opts ??= {};
|
|
326
319
|
ctx.io ??= "output";
|
|
327
320
|
const registrySchemas = Object.fromEntries(ctx.registry.components.schemas[ctx.io]);
|
|
@@ -337,6 +330,13 @@ const createSchema = (schema, ctx = {
|
|
|
337
330
|
components: jsonSchemas.components
|
|
338
331
|
};
|
|
339
332
|
};
|
|
333
|
+
const deleteZodOpenApiMeta = (jsonSchema) => {
|
|
334
|
+
delete jsonSchema.param;
|
|
335
|
+
delete jsonSchema.header;
|
|
336
|
+
delete jsonSchema.unusedIO;
|
|
337
|
+
delete jsonSchema.override;
|
|
338
|
+
delete jsonSchema.outputId;
|
|
339
|
+
};
|
|
340
340
|
const createSchemas = (schemas, ctx) => {
|
|
341
341
|
const refPath = ctx.opts.schemaRefPath ?? "#/components/schemas/";
|
|
342
342
|
const entries = {};
|
|
@@ -490,6 +490,7 @@ const createRegistry = (components) => {
|
|
|
490
490
|
const meta = zod_v4_core.globalRegistry.get(parameter);
|
|
491
491
|
const name = opts?.location?.name ?? meta?.param?.name;
|
|
492
492
|
const inLocation = opts?.location?.in ?? meta?.param?.in;
|
|
493
|
+
if (opts?.location?.name && meta?.param?.name || opts?.location?.in && meta?.param?.in) throw new Error(`Parameter at ${path.join(" > ")} has both \`.meta({ param: { name, in } })\` and \`.meta({ param: { location: { in, name } } })\` information`);
|
|
493
494
|
if (!name || !inLocation) throw new Error(`Parameter at ${path.join(" > ")} is missing \`.meta({ param: { name, in } })\` information`);
|
|
494
495
|
const schemaObject = registry$1.addSchema(parameter, [
|
|
495
496
|
...path,
|
|
@@ -523,6 +524,7 @@ const createRegistry = (components) => {
|
|
|
523
524
|
registry$1.components.parameters.ids.set(id, parameterObject);
|
|
524
525
|
return ref;
|
|
525
526
|
}
|
|
527
|
+
if (opts?.location?.name || opts?.location?.in) return parameterObject;
|
|
526
528
|
registry$1.components.parameters.seen.set(parameter, parameterObject);
|
|
527
529
|
return parameterObject;
|
|
528
530
|
},
|
|
@@ -360,7 +360,7 @@ declare module 'zod/v4' {
|
|
|
360
360
|
*/
|
|
361
361
|
unusedIO?: 'input' | 'output';
|
|
362
362
|
/**
|
|
363
|
-
* An alternate id to use for this schema in the event
|
|
363
|
+
* An alternate id to use for this schema in the event a registered schema is used in both a request and response schema.
|
|
364
364
|
* If not specified, the id will be simply derived as the id of the schema plus an `Output` suffix. Please note that `id` must be set.
|
|
365
365
|
*/
|
|
366
366
|
outputId?: string;
|
|
@@ -448,10 +448,10 @@ type OverrideType = $ZodTypes['_zod']['def']['type'];
|
|
|
448
448
|
interface CreateDocumentOptions {
|
|
449
449
|
/**
|
|
450
450
|
* Use this to allowlist empty schemas to be created for given types
|
|
451
|
-
* - `true` — Allow empty schemas for input and output
|
|
452
|
-
* - `{ input: true, output: true }` — Allow empty schemas for input and output
|
|
453
|
-
* - `{ input: true }` — Allow empty schemas for input only
|
|
454
|
-
* - `{ output: true }` — Allow empty schemas for output only
|
|
451
|
+
* - `{ [ZodType]: true}` — Allow empty schemas for input and output
|
|
452
|
+
* - `{ [ZodType]: { input: true, output: true } }` — Allow empty schemas for input and output
|
|
453
|
+
* - `{ [ZodType]: { input: true } }` — Allow empty schemas for input only
|
|
454
|
+
* - `{ [ZodType]: { output: true } }` — Allow empty schemas for output only
|
|
455
455
|
*/
|
|
456
456
|
allowEmptySchema?: Partial<Record<OverrideType, true | Partial<{
|
|
457
457
|
input: true;
|
|
@@ -463,6 +463,14 @@ interface CreateDocumentOptions {
|
|
|
463
463
|
* - `(ctx) => { ctx.jsonSchema.type = 'string'; }` — Override the schema type to be a string using a function
|
|
464
464
|
*/
|
|
465
465
|
override?: Override;
|
|
466
|
+
/**
|
|
467
|
+
* Suffix to append to the output ID of the schema.
|
|
468
|
+
* This is useful to avoid conflicts with other schemas that may have the same name.
|
|
469
|
+
* For example, if you have a schema named `Person`, you can set this to `Response` to get `PersonResponse`.
|
|
470
|
+
* If not set, the default suffix is `Output`.
|
|
471
|
+
* @default 'Output'
|
|
472
|
+
*/
|
|
473
|
+
outputIdSuffix?: string;
|
|
466
474
|
/**
|
|
467
475
|
* How to handle reused schemas.
|
|
468
476
|
* - `"ref"` — Reused schemas will be rendered as references
|
|
@@ -360,7 +360,7 @@ declare module 'zod/v4' {
|
|
|
360
360
|
*/
|
|
361
361
|
unusedIO?: 'input' | 'output';
|
|
362
362
|
/**
|
|
363
|
-
* An alternate id to use for this schema in the event
|
|
363
|
+
* An alternate id to use for this schema in the event a registered schema is used in both a request and response schema.
|
|
364
364
|
* If not specified, the id will be simply derived as the id of the schema plus an `Output` suffix. Please note that `id` must be set.
|
|
365
365
|
*/
|
|
366
366
|
outputId?: string;
|
|
@@ -448,10 +448,10 @@ type OverrideType = $ZodTypes['_zod']['def']['type'];
|
|
|
448
448
|
interface CreateDocumentOptions {
|
|
449
449
|
/**
|
|
450
450
|
* Use this to allowlist empty schemas to be created for given types
|
|
451
|
-
* - `true` — Allow empty schemas for input and output
|
|
452
|
-
* - `{ input: true, output: true }` — Allow empty schemas for input and output
|
|
453
|
-
* - `{ input: true }` — Allow empty schemas for input only
|
|
454
|
-
* - `{ output: true }` — Allow empty schemas for output only
|
|
451
|
+
* - `{ [ZodType]: true}` — Allow empty schemas for input and output
|
|
452
|
+
* - `{ [ZodType]: { input: true, output: true } }` — Allow empty schemas for input and output
|
|
453
|
+
* - `{ [ZodType]: { input: true } }` — Allow empty schemas for input only
|
|
454
|
+
* - `{ [ZodType]: { output: true } }` — Allow empty schemas for output only
|
|
455
455
|
*/
|
|
456
456
|
allowEmptySchema?: Partial<Record<OverrideType, true | Partial<{
|
|
457
457
|
input: true;
|
|
@@ -463,6 +463,14 @@ interface CreateDocumentOptions {
|
|
|
463
463
|
* - `(ctx) => { ctx.jsonSchema.type = 'string'; }` — Override the schema type to be a string using a function
|
|
464
464
|
*/
|
|
465
465
|
override?: Override;
|
|
466
|
+
/**
|
|
467
|
+
* Suffix to append to the output ID of the schema.
|
|
468
|
+
* This is useful to avoid conflicts with other schemas that may have the same name.
|
|
469
|
+
* For example, if you have a schema named `Person`, you can set this to `Response` to get `PersonResponse`.
|
|
470
|
+
* If not set, the default suffix is `Output`.
|
|
471
|
+
* @default 'Output'
|
|
472
|
+
*/
|
|
473
|
+
outputIdSuffix?: string;
|
|
466
474
|
/**
|
|
467
475
|
* How to handle reused schemas.
|
|
468
476
|
* - `"ref"` — Reused schemas will be rendered as references
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseParameterObject, CallbackObject, CallbacksObject, ComponentRegistry, ComponentsObject, ContactObject, ContentObject, CreateDocumentOptions, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, HeaderObject, HeadersObject, IExtensionName, IExtensionType, ISpecificationExtension, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, Override, ParameterLocation, ParameterObject, ParameterStyle, PathItemObject, PathObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, TagObject, XmlObject, ZodObjectInput, ZodOpenApiCallbackObject, ZodOpenApiCallbacksObject, ZodOpenApiComponentsObject, ZodOpenApiContentObject, ZodOpenApiHeaderObject, ZodOpenApiHeadersObject, ZodOpenApiMediaTypeObject, ZodOpenApiObject, ZodOpenApiOperationObject, ZodOpenApiParameterObject, ZodOpenApiParameters, ZodOpenApiPathItemObject, ZodOpenApiPathsObject, ZodOpenApiRequestBodyObject, ZodOpenApiResponseObject, ZodOpenApiResponsesObject, ZodOpenApiSchemaObject, ZodOpenApiVersion, createDocument } from "./components-
|
|
1
|
+
import { BaseParameterObject, CallbackObject, CallbacksObject, ComponentRegistry, ComponentsObject, ContactObject, ContentObject, CreateDocumentOptions, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, HeaderObject, HeadersObject, IExtensionName, IExtensionType, ISpecificationExtension, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, Override, ParameterLocation, ParameterObject, ParameterStyle, PathItemObject, PathObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, TagObject, XmlObject, ZodObjectInput, ZodOpenApiCallbackObject, ZodOpenApiCallbacksObject, ZodOpenApiComponentsObject, ZodOpenApiContentObject, ZodOpenApiHeaderObject, ZodOpenApiHeadersObject, ZodOpenApiMediaTypeObject, ZodOpenApiObject, ZodOpenApiOperationObject, ZodOpenApiParameterObject, ZodOpenApiParameters, ZodOpenApiPathItemObject, ZodOpenApiPathsObject, ZodOpenApiRequestBodyObject, ZodOpenApiResponseObject, ZodOpenApiResponsesObject, ZodOpenApiSchemaObject, ZodOpenApiVersion, createDocument } from "./components-uNe8arnt.mjs";
|
|
2
2
|
import { core } from "zod/v4";
|
|
3
3
|
|
|
4
4
|
//#region rolldown:runtime
|
|
@@ -11,7 +11,9 @@ interface SchemaResult {
|
|
|
11
11
|
declare const createSchema: (schema: core.$ZodType, ctx?: {
|
|
12
12
|
registry?: ComponentRegistry;
|
|
13
13
|
io?: "input" | "output";
|
|
14
|
-
opts?: CreateDocumentOptions
|
|
14
|
+
opts?: CreateDocumentOptions & {
|
|
15
|
+
schemaComponents?: ZodOpenApiComponentsObject["schemas"];
|
|
16
|
+
};
|
|
15
17
|
}) => {
|
|
16
18
|
schema: SchemaObject | ReferenceObject;
|
|
17
19
|
components: Record<string, SchemaObject>;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { BaseParameterObject, CallbackObject, CallbacksObject, ComponentRegistry, ComponentsObject, ContactObject, ContentObject, CreateDocumentOptions, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, HeaderObject, HeadersObject, IExtensionName, IExtensionType, ISpecificationExtension, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, Override, ParameterLocation, ParameterObject, ParameterStyle, PathItemObject, PathObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, TagObject, XmlObject, ZodObjectInput, ZodOpenApiCallbackObject, ZodOpenApiCallbacksObject, ZodOpenApiComponentsObject, ZodOpenApiContentObject, ZodOpenApiHeaderObject, ZodOpenApiHeadersObject, ZodOpenApiMediaTypeObject, ZodOpenApiObject, ZodOpenApiOperationObject, ZodOpenApiParameterObject, ZodOpenApiParameters, ZodOpenApiPathItemObject, ZodOpenApiPathsObject, ZodOpenApiRequestBodyObject, ZodOpenApiResponseObject, ZodOpenApiResponsesObject, ZodOpenApiSchemaObject, ZodOpenApiVersion, createDocument } from "./components-
|
|
1
|
+
import { BaseParameterObject, CallbackObject, CallbacksObject, ComponentRegistry, ComponentsObject, ContactObject, ContentObject, CreateDocumentOptions, DiscriminatorObject, EncodingObject, EncodingPropertyObject, ExampleObject, ExamplesObject, ExternalDocumentationObject, HeaderObject, HeadersObject, IExtensionName, IExtensionType, ISpecificationExtension, InfoObject, LicenseObject, LinkObject, LinkParametersObject, LinksObject, MediaTypeObject, OAuthFlowObject, OAuthFlowsObject, OpenAPIObject, OperationObject, Override, ParameterLocation, ParameterObject, ParameterStyle, PathItemObject, PathObject, PathsObject, ReferenceObject, RequestBodyObject, ResponseObject, ResponsesObject, SchemaObject, SchemaObjectType, SchemasObject, ScopesObject, SecurityRequirementObject, SecuritySchemeObject, SecuritySchemeType, ServerObject, ServerVariableObject, TagObject, XmlObject, ZodObjectInput, ZodOpenApiCallbackObject, ZodOpenApiCallbacksObject, ZodOpenApiComponentsObject, ZodOpenApiContentObject, ZodOpenApiHeaderObject, ZodOpenApiHeadersObject, ZodOpenApiMediaTypeObject, ZodOpenApiObject, ZodOpenApiOperationObject, ZodOpenApiParameterObject, ZodOpenApiParameters, ZodOpenApiPathItemObject, ZodOpenApiPathsObject, ZodOpenApiRequestBodyObject, ZodOpenApiResponseObject, ZodOpenApiResponsesObject, ZodOpenApiSchemaObject, ZodOpenApiVersion, createDocument } from "./components-Ds_qyBU9.js";
|
|
2
2
|
import { core } from "zod/v4";
|
|
3
3
|
|
|
4
4
|
//#region rolldown:runtime
|
|
@@ -11,7 +11,9 @@ interface SchemaResult {
|
|
|
11
11
|
declare const createSchema: (schema: core.$ZodType, ctx?: {
|
|
12
12
|
registry?: ComponentRegistry;
|
|
13
13
|
io?: "input" | "output";
|
|
14
|
-
opts?: CreateDocumentOptions
|
|
14
|
+
opts?: CreateDocumentOptions & {
|
|
15
|
+
schemaComponents?: ZodOpenApiComponentsObject["schemas"];
|
|
16
|
+
};
|
|
15
17
|
}) => {
|
|
16
18
|
schema: SchemaObject | ReferenceObject;
|
|
17
19
|
components: Record<string, SchemaObject>;
|
package/dist/index.js
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { createComponents, createPaths, createRegistry, createSchema } from "./components-
|
|
1
|
+
import { createComponents, createPaths, createRegistry, createSchema } from "./components-CncTLZvX.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/create/document.ts
|
|
4
4
|
const createDocument = (zodOpenApiObject, opts = {}) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod-openapi",
|
|
3
|
-
"version": "5.0.0-beta.
|
|
3
|
+
"version": "5.0.0-beta.17",
|
|
4
4
|
"description": "Convert Zod Schemas to OpenAPI v3.x documentation",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -54,7 +54,7 @@
|
|
|
54
54
|
"@arethetypeswrong/cli": "0.18.1",
|
|
55
55
|
"@redocly/cli": "1.34.3",
|
|
56
56
|
"@types/node": "22.15.21",
|
|
57
|
-
"eslint-plugin-zod-openapi": "
|
|
57
|
+
"eslint-plugin-zod-openapi": "2.0.0-beta.1",
|
|
58
58
|
"openapi3-ts": "4.5.0",
|
|
59
59
|
"skuba": "11.0.1",
|
|
60
60
|
"tsdown": "0.12.9",
|