File tree Expand file tree Collapse file tree 8 files changed +154
-43
lines changed
3.0.x/discriminator-all-of
3.1.x/discriminator-all-of Expand file tree Collapse file tree 8 files changed +154
-43
lines changed Original file line number Diff line number Diff line change
1
+ ---
2
+ " @hey-api/openapi-ts " : patch
3
+ ---
4
+
5
+ fix(parser): correctly handle schema extending discriminated schema
Original file line number Diff line number Diff line change @@ -44,6 +44,24 @@ export type QuxMapped = FooMapped & {
44
44
qux ?: boolean ;
45
45
} ;
46
46
47
+ export type FooUnion = ( {
48
+ id : 'bar' ;
49
+ } & BarUnion ) | ( {
50
+ id : 'baz' ;
51
+ } & BazUnion ) ;
52
+
53
+ export type BarUnion = {
54
+ id ?: string ;
55
+ bar ?: string ;
56
+ } ;
57
+
58
+ export type BazUnion = {
59
+ id ?: string ;
60
+ baz ?: string ;
61
+ } ;
62
+
63
+ export type QuxExtend = FooUnion ;
64
+
47
65
export type ClientOptions = {
48
66
baseUrl : `${string } ://${string } ` | ( string & { } ) ;
49
67
} ;
Original file line number Diff line number Diff line change @@ -44,6 +44,24 @@ export type QuxMapped = FooMapped & {
44
44
qux ?: boolean ;
45
45
} ;
46
46
47
+ export type FooUnion = ( {
48
+ id : 'bar' ;
49
+ } & BarUnion ) | ( {
50
+ id : 'baz' ;
51
+ } & BazUnion ) ;
52
+
53
+ export type BarUnion = {
54
+ id ?: string ;
55
+ bar ?: string ;
56
+ } ;
57
+
58
+ export type BazUnion = {
59
+ id ?: string ;
60
+ baz ?: string ;
61
+ } ;
62
+
63
+ export type QuxExtend = FooUnion ;
64
+
47
65
export type ClientOptions = {
48
66
baseUrl : `${string } ://${string } ` | ( string & { } ) ;
49
67
} ;
Original file line number Diff line number Diff line change @@ -67,3 +67,29 @@ components:
67
67
properties :
68
68
qux :
69
69
type : boolean
70
+ FooUnion :
71
+ oneOf :
72
+ - $ref : ' #/components/schemas/BarUnion'
73
+ - $ref : ' #/components/schemas/BazUnion'
74
+ discriminator :
75
+ propertyName : id
76
+ mapping :
77
+ bar : ' #/components/schemas/BarUnion'
78
+ baz : ' #/components/schemas/BazUnion'
79
+ BarUnion :
80
+ type : object
81
+ properties :
82
+ id :
83
+ type : string
84
+ bar :
85
+ type : string
86
+ BazUnion :
87
+ type : object
88
+ properties :
89
+ id :
90
+ type : string
91
+ baz :
92
+ type : string
93
+ QuxExtend : # this is a schema that extends the FooUnion schema
94
+ allOf :
95
+ - $ref : ' #/components/schemas/FooUnion'
Original file line number Diff line number Diff line change @@ -67,3 +67,29 @@ components:
67
67
properties :
68
68
qux :
69
69
type : boolean
70
+ FooUnion :
71
+ oneOf :
72
+ - $ref : ' #/components/schemas/BarUnion'
73
+ - $ref : ' #/components/schemas/BazUnion'
74
+ discriminator :
75
+ propertyName : id
76
+ mapping :
77
+ bar : ' #/components/schemas/BarUnion'
78
+ baz : ' #/components/schemas/BazUnion'
79
+ BarUnion :
80
+ type : object
81
+ properties :
82
+ id :
83
+ type : string
84
+ bar :
85
+ type : string
86
+ BazUnion :
87
+ type : object
88
+ properties :
89
+ id :
90
+ type : string
91
+ baz :
92
+ type : string
93
+ QuxExtend : # this is a schema that extends the FooUnion schema
94
+ allOf :
95
+ - $ref : ' #/components/schemas/FooUnion'
Original file line number Diff line number Diff line change @@ -372,29 +372,38 @@ const parseAllOf = ({
372
372
const values = discriminatorValues (
373
373
state . $ref ,
374
374
ref . discriminator . mapping ,
375
+ // If the ref has oneOf, we only use the schema name as the value
376
+ // only if current schema is part of the oneOf. Else it is extending
377
+ // the ref schema
378
+ ref . oneOf
379
+ ? ( ) => ref . oneOf ! . some ( ( o ) => '$ref' in o && o . $ref === state . $ref )
380
+ : undefined ,
375
381
) ;
376
- const valueSchemas : ReadonlyArray < IR . SchemaObject > = values . map (
377
- ( value ) => ( {
378
- const : value ,
379
- type : 'string' ,
380
- } ) ,
381
- ) ;
382
- const irDiscriminatorSchema : IR . SchemaObject = {
383
- properties : {
384
- [ ref . discriminator . propertyName ] :
385
- valueSchemas . length > 1
386
- ? {
387
- items : valueSchemas ,
388
- logicalOperator : 'or' ,
389
- }
390
- : valueSchemas [ 0 ] ! ,
391
- } ,
392
- type : 'object' ,
393
- } ;
394
- if ( ref . required ?. includes ( ref . discriminator . propertyName ) ) {
395
- irDiscriminatorSchema . required = [ ref . discriminator . propertyName ] ;
382
+
383
+ if ( values . length > 0 ) {
384
+ const valueSchemas : ReadonlyArray < IR . SchemaObject > = values . map (
385
+ ( value ) => ( {
386
+ const : value ,
387
+ type : 'string' ,
388
+ } ) ,
389
+ ) ;
390
+ const irDiscriminatorSchema : IR . SchemaObject = {
391
+ properties : {
392
+ [ ref . discriminator . propertyName ] :
393
+ valueSchemas . length > 1
394
+ ? {
395
+ items : valueSchemas ,
396
+ logicalOperator : 'or' ,
397
+ }
398
+ : valueSchemas [ 0 ] ! ,
399
+ } ,
400
+ type : 'object' ,
401
+ } ;
402
+ if ( ref . required ?. includes ( ref . discriminator . propertyName ) ) {
403
+ irDiscriminatorSchema . required = [ ref . discriminator . propertyName ] ;
404
+ }
405
+ schemaItems . push ( irDiscriminatorSchema ) ;
396
406
}
397
- schemaItems . push ( irDiscriminatorSchema ) ;
398
407
}
399
408
400
409
if ( ! state . circularReferenceTracker . has ( compositionSchema . $ref ) ) {
Original file line number Diff line number Diff line change @@ -405,29 +405,37 @@ const parseAllOf = ({
405
405
const values = discriminatorValues (
406
406
state . $ref ,
407
407
ref . discriminator . mapping ,
408
+ // If the ref has oneOf, we only use the schema name as the value
409
+ // only if current schema is part of the oneOf. Else it is extending
410
+ // the ref schema
411
+ ref . oneOf
412
+ ? ( ) => ref . oneOf ! . some ( ( o ) => '$ref' in o && o . $ref === state . $ref )
413
+ : undefined ,
408
414
) ;
409
- const valueSchemas : ReadonlyArray < IR . SchemaObject > = values . map (
410
- ( value ) => ( {
411
- const : value ,
412
- type : 'string' ,
413
- } ) ,
414
- ) ;
415
- const irDiscriminatorSchema : IR . SchemaObject = {
416
- properties : {
417
- [ ref . discriminator . propertyName ] :
418
- valueSchemas . length > 1
419
- ? {
420
- items : valueSchemas ,
421
- logicalOperator : 'or' ,
422
- }
423
- : valueSchemas [ 0 ] ! ,
424
- } ,
425
- type : 'object' ,
426
- } ;
427
- if ( ref . required ?. includes ( ref . discriminator . propertyName ) ) {
428
- irDiscriminatorSchema . required = [ ref . discriminator . propertyName ] ;
415
+ if ( values . length > 0 ) {
416
+ const valueSchemas : ReadonlyArray < IR . SchemaObject > = values . map (
417
+ ( value ) => ( {
418
+ const : value ,
419
+ type : 'string' ,
420
+ } ) ,
421
+ ) ;
422
+ const irDiscriminatorSchema : IR . SchemaObject = {
423
+ properties : {
424
+ [ ref . discriminator . propertyName ] :
425
+ valueSchemas . length > 1
426
+ ? {
427
+ items : valueSchemas ,
428
+ logicalOperator : 'or' ,
429
+ }
430
+ : valueSchemas [ 0 ] ! ,
431
+ } ,
432
+ type : 'object' ,
433
+ } ;
434
+ if ( ref . required ?. includes ( ref . discriminator . propertyName ) ) {
435
+ irDiscriminatorSchema . required = [ ref . discriminator . propertyName ] ;
436
+ }
437
+ schemaItems . push ( irDiscriminatorSchema ) ;
429
438
}
430
- schemaItems . push ( irDiscriminatorSchema ) ;
431
439
}
432
440
433
441
if ( ! state . circularReferenceTracker . has ( compositionSchema . $ref ) ) {
Original file line number Diff line number Diff line change @@ -3,6 +3,7 @@ import { refToName } from '../../../utils/ref';
3
3
export const discriminatorValues = (
4
4
$ref : string ,
5
5
mapping ?: Record < string , string > ,
6
+ shouldUseRefAsValue ?: ( ) => boolean ,
6
7
) : ReadonlyArray < string > => {
7
8
const values : Array < string > = [ ] ;
8
9
@@ -12,7 +13,7 @@ export const discriminatorValues = (
12
13
}
13
14
}
14
15
15
- if ( ! values . length ) {
16
+ if ( ! values . length && ( ! shouldUseRefAsValue || shouldUseRefAsValue ( ) ) ) {
16
17
return [ refToName ( $ref ) ] ;
17
18
}
18
19
You can’t perform that action at this time.
0 commit comments