Skip to content

Commit

Permalink
fix: false-positive recursive detection with oneOf
Browse files Browse the repository at this point in the history
fixes #723, fixes #585
  • Loading branch information
RomanHotsiy committed Nov 27, 2018
1 parent e2d0cd5 commit 59eaa8d
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 20 deletions.
13 changes: 12 additions & 1 deletion src/services/OpenAPIParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,12 @@ export class OpenAPIParser {
return res;
}

exitParents(shema: MergedOpenAPISchema) {
for (const parent$ref of shema.parentRefs || []) {
this.exitRef({ $ref: parent$ref });
}
}

private hoistOneOfs(schema: OpenAPISchema) {
if (schema.allOf === undefined) {
return schema;
Expand All @@ -304,9 +310,14 @@ export class OpenAPIParser {
const afterAllOf = allOf.slice(i + 1);
return {
oneOf: sub.oneOf.map(part => {
return this.mergeAllOf({
const merged = this.mergeAllOf({
allOf: [...beforeAllOf, part, ...afterAllOf],
});

// each oneOf should be independent so exiting all the parent refs
// otherwise it will cause false-positive recursive detection
this.exitParents(merged);
return merged;
}),
};
}
Expand Down
42 changes: 23 additions & 19 deletions src/services/models/Schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,7 @@ export class SchemaModel {
this.init(parser, isChild);

parser.exitRef(schemaOrRef);

for (const parent$ref of this.schema.parentRefs || []) {
// exit all the refs visited during allOf traverse
parser.exitRef({ $ref: parent$ref });
}
parser.exitParents(this.schema);

if (options.showExtensions) {
this.extensions = extractExtensions(this.schema, options.showExtensions);
Expand Down Expand Up @@ -164,20 +160,28 @@ export class SchemaModel {
}

private initOneOf(oneOf: OpenAPISchema[], parser: OpenAPIParser) {
this.oneOf = oneOf!.map(
(variant, idx) =>
new SchemaModel(
parser,
// merge base schema into each of oneOf's subschemas
{
// variant may already have allOf so merge it to not get overwritten
...parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx),
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
} as OpenAPISchema,
this.pointer + '/oneOf/' + idx,
this.options,
),
);
this.oneOf = oneOf!.map((variant, idx) => {
const merged = parser.mergeAllOf(variant, this.pointer + '/oneOf/' + idx);

const schema = new SchemaModel(
parser,
// merge base schema into each of oneOf's subschemas
{
// variant may already have allOf so merge it to not get overwritten
...merged,
allOf: [{ ...this.schema, oneOf: undefined, anyOf: undefined }],
} as OpenAPISchema,
this.pointer + '/oneOf/' + idx,
this.options,
);

// each oneOf should be independent so exiting all the parent refs
// otherwise it will cause false-positive recursive detection
parser.exitParents(merged);

return schema;
});

this.displayType = this.oneOf
.map(schema => {
let name =
Expand Down

0 comments on commit 59eaa8d

Please sign in to comment.