@speclynx/apidom-reference 3.1.0 → 3.2.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.
@@ -129,16 +129,22 @@ class OpenAPI2DereferenceVisitor {
129
129
  const type = referencingElement.element;
130
130
  const codeFrame = toYAML(referencingElement);
131
131
 
132
- // find element location: tree search for entry documents, visitor path for external
132
+ // find element location by identity in the document tree.
133
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
134
+ // falls back to visitorPath which may produce an incomplete path when
135
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
133
136
  let location;
134
- traverse(this.reference.value.result, {
135
- enter: p => {
136
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
137
- location = p.formatPath();
138
- p.stop();
137
+ const root = this.reference.value.result;
138
+ if (isElement(root)) {
139
+ traverse(root, {
140
+ enter: p => {
141
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
142
+ location = p.formatPath();
143
+ p.stop();
144
+ }
139
145
  }
140
- }
141
- });
146
+ });
147
+ }
142
148
  location ??= visitorPath.formatPath();
143
149
  const hop = {
144
150
  uri,
@@ -206,6 +212,7 @@ class OpenAPI2DereferenceVisitor {
206
212
  return;
207
213
  }
208
214
  const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
215
+ const indirectionsSize = this.indirections.length;
209
216
  try {
210
217
  const reference = await this.toReference(toValue(referencingElement.$ref));
211
218
  this.indirections.push(referencingElement);
@@ -266,7 +273,6 @@ class OpenAPI2DereferenceVisitor {
266
273
  });
267
274
  const replacer = this.options.dereference.strategyOpts['openapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
268
275
  const replacement = replacer(refElement);
269
- this.indirections.pop();
270
276
  path.replaceWith(replacement);
271
277
  return;
272
278
  }
@@ -298,7 +304,6 @@ class OpenAPI2DereferenceVisitor {
298
304
  });
299
305
  directAncestors.delete(referencingElement);
300
306
  }
301
- this.indirections.pop();
302
307
 
