Skip to content

Commit d1cd295

Browse files
committed
adds discriminator mappings to the ObjectSerializer
This allows (de)serializing models using `oneOf` via the union type name, returning the proper sub-type. Part of OpenAPITools#10145.
1 parent 72cec10 commit d1cd295

File tree

1 file changed

+46
-12
lines changed
  • modules/openapi-generator/src/main/resources/typescript-node

1 file changed

+46
-12
lines changed

modules/openapi-generator/src/main/resources/typescript-node/models.mustache

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -62,12 +62,34 @@ let typeMap: {[index: string]: any} = {
6262
{{#models}}
6363
{{#model}}
6464
{{^isEnum}}
65+
{{^discriminator}}
6566
"{{classname}}": {{classname}},
67+
{{/discriminator}}
6668
{{/isEnum}}
6769
{{/model}}
6870
{{/models}}
6971
}
7072

73+
let unionMap: {[index: string]: {discriminator: string, mapping: Record<string, string>}} = {
74+
{{#models}}
75+
{{#model}}
76+
{{^isEnum}}
77+
{{#discriminator}}
78+
"{{classname}}": {
79+
"discriminator": "{{discriminator.propertyName}}",
80+
"mapping": {
81+
{{#mappedModels}}
82+
"{{mappingName}}": "{{modelName}}",
83+
{{/mappedModels}}
84+
}
85+
},
86+
{{/discriminator}}
87+
{{/isEnum}}
88+
{{/model}}
89+
{{/models}}
90+
}
91+
92+
7193
export class ObjectSerializer {
7294
public static findCorrectType(data: any, expectedType: string) {
7395
if (data == undefined) {
@@ -81,24 +103,36 @@ export class ObjectSerializer {
81103
return expectedType;
82104
}
83105

84-
if (!typeMap[expectedType]) {
106+
if (!typeMap[expectedType] && !unionMap[expectedType]) {
85107
return expectedType; // w/e we don't know the type
86108
}
87109
88-
// Check the discriminator
89-
let discriminatorProperty = typeMap[expectedType].discriminator;
90-
if (discriminatorProperty == null) {
91-
return expectedType; // the type does not have a discriminator. use it.
110+
if (unionMap[expectedType]) {
111+
const discriminator = unionMap[expectedType];
112+
let discriminatorValue = data[discriminator.discriminator];
113+
if (discriminatorValue && discriminator.mapping[discriminatorValue]) {
114+
// found a subclass
115+
return discriminator.mapping[discriminatorValue];
116+
} else if (discriminatorValue && typeMap[discriminatorValue]) {
117+
// legacy fallback behavior
118+
return typeMap[discriminatorValue];
119+
}
92120
} else {
93-
if (data[discriminatorProperty]) {
94-
var discriminatorType = data[discriminatorProperty];
95-
if(typeMap[discriminatorType]){
96-
return discriminatorType; // use the type given in the discriminator
121+
// Check the discriminator
122+
let discriminatorProperty = typeMap[expectedType].discriminator;
123+
if (discriminatorProperty == null) {
124+
return expectedType; // the type does not have a discriminator. use it.
125+
} else {
126+
if (data[discriminatorProperty]) {
127+
var discriminatorType = data[discriminatorProperty];
128+
if(typeMap[discriminatorType]){
129+
return discriminatorType; // use the type given in the discriminator
130+
} else {
131+
return expectedType; // discriminator did not map to a type
132+
}
97133
} else {
98-
return expectedType; // discriminator did not map to a type
134+
return expectedType; // discriminator was not present (or an empty string)
99135
}
100-
} else {
101-
return expectedType; // discriminator was not present (or an empty string)
102136
}
103137
}
104138
}

0 commit comments

Comments
 (0)