Skip to content

Commit 6e390f9

Browse files
committed
fix: support discriminator mapping 1-n
fixes #1111
1 parent 81a44a2 commit 6e390f9

File tree

2 files changed

+28
-10
lines changed

2 files changed

+28
-10
lines changed

src/services/OpenAPIParser.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -296,16 +296,16 @@ export class OpenAPIParser {
296296
* returns map of definition pointer to definition name
297297
* @param $refs array of references to find derived from
298298
*/
299-
findDerived($refs: string[]): Dict<string> {
300-
const res: Dict<string> = {};
299+
findDerived($refs: string[]): Dict<string[]> {
300+
const res: Dict<string[]> = {};
301301
const schemas = (this.spec.components && this.spec.components.schemas) || {};
302302
for (const defName in schemas) {
303303
const def = this.deref(schemas[defName]);
304304
if (
305305
def.allOf !== undefined &&
306306
def.allOf.find(obj => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1)
307307
) {
308-
res['#/components/schemas/' + defName] = def['x-discriminator-value'] || defName;
308+
res['#/components/schemas/' + defName] = [def['x-discriminator-value'] || defName];
309309
}
310310
}
311311
return res;

src/services/models/Schema.ts

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -216,27 +216,45 @@ export class SchemaModel {
216216
) {
217217
const discriminator = getDiscriminator(schema)!;
218218
this.discriminatorProp = discriminator.propertyName;
219-
const derived = parser.findDerived([...(schema.parentRefs || []), this.pointer]);
219+
const inversedMapping = parser.findDerived([...(schema.parentRefs || []), this.pointer]);
220220

221221
if (schema.oneOf) {
222222
for (const variant of schema.oneOf) {
223223
if (variant.$ref === undefined) {
224224
continue;
225225
}
226226
const name = JsonPointer.baseName(variant.$ref);
227-
derived[variant.$ref] = name;
227+
inversedMapping[variant.$ref] = [name];
228228
}
229229
}
230230

231231
const mapping = discriminator.mapping || {};
232232
for (const name in mapping) {
233-
derived[mapping[name]] = name;
233+
const $ref = mapping[name];
234+
235+
if (Array.isArray(inversedMapping[$ref])) {
236+
inversedMapping[$ref].push(name);
237+
} else {
238+
inversedMapping[$ref] = [name];
239+
}
240+
}
241+
242+
const refs: Array<{ $ref; name }> = [];
243+
244+
for (const $ref of Object.keys(inversedMapping)) {
245+
const names = inversedMapping[$ref];
246+
if (Array.isArray(names)) {
247+
for (const name of names) {
248+
refs.push({ $ref, name });
249+
}
250+
} else {
251+
refs.push({ $ref, name: names });
252+
}
234253
}
235254

236-
const refs = Object.keys(derived);
237-
this.oneOf = refs.map(ref => {
238-
const innerSchema = new SchemaModel(parser, parser.byRef(ref)!, ref, this.options, true);
239-
innerSchema.title = derived[ref];
255+
this.oneOf = refs.map(({ $ref, name }) => {
256+
const innerSchema = new SchemaModel(parser, parser.byRef($ref)!, $ref, this.options, true);
257+
innerSchema.title = name;
240258
return innerSchema;
241259
});
242260
}

0 commit comments

Comments
 (0)