zod-openapi 3.2.0 → 4.0.0-beta.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/README.md +90 -15
- package/dist/components.chunk.cjs +328 -180
- package/dist/components.chunk.mjs +328 -180
- package/dist/extendZod.chunk.cjs +65 -10
- package/dist/extendZod.chunk.mjs +65 -10
- package/dist/extendZodTypes.d.ts +17 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -467,19 +467,7 @@ createDocument({
|
|
|
467
467
|
});
|
|
468
468
|
```
|
|
469
469
|
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
`.transform()`, `.default()` and `.pipe()` are complicated because they technically comprise of two types (input & output). This means that we need to understand which type you are creating. In particular with transform it is very difficult to infer the output type. This library will automatically select which _type_ to use by checking how the schema is used based on the following rules:
|
|
473
|
-
|
|
474
|
-
_Input_: Request Bodies, Request Parameters, Headers
|
|
475
|
-
|
|
476
|
-
_Output_: Responses, Response Headers
|
|
477
|
-
|
|
478
|
-
If a registered schema with a transform or pipeline is used in both a request and response schema you will receive an error because the created schema for each will be different. To override the creation type for a specific ZodEffect, add an `.openapi()` field on it and set the `effectType` field to `input`, `output` or `same`. This will force this library to always generate the input/output type even if we are creating a response (output) or request (input) type. You typically want to set this when you know the type has not changed in the transform. `same` is the recommended choice as it will generate a TypeScript compiler error if the input and output types in the transform drift.
|
|
479
|
-
|
|
480
|
-
`.preprocess()` will always return the `output` type even if we are creating an input schema. If a different input type is required you can achieve this with a `.transform()` combined with a `.pipe()` or simply declare a manual `type` in `.openapi()`.
|
|
481
|
-
|
|
482
|
-
If you are adding a ZodSchema directly to the `components` section which is not referenced anywhere in the document, additional context may be required to create either an input or output schema. You can do this by setting the `refType` field to `input` or `output` in `.openapi()`. This defaults to `output` by default.
|
|
470
|
+
Unfortunately, as a limitation of this library, you will need to attach an `.openapi()` field or `.describe()` to the schema that you are passing into the components or else you may not get the full power of the component generation. As a result, I recommend utilising the auto registering components over manual egistration.
|
|
483
471
|
|
|
484
472
|
#### Parameters
|
|
485
473
|
|
|
@@ -649,6 +637,90 @@ createDocument({
|
|
|
649
637
|
});
|
|
650
638
|
```
|
|
651
639
|
|
|
640
|
+
### Zod Effects
|
|
641
|
+
|
|
642
|
+
`.transform()`, `.catch()`, `.default()` and `.pipe()` are complicated because they all comprise of two different types that we could generate (input & output).
|
|
643
|
+
|
|
644
|
+
We attempt to determine what type of schema to create based on the following contexts:
|
|
645
|
+
|
|
646
|
+
_Input_: Request Bodies, Request Parameters, Headers
|
|
647
|
+
|
|
648
|
+
_Output_: Responses, Response Headers
|
|
649
|
+
|
|
650
|
+
As an example:
|
|
651
|
+
|
|
652
|
+
```ts
|
|
653
|
+
z.object({
|
|
654
|
+
a: z.string().default('a'),
|
|
655
|
+
});
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
In a request context, this would render the following OpenAPI schema:
|
|
659
|
+
|
|
660
|
+
```yaml
|
|
661
|
+
type: 'object'
|
|
662
|
+
properties:
|
|
663
|
+
- a:
|
|
664
|
+
type: 'string'
|
|
665
|
+
default: 'a'
|
|
666
|
+
```
|
|
667
|
+
|
|
668
|
+
or the following for a response:
|
|
669
|
+
|
|
670
|
+
```yaml
|
|
671
|
+
type: 'object'
|
|
672
|
+
properties:
|
|
673
|
+
- a:
|
|
674
|
+
type: 'string'
|
|
675
|
+
default: 'a'
|
|
676
|
+
required:
|
|
677
|
+
- a
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
Note how the response schema created an extra `required` field. This means, if you were to register a Zod schema with `.default()` as a component and use it in both a request or response, your schema would be invalid. Zod OpenAPI keeps track of this usage and will throw an error if this occurs.
|
|
681
|
+
|
|
682
|
+
#### EffectType
|
|
683
|
+
|
|
684
|
+
```ts
|
|
685
|
+
z.string().transform((str) => str.trim());
|
|
686
|
+
```
|
|
687
|
+
|
|
688
|
+
Whilst the TypeScript compiler can understand that the result is still a `string`, unfortunately we cannot introspect this as your transform function may be far more complicated than this example. To address this, you can set the `effectType` on the schema to `same`, `input` or `output`.
|
|
689
|
+
|
|
690
|
+
`same` - This informs Zod OpenAPI to pick either the input schema or output schema to generate with because they should be the same.
|
|
691
|
+
|
|
692
|
+
```ts
|
|
693
|
+
z.string()
|
|
694
|
+
.transform((str) => str.trim())
|
|
695
|
+
.openapi({ effectType: 'same' });
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
If the transform were to drift from this, you will receive a TypeScript error:
|
|
699
|
+
|
|
700
|
+
```ts
|
|
701
|
+
z.string()
|
|
702
|
+
.transform((str) => str.length)
|
|
703
|
+
.openapi({ effectType: 'same' });
|
|
704
|
+
// ~~~~~~~~~~
|
|
705
|
+
// Type 'same' is not assignable to type 'CreationType | undefined'.ts(2322)
|
|
706
|
+
```
|
|
707
|
+
|
|
708
|
+
`input` or `output` - This tells Zod OpenAPI to pick a specific schema to create whenever we run into this schema, regardless of it is a request or response schema.
|
|
709
|
+
|
|
710
|
+
```ts
|
|
711
|
+
z.string()
|
|
712
|
+
.transform((str) => str.length)
|
|
713
|
+
.openapi({ effectType: 'input' });
|
|
714
|
+
```
|
|
715
|
+
|
|
716
|
+
#### Preprocess
|
|
717
|
+
|
|
718
|
+
`.preprocess()` will always return the `output` type even if we are creating an input schema. If a different input type is required you can achieve this with a `.transform()` combined with a `.pipe()` or simply declare a manual `type` in `.openapi()`.
|
|
719
|
+
|
|
720
|
+
#### Component Effects
|
|
721
|
+
|
|
722
|
+
If you are adding a ZodSchema directly to the `components` section which is not referenced anywhere in the document, additional context may be required to create either an input or output schema. You can do this by setting the `refType` field to `input` or `output` in `.openapi()`. This defaults to `output` by default.
|
|
723
|
+
|
|
652
724
|
## Supported OpenAPI Versions
|
|
653
725
|
|
|
654
726
|
Currently the following versions of OpenAPI are supported
|
|
@@ -667,7 +739,7 @@ createDocument({
|
|
|
667
739
|
});
|
|
668
740
|
```
|
|
669
741
|
|
|
670
|
-
|
|
742
|
+
As an example `z.string().nullable()` will be rendered differently
|
|
671
743
|
|
|
672
744
|
`3.0.0`
|
|
673
745
|
|
|
@@ -694,6 +766,8 @@ For example in `z.string().nullable()` will be rendered differently
|
|
|
694
766
|
- ZodBoolean
|
|
695
767
|
- ZodBranded
|
|
696
768
|
- ZodCatch
|
|
769
|
+
- Treated as ZodDefault
|
|
770
|
+
- ZodCustom
|
|
697
771
|
- ZodDate
|
|
698
772
|
- `type` is mapped as `string` by default
|
|
699
773
|
- ZodDefault
|
|
@@ -715,7 +789,8 @@ For example in `z.string().nullable()` will be rendered differently
|
|
|
715
789
|
- ZodNullable
|
|
716
790
|
- ZodNumber
|
|
717
791
|
- `integer` `type` mapping for `.int()`
|
|
718
|
-
- `exclusiveMin`/`min`/`exclusiveMax`/`max` mapping for `.min()`, `.max()`, `lt()`, `gt()
|
|
792
|
+
- `exclusiveMin`/`min`/`exclusiveMax`/`max` mapping for `.min()`, `.max()`, `lt()`, `gt()`, `.positive()`, `.negative()`, `.nonnegative()`, `.nonpositive()`.
|
|
793
|
+
- `multipleOf` mapping for `.multipleOf()`
|
|
719
794
|
- ZodObject
|
|
720
795
|
- `additionalProperties` mapping for `.catchall()`, `.strict()`
|
|
721
796
|
- `allOf` mapping for `.extend()` when the base object is registered and does not have `catchall()`, `strict()` and extension does not override a field.
|