Skip to content

Commit 2475bad

Browse files
committed
try and improve how circular references are handled by moving them to their own schema.
1 parent 40b0535 commit 2475bad

File tree

1 file changed

+40
-13
lines changed

1 file changed

+40
-13
lines changed

src/Convertor.js

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -110,12 +110,26 @@ class Convertor {
110110

111111
closeCircularReferences() {
112112
const report = this.isCyclic(this.schema, true);
113-
113+
let seenSchemas = new WeakMap();
114+
let i = 0;
114115
for (const reportDetail of report) {
115116
try {
116-
this.closingTheCircle(this.schema, reportDetail.duplicate, {
117-
description: `This was found to be a circular reference and has been closed off to avoid repetitive processing. This closure was made by json-schema-for-openapi v${packageData.version} - please open an issue at: ${packageData.bugs.url}`,
118-
});
117+
const dupeName = `cyclic_${i}`;
118+
if (seenSchemas.has(reportDetail.instance)) {
119+
const value = {
120+
$ref: `#/components/schemas/${seenSchemas.get(
121+
reportDetail.instance
122+
)}`,
123+
};
124+
125+
this.closingTheCircle(this.schema, reportDetail.duplicate, value);
126+
} else {
127+
seenSchemas.set(reportDetail.instance, dupeName);
128+
this.addToComponents(dupeName, reportDetail.instance);
129+
const value = { $ref: `#/components/schemas/${dupeName}` };
130+
this.closingTheCircle(this.schema, reportDetail.duplicate, value);
131+
}
132+
i++;
119133
} catch (err) {
120134
console.error(err);
121135
throw err;
@@ -330,15 +344,16 @@ class Convertor {
330344

331345
traverse(schema.if, traversal);
332346

333-
if (this.components.schemas) {
334-
Object.assign(this.components.schemas, {
335-
[ifSchemaRefName]: schema.if,
336-
});
337-
} else {
338-
Object.assign(this.components, {
339-
schemas: { [ifSchemaRefName]: schema.if },
340-
});
341-
}
347+
// if (this.components.schemas) {
348+
// Object.assign(this.components.schemas, {
349+
// [ifSchemaRefName]: schema.if,
350+
// });
351+
// } else {
352+
// Object.assign(this.components, {
353+
// schemas: { [ifSchemaRefName]: schema.if },
354+
// });
355+
// }
356+
this.addToComponents(ifSchemaRefName, schema.if);
342357

343358
if (schema?.then || schema?.else) {
344359
let oneOf = [];
@@ -579,6 +594,18 @@ class Convertor {
579594

580595
return bReturnReport ? oReturnVal.report : oReturnVal.found;
581596
}
597+
598+
addToComponents(schemaRefName, schema) {
599+
if (this.components.schemas) {
600+
Object.assign(this.components.schemas, {
601+
[schemaRefName]: schema,
602+
});
603+
} else {
604+
Object.assign(this.components, {
605+
schemas: { [schemaRefName]: schema },
606+
});
607+
}
608+
}
582609
}
583610

584611
module.exports = Convertor;

0 commit comments

Comments
 (0)