@apidevtools/json-schema-ref-parser 12.0.0 → 12.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -174,24 +174,46 @@ function dereference$Ref($ref, path, pathFromRoot, parents, processedObjects, de
174
174
  //
175
175
  // If the cached object however is _not_ circular and there are additional keys alongside our
176
176
  // `$ref` pointer here we should merge them back in and return that.
177
- if (cache.circular) {
177
+ if (!cache.circular) {
178
+ const refKeys = Object.keys($ref);
179
+ if (refKeys.length > 1) {
180
+ const extraKeys = {};
181
+ for (const key of refKeys) {
182
+ if (key !== "$ref" && !(key in cache.value)) {
183
+ // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
184
+ extraKeys[key] = $ref[key];
185
+ }
186
+ }
187
+ return {
188
+ circular: cache.circular,
189
+ value: Object.assign({}, cache.value, extraKeys),
190
+ };
191
+ }
178
192
  return cache;
179
193
  }
180
- const refKeys = Object.keys($ref);
181
- if (refKeys.length > 1) {
182
- const extraKeys = {};
183
- for (const key of refKeys) {
184
- if (key !== "$ref" && !(key in cache.value)) {
185
- // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
186
- extraKeys[key] = $ref[key];
187
- }
194
+ // If both our cached value and our incoming `$ref` are the same then we can return what we
195
+ // got out of the cache, otherwise we should re-process this value. We need to do this because
196
+ // the current dereference caching mechanism doesn't take into account that `$ref` are neither
197
+ // unique or reference the same file.
198
+ //
199
+ // For example if `schema.yaml` references `definitions/child.yaml` and
200
+ // `definitions/parent.yaml` references `child.yaml` then `$ref: 'child.yaml'` may get cached
201
+ // for `definitions/child.yaml`, resulting in `schema.yaml` being having an invalid reference
202
+ // to `child.yaml`.
203
+ //
204
+ // This check is not perfect and the design of the dereference caching mechanism needs a total
205
+ // overhaul.
206
+ if (typeof cache.value === 'object' && '$ref' in cache.value && '$ref' in $ref) {
207
+ if (cache.value.$ref === $ref.$ref) {
208
+ return cache;
209
+ }
210
+ else {
211
+ // no-op
188
212
  }
189
- return {
190
- circular: cache.circular,
191
- value: Object.assign({}, cache.value, extraKeys),
192
- };
193
213
  }
194
- return cache;
214
+ else {
215
+ return cache;
216
+ }
195
217
  }
196
218
  const pointer = $refs._resolve($refPath, path, options);
197
219
  if (pointer === null) {
@@ -220,26 +220,46 @@ function dereference$Ref<S extends object = JSONSchema, O extends ParserOptions<
220
220
  //
221
221
  // If the cached object however is _not_ circular and there are additional keys alongside our
222
222
  // `$ref` pointer here we should merge them back in and return that.
223
- if (cache.circular) {
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
+ }
232
+ }
233
+ return {
234
+ circular: cache.circular,
235
+ value: Object.assign({}, cache.value, extraKeys),
236
+ };
237
+ }
238
+
224
239
  return cache;
225
240
  }
226
241
 
227
- const refKeys = Object.keys($ref);
228
- if (refKeys.length > 1) {
229
- const extraKeys = {};
230
- for (const key of refKeys) {
231
- if (key !== "$ref" && !(key in cache.value)) {
232
- // @ts-expect-error TS(7053): Element implicitly has an 'any' type because expre... Remove this comment to see the full error message
233
- extraKeys[key] = $ref[key];
234
- }
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
235
259
  }
236
- return {
237
- circular: cache.circular,
238
- value: Object.assign({}, cache.value, extraKeys),
239
- };
260
+ } else {
261
+ return cache;
240
262
  }
241
-
242
- return cache;
243
263
  }
244
264
 
245
265
  const pointer = $refs._resolve($refPath, path, options);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apidevtools/json-schema-ref-parser",
3
- "version": "12.0.0",
3
+ "version": "12.0.1",
4
4
  "description": "Parse, Resolve, and Dereference JSON Schema $ref pointers",
5
5
  "scripts": {
6
6
  "prepublishOnly": "yarn build",