1
- import type { SchemaObject , SchemaObjectType } from 'openapi3-ts/oas31' ;
1
+ import type { SchemaObject , SchemaObjectType } from 'openapi3-ts/oas31' ;
2
2
import merge from 'ts-deepmerge' ;
3
- import { AnyZodObject , z , ZodTypeAny } from 'zod' ;
3
+ import { AnyZodObject , z , ZodTypeAny } from 'zod' ;
4
+
5
+ type AnatineSchemaObject = SchemaObject & { hideDefinitions ?: string [ ] } ;
4
6
5
7
export interface OpenApiZodAny extends ZodTypeAny {
6
- metaOpenApi ?: SchemaObject | SchemaObject [ ] ;
8
+ metaOpenApi ?: AnatineSchemaObject | AnatineSchemaObject [ ] ;
7
9
}
8
10
9
11
interface OpenApiZodAnyObject extends AnyZodObject {
10
- metaOpenApi ?: SchemaObject | SchemaObject [ ] ;
12
+ metaOpenApi ?: AnatineSchemaObject | AnatineSchemaObject [ ] ;
11
13
}
12
14
13
15
interface ParsingArgs < T > {
14
16
zodRef : T ;
15
- schemas : SchemaObject [ ] ;
17
+ schemas : AnatineSchemaObject [ ] ;
16
18
useOutput ?: boolean ;
19
+ hideDefinitions ?: string [ ] ;
17
20
}
18
21
19
22
export function extendApi < T extends OpenApiZodAny > (
20
23
schema : T ,
21
- SchemaObject : SchemaObject = { }
24
+ schemaObject : AnatineSchemaObject = { }
22
25
) : T {
23
- schema . metaOpenApi = Object . assign ( schema . metaOpenApi || { } , SchemaObject ) ;
26
+ schema . metaOpenApi = Object . assign ( schema . metaOpenApi || { } , schemaObject ) ;
24
27
return schema ;
25
28
}
26
29
27
30
function iterateZodObject ( {
28
31
zodRef,
29
32
useOutput,
33
+ hideDefinitions,
30
34
} : ParsingArgs < OpenApiZodAnyObject > ) {
31
- return Object . keys ( zodRef . shape ) . reduce (
32
- ( carry , key ) => ( {
33
- ...carry ,
34
- [ key ] : generateSchema ( zodRef . shape [ key ] , useOutput ) ,
35
- } ) ,
36
- { } as Record < string , SchemaObject >
37
- ) ;
35
+ const reduced = Object . keys ( zodRef . shape )
36
+ . filter ( ( key ) => hideDefinitions ?. includes ( key ) === false )
37
+ . reduce (
38
+ ( carry , key ) => ( {
39
+ ...carry ,
40
+ [ key ] : generateSchema ( zodRef . shape [ key ] , useOutput ) ,
41
+ } ) ,
42
+ { } as Record < string , SchemaObject >
43
+ ) ;
44
+
45
+ return reduced ;
38
46
}
39
47
40
48
function parseTransformation ( {
@@ -54,16 +62,16 @@ function parseTransformation({
54
62
[ 'integer' , 'number' ] . includes ( `${ input . type } ` )
55
63
? 0
56
64
: 'string' === input . type
57
- ? ''
58
- : 'boolean' === input . type
59
- ? false
60
- : 'object' === input . type
61
- ? { }
62
- : 'null' === input . type
63
- ? null
64
- : 'array' === input . type
65
- ? [ ]
66
- : undefined ,
65
+ ? ''
66
+ : 'boolean' === input . type
67
+ ? false
68
+ : 'object' === input . type
69
+ ? { }
70
+ : 'null' === input . type
71
+ ? null
72
+ : 'array' === input . type
73
+ ? [ ]
74
+ : undefined ,
67
75
{ addIssue : ( ) => undefined , path : [ ] } // TODO: Discover if context is necessary here
68
76
) ;
69
77
} catch ( e ) {
@@ -77,8 +85,8 @@ function parseTransformation({
77
85
...input ,
78
86
...( [ 'number' , 'string' , 'boolean' , 'null' ] . includes ( output )
79
87
? {
80
- type : output as 'number' | 'string' | 'boolean' | 'null' ,
81
- }
88
+ type : output as 'number' | 'string' | 'boolean' | 'null' ,
89
+ }
82
90
: { } ) ,
83
91
} ,
84
92
...schemas
@@ -165,10 +173,26 @@ function parseNumber({
165
173
) ;
166
174
}
167
175
176
+
177
+
178
+ function getExcludedDefinitionsFromSchema ( schemas : AnatineSchemaObject [ ] ) : string [ ] {
179
+
180
+
181
+ const excludedDefinitions = [ ] ;
182
+ for ( const schema of schemas ) {
183
+ if ( Array . isArray ( schema . hideDefinitions ) ) {
184
+ excludedDefinitions . push ( ...schema . hideDefinitions )
185
+ }
186
+ }
187
+
188
+ return excludedDefinitions
189
+ }
190
+
168
191
function parseObject ( {
169
192
zodRef,
170
193
schemas,
171
194
useOutput,
195
+ hideDefinitions,
172
196
} : ParsingArgs <
173
197
z . ZodObject < never , 'passthrough' | 'strict' | 'strip' >
174
198
> ) : SchemaObject {
@@ -213,11 +237,13 @@ function parseObject({
213
237
zodRef : zodRef as OpenApiZodAnyObject ,
214
238
schemas,
215
239
useOutput,
240
+ hideDefinitions : getExcludedDefinitionsFromSchema ( schemas ) ,
216
241
} ) ,
217
242
...required ,
218
243
...additionalProperties ,
244
+ ...hideDefinitions
219
245
} ,
220
- zodRef . description ? { description : zodRef . description } : { } ,
246
+ zodRef . description ? { description : zodRef . description , hideDefinitions } : { } ,
221
247
...schemas
222
248
) ;
223
249
}
@@ -389,22 +415,27 @@ function parseUnion({
389
415
useOutput,
390
416
} : ParsingArgs < z . ZodUnion < [ z . ZodTypeAny , ...z . ZodTypeAny [ ] ] > > ) : SchemaObject {
391
417
const contents = zodRef . _def . options ;
392
- if ( contents . reduce ( ( prev , content ) => prev && content . _def . typeName === 'ZodLiteral' , true ) ) {
418
+ if (
419
+ contents . reduce (
420
+ ( prev , content ) => prev && content . _def . typeName === 'ZodLiteral' ,
421
+ true
422
+ )
423
+ ) {
393
424
// special case to transform unions of literals into enums
394
425
const literals = contents as unknown as z . ZodLiteral < OpenApiZodAny > [ ] ;
395
- const type = literals
396
- . reduce ( ( prev , content ) =>
397
- ! prev || prev === typeof content . _def . value ?
398
- typeof content . _def . value :
399
- null ,
400
- null as null | string
401
- ) ;
426
+ const type = literals . reduce (
427
+ ( prev , content ) =>
428
+ ! prev || prev === typeof content . _def . value
429
+ ? typeof content . _def . value
430
+ : null ,
431
+ null as null | string
432
+ ) ;
402
433
403
434
if ( type ) {
404
435
return merge (
405
436
{
406
437
type : type as 'string' | 'number' | 'boolean' ,
407
- enum : literals . map ( ( literal ) => literal . _def . value )
438
+ enum : literals . map ( ( literal ) => literal . _def . value ) ,
408
439
} ,
409
440
zodRef . description ? { description : zodRef . description } : { } ,
410
441
...schemas
0 commit comments