Skip to content

Commit d26fe26

Browse files
committed
fix(recursion): resolve infinite loop with recursive links
1 parent 600f02d commit d26fe26

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

src/dereferencer.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ export default class Dereferencer {
157157
const refProm = referenceResolver.resolve(ref, this.options.rootSchema);
158158
proms.push(refProm);
159159
fetched = await refProm as JSONSchema;
160+
this.refCache[ref] = fetched
160161
}
161162

162163
if (this.options.recursive === true && fetched !== true && fetched !== false && ref !== "#") {

src/index.test.ts

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import {inspect} from 'util';
21
import Dereferencer, { NonStringRefError } from "./index";
32
import { Properties, JSONSchemaObject, JSONSchema } from "@json-schema-tools/meta-schema";
43

@@ -169,6 +168,70 @@ describe("Dereferencer", () => {
169168
expect(oneOfs[0].properties.contains).toBe(dereffed);
170169
});
171170

171+
it("does not get stuck on a recursive ", async () => {
172+
expect.assertions(1);
173+
const dereferencer = new Dereferencer({
174+
definitions: {
175+
node: {
176+
type: "object",
177+
properties: {
178+
name: {
179+
type: "string"
180+
},
181+
children: {
182+
type: "array",
183+
items: {
184+
$ref: "#/definitions/node"
185+
}
186+
}
187+
}
188+
}
189+
},
190+
type: "object",
191+
properties: {
192+
tree: {
193+
title: "Recursive references",
194+
$ref: "#/definitions/node"
195+
}
196+
}
197+
});
198+
199+
const dereffed = await dereferencer.resolve();
200+
201+
202+
const recursiveChildren = {
203+
type: 'array',
204+
items: {
205+
type: 'object',
206+
properties: {
207+
name: {
208+
type: 'string'
209+
},
210+
children: {}
211+
}
212+
},
213+
};
214+
recursiveChildren.items.properties.children = recursiveChildren
215+
216+
const expected = {
217+
type: "object",
218+
properties: {
219+
tree: {
220+
title: "Recursive references",
221+
type: "object",
222+
properties: {
223+
name: {
224+
type: 'string'
225+
},
226+
children: recursiveChildren
227+
}
228+
},
229+
}
230+
}
231+
232+
expect(dereffed).toStrictEqual(expected);
233+
});
234+
172235
it("can deal with root refs-to-ref as url, metaschema on master", async () => {
173236
expect.assertions(8);
174237
const dereferencer = new Dereferencer({

0 commit comments

Comments
 (0)