Skip to content

Commit 9676218

Browse files
committed
fix: restructuring some of this confusing cache logic
1 parent d520ec2 commit 9676218

File tree

1 file changed

+34
-32
lines changed

1 file changed

+34
-32
lines changed

lib/dereference.ts

Lines changed: 34 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -220,43 +220,45 @@ function dereference$Ref<S extends object = JSONSchema, O extends ParserOptions<
220220
//
221221
// If the cached object however is _not_ circular and there are additional keys alongside our
222222
// `$ref` pointer here we should merge them back in and return that.
223-
if (cache.circular) {
224-
// If both our cached value and our incoming `$ref` are the same then we can return what we
225-
// got out of the cache, otherwise we should re-process this value. We need to do this because
226-
// the current dereference caching mechanism doesn't take into account that `$ref` are neither
227-
// unique or reference the same file.
228-
//
229-
// For example if `schema.yaml` references `definitions/child.yaml` and
230-
// `definitions/parent.yaml` references `child.yaml` then `$ref: 'child.yaml'` may get cached
231-
// for `definitions/child.yaml`, resulting in `schema.yaml` being having an invalid reference
232-
// to `child.yaml`.
233-
//
234-
// This check is not perfect and the design of the dereference caching mechanism needs a total
235-
// overhaul.
236-
if (typeof cache.value === 'object' && '$ref' in cache.value && '$ref' in $ref) {
237-
if (cache.value.$ref === $ref.$ref) {
238-
return cache;
239-
} else {
240-
// no-op
223+
if (!cache.circular) {
224+
const refKeys = Object.keys($ref);
225+
if (refKeys.length > 1) {
226+
const extraKeys = {};
227+
for (const key of refKeys) {
228+
if (key !== "$ref" && !(key in cache.value)) {
229+
// @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
230+
extraKeys[key] = $ref[key];
231+
}
241232
}
242-
} else {
243-
return cache;
233+
return {
234+
circular: cache.circular,
235+
value: Object.assign({}, cache.value, extraKeys),
236+
};
244237
}
238+
239+
return cache;
245240
}
246241

247-
const refKeys = Object.keys($ref);
248-
if (refKeys.length > 1) {
249-
const extraKeys = {};
250-
for (const key of refKeys) {
251-
if (key !== "$ref" && !(key in cache.value)) {
252-
// @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
253-
extraKeys[key] = $ref[key];
254-
}
242+
// If both our cached value and our incoming `$ref` are the same then we can return what we
243+
// got out of the cache, otherwise we should re-process this value. We need to do this because
244+
// the current dereference caching mechanism doesn't take into account that `$ref` are neither
245+
// unique or reference the same file.
246+
//
247+
// For example if `schema.yaml` references `definitions/child.yaml` and
248+
// `definitions/parent.yaml` references `child.yaml` then `$ref: 'child.yaml'` may get cached
249+
// for `definitions/child.yaml`, resulting in `schema.yaml` being having an invalid reference
250+
// to `child.yaml`.
251+
//
252+
// This check is not perfect and the design of the dereference caching mechanism needs a total
253+
// overhaul.
254+
if (typeof cache.value === 'object' && '$ref' in cache.value && '$ref' in $ref) {
255+
if (cache.value.$ref === $ref.$ref) {
256+
return cache;
257+
} else {
258+
// no-op
255259
}
256-
return {
257-
circular: cache.circular,
258-
value: Object.assign({}, cache.value, extraKeys),
259-
};
260+
} else {
261+
return cache;
260262
}
261263
}
262264

0 commit comments

Comments
 (0)