303
308
  /**
304
309
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -319,6 +324,8 @@ class OpenAPI2DereferenceVisitor {
319
324
  } catch (error) {
320
325
  const $ref = toValue(referencingElement.$ref);
321
326
  this.handleError(`Error while dereferencing Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
327
+ } finally {
328
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
322
329
  }
323
330
  }
324
331
  async PathItemElement(path) {
@@ -349,6 +356,7 @@ class OpenAPI2DereferenceVisitor {
349
356
  return;
350
357
  }
351
358
  const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
359
+ const indirectionsSize = this.indirections.length;
352
360
  try {
353
361
  const reference = await this.toReference(toValue(referencingElement.$ref));
354
362
  this.indirections.push(referencingElement);
@@ -399,7 +407,6 @@ class OpenAPI2DereferenceVisitor {
399
407
  });
400
408
  const replacer = this.options.dereference.strategyOpts['openapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
401
409
  const replacement = replacer(refElement);
402
- this.indirections.pop();
403
410
  path.replaceWith(replacement);
404
411
  return;
405
412
  }
@@ -433,7 +440,6 @@ class OpenAPI2DereferenceVisitor {
433
440
  // remove referencing reference from ancestors lineage
434
441
  directAncestors.delete(referencingElement);
435
442
  }
436
- this.indirections.pop();
437
443
 
438
444
  /**
439
445
  * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
@@ -465,6 +471,8 @@ class OpenAPI2DereferenceVisitor {
465
471
  } catch (error) {
466
472
  const $ref = toValue(referencingElement.$ref);
467
473
  this.handleError(`Error while dereferencing Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
474
+ } finally {
475
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
468
476
  }
469
477
  }
470
478
  async JSONReferenceElement(path) {
@@ -492,6 +500,7 @@ class OpenAPI2DereferenceVisitor {
492
500
  return;
493
501
  }
494
502
  const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
503
+ const indirectionsSize = this.indirections.length;
495
504
  try {
496
505
  const reference = await this.toReference(toValue(referencingElement.$ref));
497
506
  this.indirections.push(referencingElement);
@@ -552,7 +561,6 @@ class OpenAPI2DereferenceVisitor {
552
561
  });
553
562
  const replacer = this.options.dereference.strategyOpts['openapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
554
563
  const replacement = replacer(refElement);
555
- this.indirections.pop();
556
564
  path.replaceWith(replacement);
557
565
  return;
558
566
  }
@@ -586,7 +594,6 @@ class OpenAPI2DereferenceVisitor {
586
594
  // remove referencing reference from ancestors lineage
587
595
  directAncestors.delete(referencingElement);
588
596
  }
589
- this.indirections.pop();
590
597
 
591
598
  /**
592
599
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -607,6 +614,8 @@ class OpenAPI2DereferenceVisitor {
607
614
  } catch (error) {
608
615
  const $ref = toValue(referencingElement.$ref);
609
616
  this.handleError(`Error while dereferencing JSON Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
617
+ } finally {
618
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
610
619
  }
611
620
  }
612
621
  }
@@ -137,16 +137,22 @@ class OpenAPI3_0DereferenceVisitor {
137
137
  const type = referencingElement.element;
138
138
  const codeFrame = (0, _apidomCore.toYAML)(referencingElement);
139
139
 
140
- // find element location: tree search for entry documents, visitor path for external
140
+ // find element location by identity in the document tree.
141
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
142
+ // falls back to visitorPath which may produce an incomplete path when
143
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
141
144
  let location;
142
- (0, _apidomTraverse.traverse)(this.reference.value.result, {
143
- enter: p => {
144
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
145
- location = p.formatPath();
146
- p.stop();
145
+ const root = this.reference.value.result;
146
+ if ((0, _apidomDatamodel.isElement)(root)) {
147
+ (0, _apidomTraverse.traverse)(root, {
148
+ enter: p => {
149
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
150
+ location = p.formatPath();
151
+ p.stop();
152
+ }
147
153
  }
148
- }
149
- });
154
+ });
155
+ }
150
156
  location ??= visitorPath.formatPath();
151
157
  const hop = {
152
158
  uri,
@@ -214,6 +220,7 @@ class OpenAPI3_0DereferenceVisitor {
214
220
  return;
215
221
  }
216
222
  const $refBaseURI = url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
223
+ const indirectionsSize = this.indirections.length;
217
224
  try {
218
225
  const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
219
226
  this.indirections.push(referencingElement);
@@ -274,7 +281,6 @@ class OpenAPI3_0DereferenceVisitor {
274
281
  });
275
282
  const replacer = this.options.dereference.strategyOpts['openapi-3-0']?.circularReplacer ?? this.options.dereference.circularReplacer;
276
283
  const replacement = replacer(refElement);
277
- this.indirections.pop();
278
284
  path.replaceWith(replacement);
279
285
  return;
280
286
  }
@@ -308,7 +314,6 @@ class OpenAPI3_0DereferenceVisitor {
308
314
  // remove referencing reference from ancestors lineage
309
315
  directAncestors.delete(referencingElement);
310
316
  }
311
- this.indirections.pop();
312
317
 
313
318
  /**
314
319
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -329,6 +334,8 @@ class OpenAPI3_0DereferenceVisitor {
329
334
  } catch (error) {
330
335
  const $ref = (0, _apidomCore.toValue)(referencingElement.$ref);
331
336
  this.handleError(`Error while dereferencing Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
337
+ } finally {
338
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
332
339
  }
333
340
  }
334
341
  async PathItemElement(path) {
@@ -359,6 +366,7 @@ class OpenAPI3_0DereferenceVisitor {
359
366
  return;
360
367
  }
361
368
  const $refBaseURI = url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
369
+ const indirectionsSize = this.indirections.length;
362
370
  try {
363
371
  const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
364
372
  this.indirections.push(referencingElement);
@@ -409,7 +417,6 @@ class OpenAPI3_0DereferenceVisitor {
409
417
  });
410
418
  const replacer = this.options.dereference.strategyOpts['openapi-3-0']?.circularReplacer ?? this.options.dereference.circularReplacer;
411
419
  const replacement = replacer(refElement);
412
- this.indirections.pop();
413
420
  path.replaceWith(replacement);
414
421
  return;
415
422
  }
@@ -443,7 +450,6 @@ class OpenAPI3_0DereferenceVisitor {
443
450
  // remove referencing reference from ancestors lineage
444
451
  directAncestors.delete(referencingElement);
445
452
  }
446
- this.indirections.pop();
447
453
 
448
454
  /**
449
455
  * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
@@ -474,6 +480,8 @@ class OpenAPI3_0DereferenceVisitor {
474
480
  } catch (error) {
475
481
  const $ref = (0, _apidomCore.toValue)(referencingElement.$ref);
476
482
  this.handleError(`Error while dereferencing Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
483
+ } finally {
484
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
477
485
  }
478
486
  }
479
487
  async LinkElement(path) {
@@ -130,16 +130,22 @@ class OpenAPI3_0DereferenceVisitor {
130
130
  const type = referencingElement.element;
131
131
  const codeFrame = toYAML(referencingElement);
132
132
 
133
- // find element location: tree search for entry documents, visitor path for external
133
+ // find element location by identity in the document tree.
134
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
135
+ // falls back to visitorPath which may produce an incomplete path when
136
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
134
137
  let location;
135
- traverse(this.reference.value.result, {
136
- enter: p => {
137
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
138
- location = p.formatPath();
139
- p.stop();
138
+ const root = this.reference.value.result;
139
+ if (isElement(root)) {
140
+ traverse(root, {
141
+ enter: p => {
142
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
143
+ location = p.formatPath();
144
+ p.stop();
145
+ }
140
146
  }
141
- }
142
- });
147
+ });
148
+ }
143
149
  location ??= visitorPath.formatPath();
144
150
  const hop = {
145
151
  uri,
@@ -207,6 +213,7 @@ class OpenAPI3_0DereferenceVisitor {
207
213
  return;
208
214
  }
209
215
  const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
216
+ const indirectionsSize = this.indirections.length;
210
217
  try {
211
218
  const reference = await this.toReference(toValue(referencingElement.$ref));
212
219
  this.indirections.push(referencingElement);
@@ -267,7 +274,6 @@ class OpenAPI3_0DereferenceVisitor {
267
274
  });
268
275
  const replacer = this.options.dereference.strategyOpts['openapi-3-0']?.circularReplacer ?? this.options.dereference.circularReplacer;
269
276
  const replacement = replacer(refElement);
270
- this.indirections.pop();
271
277
  path.replaceWith(replacement);
272
278
  return;
273
279
  }
@@ -301,7 +307,6 @@ class OpenAPI3_0DereferenceVisitor {
301
307
  // remove referencing reference from ancestors lineage
302
308
  directAncestors.delete(referencingElement);
303
309
  }
304
- this.indirections.pop();
305
310
 
306
311
  /**
307
312
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -322,6 +327,8 @@ class OpenAPI3_0DereferenceVisitor {
322
327
  } catch (error) {
323
328
  const $ref = toValue(referencingElement.$ref);
324
329
  this.handleError(`Error while dereferencing Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
330
+ } finally {
331
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
325
332
  }
326
333
  }
327
334
  async PathItemElement(path) {
@@ -352,6 +359,7 @@ class OpenAPI3_0DereferenceVisitor {
352
359
  return;
353
360
  }
354
361
  const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
362
+ const indirectionsSize = this.indirections.length;
355
363
  try {
356
364
  const reference = await this.toReference(toValue(referencingElement.$ref));
357
365
  this.indirections.push(referencingElement);
@@ -402,7 +410,6 @@ class OpenAPI3_0DereferenceVisitor {
402
410
  });
403
411
  const replacer = this.options.dereference.strategyOpts['openapi-3-0']?.circularReplacer ?? this.options.dereference.circularReplacer;
404
412
  const replacement = replacer(refElement);
405
- this.indirections.pop();
406
413
  path.replaceWith(replacement);
407
414
  return;
408
415
  }
@@ -436,7 +443,6 @@ class OpenAPI3_0DereferenceVisitor {
436
443
  // remove referencing reference from ancestors lineage
437
444
  directAncestors.delete(referencingElement);
438
445
  }
439
- this.indirections.pop();
440
446
 
441
447
  /**
442
448
  * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
@@ -467,6 +473,8 @@ class OpenAPI3_0DereferenceVisitor {
467
473
  } catch (error) {
468
474
  const $ref = toValue(referencingElement.$ref);
469
475
  this.handleError(`Error while dereferencing Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
476
+ } finally {
477
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
470
478
  }
471
479
  }
472
480
  async LinkElement(path) {
@@ -142,16 +142,22 @@ class OpenAPI3_1DereferenceVisitor {
142
142
  const type = referencingElement.element;
143
143
  const codeFrame = (0, _apidomCore.toYAML)(referencingElement);
144
144
 
145
- // find element location: tree search for entry documents, visitor path for external
145
+ // find element location by identity in the document tree.
146
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
147
+ // falls back to visitorPath which may produce an incomplete path when
148
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
146
149
  let location;
147
- (0, _apidomTraverse.traverse)(this.reference.value.result, {
148
- enter: p => {
149
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
150
- location = p.formatPath();
151
- p.stop();
150
+ const root = this.reference.value.result;
151
+ if ((0, _apidomDatamodel.isElement)(root)) {
152
+ (0, _apidomTraverse.traverse)(root, {
153
+ enter: p => {
154
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
155
+ location = p.formatPath();
156
+ p.stop();
157
+ }
152
158
  }
153
- }
154
- });
159
+ });
160
+ }
155
161
  location ??= visitorPath.formatPath();
156
162
  const hop = {
157
163
  uri,
@@ -135,16 +135,22 @@ class OpenAPI3_1DereferenceVisitor {
135
135
  const type = referencingElement.element;
136
136
  const codeFrame = toYAML(referencingElement);
137
137
 
138
- // find element location: tree search for entry documents, visitor path for external
138
+ // find element location by identity in the document tree.
139
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
140
+ // falls back to visitorPath which may produce an incomplete path when
141
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
139
142
  let location;
140
- traverse(this.reference.value.result, {
141
- enter: p => {
142
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
143
- location = p.formatPath();
144
- p.stop();
143
+ const root = this.reference.value.result;
144
+ if (isElement(root)) {
145
+ traverse(root, {
146
+ enter: p => {
147
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
148
+ location = p.formatPath();
149
+ p.stop();
150
+ }
145
151
  }
146
- }
147
- });
152
+ });
153
+ }
148
154
  location ??= visitorPath.formatPath();
149
155
  const hop = {
150
156
  uri,