1
1
import {
2
- ParameterObject ,
3
- PathItemObject ,
4
- ReferenceObject ,
5
- RequestBodyObject ,
6
- ResponseObject ,
7
- SchemaObject ,
8
- } from 'openapi3-ts/oas30' ;
9
- import {
10
- camel ,
11
2
ClientBuilder ,
12
3
ClientGeneratorsBuilder ,
13
- escape ,
4
+ ContextSpecs ,
14
5
GeneratorDependency ,
6
+ GeneratorMutator ,
15
7
GeneratorOptions ,
16
8
GeneratorVerbOptions ,
17
- isString ,
18
- resolveRef ,
19
- ContextSpecs ,
20
- isObject ,
9
+ ZodCoerceType ,
10
+ camel ,
11
+ escape ,
12
+ generateMutator ,
13
+ getNumberWord ,
21
14
isBoolean ,
15
+ isObject ,
16
+ isString ,
22
17
jsStringEscape ,
23
- getNumberWord ,
24
18
pascal ,
25
- ZodCoerceType ,
26
- generateMutator ,
27
- GeneratorMutator ,
19
+ resolveRef ,
28
20
} from '@orval/core' ;
29
21
import uniq from 'lodash.uniq' ;
22
+ import {
23
+ ParameterObject ,
24
+ PathItemObject ,
25
+ ReferenceObject ,
26
+ RequestBodyObject ,
27
+ ResponseObject ,
28
+ SchemaObject ,
29
+ } from 'openapi3-ts/oas30' ;
30
30
31
31
const ZOD_DEPENDENCIES : GeneratorDependency [ ] = [
32
32
{
@@ -76,12 +76,16 @@ export type ZodValidationSchemaDefinition = {
76
76
consts : string [ ] ;
77
77
} ;
78
78
79
+ const minAndMaxTypes = [ 'number' , 'string' , 'array' ] ;
80
+
79
81
export const generateZodValidationSchemaDefinition = (
80
82
schema : SchemaObject | undefined ,
81
83
context : ContextSpecs ,
82
- _required : boolean | undefined ,
83
84
name : string ,
84
85
strict : boolean ,
86
+ rules ?: {
87
+ required ?: boolean ;
88
+ } ,
85
89
) : ZodValidationSchemaDefinition => {
86
90
if ( ! schema ) return { functions : [ ] , consts : [ ] } ;
87
91
@@ -99,22 +103,13 @@ export const generateZodValidationSchemaDefinition = (
99
103
100
104
const functions : [ string , any ] [ ] = [ ] ;
101
105
const type = resolveZodType ( schema . type ) ;
102
- const required = schema . default !== undefined ? false : _required ?? false ;
106
+ const required =
107
+ schema . default !== undefined ? false : rules ?. required ?? false ;
103
108
const nullable =
104
109
schema . nullable ??
105
110
( Array . isArray ( schema . type ) && schema . type . includes ( 'null' ) ) ;
106
- const min =
107
- schema . minimum ??
108
- schema . exclusiveMinimum ??
109
- schema . minLength ??
110
- schema . minItems ??
111
- undefined ;
112
- const max =
113
- schema . maximum ??
114
- schema . exclusiveMaximum ??
115
- schema . maxLength ??
116
- schema . maxItems ??
117
- undefined ;
111
+ const min = schema . minimum ?? schema . minLength ?? schema . minItems ;
112
+ const max = schema . maximum ?? schema . maxLength ?? schema . maxItems ;
118
113
const matches = schema . pattern ?? undefined ;
119
114
120
115
switch ( type ) {
@@ -125,9 +120,11 @@ export const generateZodValidationSchemaDefinition = (
125
120
generateZodValidationSchemaDefinition (
126
121
items ,
127
122
context ,
128
- true ,
129
123
camel ( `${ name } -item` ) ,
130
124
strict ,
125
+ {
126
+ required : true ,
127
+ } ,
131
128
) ,
132
129
] ) ;
133
130
break ;
@@ -193,9 +190,11 @@ export const generateZodValidationSchemaDefinition = (
193
190
generateZodValidationSchemaDefinition (
194
191
schema as SchemaObject ,
195
192
context ,
196
- true ,
197
193
camel ( name ) ,
198
194
strict ,
195
+ {
196
+ required : true ,
197
+ } ,
199
198
) ,
200
199
) ,
201
200
] ) ;
@@ -210,9 +209,11 @@ export const generateZodValidationSchemaDefinition = (
210
209
[ key ] : generateZodValidationSchemaDefinition (
211
210
schema . properties ?. [ key ] as any ,
212
211
context ,
213
- schema . required ?. includes ( key ) ,
214
212
camel ( `${ name } -${ key } ` ) ,
215
213
strict ,
214
+ {
215
+ required : schema . required ?. includes ( key ) ,
216
+ } ,
216
217
) ,
217
218
} ) )
218
219
. reduce ( ( acc , curr ) => ( { ...acc , ...curr } ) , { } ) ,
@@ -233,9 +234,11 @@ export const generateZodValidationSchemaDefinition = (
233
234
? { }
234
235
: ( schema . additionalProperties as SchemaObject ) ,
235
236
context ,
236
- true ,
237
237
name ,
238
238
strict ,
239
+ {
240
+ required : true ,
241
+ } ,
239
242
) ,
240
243
] ) ;
241
244
@@ -248,18 +251,21 @@ export const generateZodValidationSchemaDefinition = (
248
251
}
249
252
}
250
253
251
- if ( min !== undefined ) {
252
- if ( min === 1 ) {
253
- functions . push ( [ 'min' , `${ min } ` ] ) ;
254
- } else {
255
- consts . push ( `export const ${ name } Min${ constsCounterValue } = ${ min } ;\n` ) ;
256
- functions . push ( [ 'min' , `${ name } Min${ constsCounterValue } ` ] ) ;
254
+ if ( minAndMaxTypes . includes ( type ) ) {
255
+ if ( min !== undefined ) {
256
+ if ( min === 1 ) {
257
+ functions . push ( [ 'min' , `${ min } ` ] ) ;
258
+ } else {
259
+ consts . push ( `export const ${ name } Min${ constsCounterValue } = ${ min } ;\n` ) ;
260
+ functions . push ( [ 'min' , `${ name } Min${ constsCounterValue } ` ] ) ;
261
+ }
262
+ }
263
+ if ( max !== undefined ) {
264
+ consts . push ( `export const ${ name } Max${ constsCounterValue } = ${ max } ;\n` ) ;
265
+ functions . push ( [ 'max' , `${ name } Max${ constsCounterValue } ` ] ) ;
257
266
}
258
267
}
259
- if ( max !== undefined ) {
260
- consts . push ( `export const ${ name } Max${ constsCounterValue } = ${ max } ;\n` ) ;
261
- functions . push ( [ 'max' , `${ name } Max${ constsCounterValue } ` ] ) ;
262
- }
268
+
263
269
if ( matches ) {
264
270
const isStartWithSlash = matches . startsWith ( '/' ) ;
265
271
const isEndWithSlash = matches . endsWith ( '/' ) ;
@@ -462,6 +468,10 @@ const parseBodyAndResponse = ({
462
468
} ) : {
463
469
input : ZodValidationSchemaDefinition ;
464
470
isArray : boolean ;
471
+ rules ?: {
472
+ min ?: number ;
473
+ max ?: number ;
474
+ } ;
465
475
} => {
466
476
if ( ! data ) {
467
477
return {
@@ -489,25 +499,42 @@ const parseBodyAndResponse = ({
489
499
490
500
// keep the same behaviour for array
491
501
if ( resolvedJsonSchema . items ) {
502
+ const min =
503
+ resolvedJsonSchema . minimum ??
504
+ resolvedJsonSchema . minLength ??
505
+ resolvedJsonSchema . minItems ;
506
+ const max =
507
+ resolvedJsonSchema . maximum ??
508
+ resolvedJsonSchema . maxLength ??
509
+ resolvedJsonSchema . maxItems ;
510
+
492
511
return {
493
512
input : generateZodValidationSchemaDefinition (
494
513
resolvedJsonSchema . items as SchemaObject ,
495
514
context ,
496
- true ,
497
515
name ,
498
516
strict ,
517
+ {
518
+ required : true ,
519
+ } ,
499
520
) ,
500
521
isArray : true ,
522
+ rules : {
523
+ ...( typeof min !== 'undefined' ? { min } : { } ) ,
524
+ ...( typeof max !== 'undefined' ? { max } : { } ) ,
525
+ } ,
501
526
} ;
502
527
}
503
528
504
529
return {
505
530
input : generateZodValidationSchemaDefinition (
506
531
resolvedJsonSchema ,
507
532
context ,
508
- true ,
509
533
name ,
510
534
strict ,
535
+ {
536
+ required : true ,
537
+ } ,
511
538
) ,
512
539
isArray : false ,
513
540
} ;
@@ -570,9 +597,11 @@ const parseParameters = ({
570
597
const definition = generateZodValidationSchemaDefinition (
571
598
schema ,
572
599
context ,
573
- parameter . required ,
574
600
camel ( `${ operationName } -${ parameter . in } -${ parameter . name } ` ) ,
575
601
mapStrict [ parameter . in as 'path' | 'query' | 'header' ] ?? false ,
602
+ {
603
+ required : parameter . required ,
604
+ } ,
576
605
) ;
577
606
578
607
if ( parameter . in === 'header' ) {
@@ -772,7 +801,11 @@ const generateZodRoute = async (
772
801
? [
773
802
parsedBody . isArray
774
803
? `export const ${ operationName } BodyItem = ${ inputBody . zod }
775
- export const ${ operationName } Body = zod.array(${ operationName } BodyItem)`
804
+ export const ${ operationName } Body = zod.array(${ operationName } BodyItem)${
805
+ parsedBody . rules ?. min ? `.min(${ parsedBody . rules ?. min } )` : ''
806
+ } ${
807
+ parsedBody . rules ?. max ? `.max(${ parsedBody . rules ?. max } )` : ''
808
+ } `
776
809
: `export const ${ operationName } Body = ${ inputBody . zod } ` ,
777
810
]
778
811
: [ ] ) ,
@@ -786,8 +819,18 @@ export const ${operationName}Body = zod.array(${operationName}BodyItem)`
786
819
...( inputResponse . zod
787
820
? [
788
821
parsedResponses [ index ] . isArray
789
- ? `export const ${ operationResponse } Item = ${ inputResponse . zod }
790
- export const ${ operationResponse } = zod.array(${ operationResponse } Item)`
822
+ ? `export const ${ operationResponse } Item = ${
823
+ inputResponse . zod
824
+ }
825
+ export const ${ operationResponse } = zod.array(${ operationResponse } Item)${
826
+ parsedResponses [ index ] . rules ?. min
827
+ ? `.min(${ parsedResponses [ index ] . rules ?. min } )`
828
+ : ''
829
+ } ${
830
+ parsedResponses [ index ] . rules ?. max
831
+ ? `.max(${ parsedResponses [ index ] . rules ?. max } )`
832
+ : ''
833
+ } `
791
834
: `export const ${ operationResponse } = ${ inputResponse . zod } ` ,
792
835
]
793
836
: [ ] ) ,
0 commit comments