@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.
package/CHANGELOG.md CHANGED
@@ -3,6 +3,22 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [3.2.1](https://github.com/speclynx/apidom/compare/v3.2.0...v3.2.1) (2026-03-09)
7
+
8
+ ### Bug Fixes
9
+
10
+ - fix issues preventing integrating with Language Service ([#143](https://github.com/speclynx/apidom/issues/143)) ([26480d7](https://github.com/speclynx/apidom/commit/26480d7a495fa57da8b39120a73f64ab2d9d61bf))
11
+
12
+ # [3.2.0](https://github.com/speclynx/apidom/compare/v3.1.0...v3.2.0) (2026-03-08)
13
+
14
+ ### Bug Fixes
15
+
16
+ - **referece:** fix indirection leak in dereference strategies ([#141](https://github.com/speclynx/apidom/issues/141)) ([57ec415](https://github.com/speclynx/apidom/commit/57ec4153baade728681e43223d058ef35b707212))
17
+
18
+ ### Features
19
+
20
+ - add keywords to all package.json files for npm search discoverability ([#142](https://github.com/speclynx/apidom/issues/142)) ([f6c2b38](https://github.com/speclynx/apidom/commit/f6c2b387db48427f0f12e3019e1bdb8d7e05dd00))
21
+
6
22
  # [3.1.0](https://github.com/speclynx/apidom/compare/v3.0.0...v3.1.0) (2026-03-08)
7
23
 
8
24
  ### Features
@@ -750,15 +750,22 @@ class ApiDOMDereferenceVisitor {
750
750
  const isEntryDocument = _util_url_ts__WEBPACK_IMPORTED_MODULE_12__.stripHash(this.reference.refSet?.rootRef?.uri ?? '') === this.reference.uri;
751
751
  const uri = this.reference.uri;
752
752
  const type = referencingElement.element;
753
+ // find element location by identity in the document tree.
754
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
755
+ // falls back to visitorPath which may produce an incomplete path when
756
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
753
757
  let location;
754
- (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_8__.traverse)(this.reference.value.result, {
755
- enter(p) {
756
- if (p.node === referencingElement) {
757
- location = p.formatPath();
758
- p.stop();
758
+ const root = this.reference.value.result;
759
+ if ((0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__.isElement)(root)) {
760
+ (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_8__.traverse)(root, {
761
+ enter(p) {
762
+ if (p.node === referencingElement) {
763
+ location = p.formatPath();
764
+ p.stop();
765
+ }
759
766
  }
760
- }
761
- });
767
+ });
768
+ }
762
769
  location ??= visitorPath.formatPath();
763
770
  const codeFrame = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_7__["default"])(referencingElement);
764
771
  const hop = {
@@ -1519,16 +1526,22 @@ class Arazzo1DereferenceVisitor {
1519
1526
  const type = referencingElement.element;
1520
1527
  const codeFrame = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_6__["default"])(referencingElement);
1521
1528
 
1522
- // find element location: tree search for entry documents, visitor path for external
1529
+ // find element location by identity in the document tree.
1530
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
1531
+ // falls back to visitorPath which may produce an incomplete path when
1532
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
1523
1533
  let location;
1524
- (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_8__.traverse)(this.reference.value.result, {
1525
- enter: p => {
1526
- if (p.node === referencingElement) {
1527
- location = p.formatPath();
1528
- p.stop();
1534
+ const root = this.reference.value.result;
1535
+ if ((0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__.isElement)(root)) {
1536
+ (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_8__.traverse)(root, {
1537
+ enter(p) {
1538
+ if (p.node === referencingElement) {
1539
+ location = p.formatPath();
1540
+ p.stop();
1541
+ }
1529
1542
  }
1530
- }
1531
- });
1543
+ });
1544
+ }
1532
1545
  location ??= visitorPath.formatPath();
1533
1546
  const hop = {
1534
1547
  uri,
@@ -1653,6 +1666,7 @@ class Arazzo1DereferenceVisitor {
1653
1666
  path.skip();
1654
1667
  return;
1655
1668
  }
1669
+ const indirectionsSize = this.indirections.length;
1656
1670
  try {
1657
1671
  // compute baseURI using rules around $id and $ref keywords
1658
1672
  let reference = await this.toReference(_util_url_ts__WEBPACK_IMPORTED_MODULE_22__.unsanitize(this.reference.uri));
@@ -1797,7 +1811,6 @@ class Arazzo1DereferenceVisitor {
1797
1811
  });
1798
1812
  const replacer = this.options.dereference.strategyOpts['arazzo-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
1799
1813
  const replacement = replacer(refElement);
1800
- this.indirections.pop();
1801
1814
  path.replaceWith(replacement);
1802
1815
  return;
1803
1816
  }
@@ -1830,7 +1843,6 @@ class Arazzo1DereferenceVisitor {
1830
1843
  // remove referencing reference from ancestors lineage
1831
1844
  directAncestors.delete(referencingElement);
1832
1845
  }
1833
- this.indirections.pop();
1834
1846
 
1835
1847
  // Boolean JSON Schemas
1836
1848
  if ((0,_speclynx_apidom_ns_arazzo_1__WEBPACK_IMPORTED_MODULE_12__.isBooleanJSONSchemaElement)(referencedElement)) {
@@ -1873,6 +1885,8 @@ class Arazzo1DereferenceVisitor {
1873
1885
  } catch (error) {
1874
1886
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref);
1875
1887
  this.handleError(`Error while dereferencing Schema Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
1888
+ } finally {
1889
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
1876
1890
  }
1877
1891
  }
1878
1892
  }
@@ -2152,16 +2166,22 @@ class AsyncAPI2DereferenceVisitor {
2152
2166
  const type = referencingElement.element;
2153
2167
  const codeFrame = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement);
2154
2168
 
2155
- // find element location: tree search for entry documents, visitor path for external
2169
+ // find element location by identity in the document tree.
2170
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
2171
+ // falls back to visitorPath which may produce an incomplete path when
2172
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
2156
2173
  let location;
2157
- (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_7__.traverse)(this.reference.value.result, {
2158
- enter: p => {
2159
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
2160
- location = p.formatPath();
2161
- p.stop();
2174
+ const root = this.reference.value.result;
2175
+ if ((0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_1__.isElement)(root)) {
2176
+ (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_7__.traverse)(root, {
2177
+ enter: p => {
2178
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
2179
+ location = p.formatPath();
2180
+ p.stop();
2181
+ }
2162
2182
  }
2163
- }
2164
- });
2183
+ });
2184
+ }
2165
2185
  location ??= visitorPath.formatPath();
2166
2186
  const hop = {
2167
2187
  uri,
@@ -2229,6 +2249,7 @@ class AsyncAPI2DereferenceVisitor {
2229
2249
  return;
2230
2250
  }
2231
2251
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_18__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
2252
+ const indirectionsSize = this.indirections.length;
2232
2253
  try {
2233
2254
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
2234
2255
  this.indirections.push(referencingElement);
@@ -2289,7 +2310,6 @@ class AsyncAPI2DereferenceVisitor {
2289
2310
  });
2290
2311
  const replacer = this.options.dereference.strategyOpts['asyncapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
2291
2312
  const replacement = replacer(refElement);
2292
- this.indirections.pop();
2293
2313
  path.replaceWith(replacement);
2294
2314
  return;
2295
2315
  }
@@ -2323,7 +2343,6 @@ class AsyncAPI2DereferenceVisitor {
2323
2343
  // remove referencing reference from ancestors lineage
2324
2344
  directAncestors.delete(referencingElement);
2325
2345
  }
2326
- this.indirections.pop();
2327
2346
 
2328
2347
  // Boolean JSON Schemas
2329
2348
  if ((0,_speclynx_apidom_ns_asyncapi_2__WEBPACK_IMPORTED_MODULE_12__.isBooleanJSONSchemaElement)(referencedElement)) {
@@ -2358,6 +2377,8 @@ class AsyncAPI2DereferenceVisitor {
2358
2377
  } catch (error) {
2359
2378
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref);
2360
2379
  this.handleError(`Error while dereferencing Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
2380
+ } finally {
2381
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
2361
2382
  }
2362
2383
  }
2363
2384
  async ChannelItemElement(path) {
@@ -2388,6 +2409,7 @@ class AsyncAPI2DereferenceVisitor {
2388
2409
  return;
2389
2410
  }
2390
2411
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_18__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
2412
+ const indirectionsSize = this.indirections.length;
2391
2413
  try {
2392
2414
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
2393
2415
  this.indirections.push(referencingElement);
@@ -2438,7 +2460,6 @@ class AsyncAPI2DereferenceVisitor {
2438
2460
  });
2439
2461
  const replacer = this.options.dereference.strategyOpts['asyncapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
2440
2462
  const replacement = replacer(refElement);
2441
- this.indirections.pop();
2442
2463
  path.replaceWith(replacement);
2443
2464
  return;
2444
2465
  }
@@ -2472,7 +2493,6 @@ class AsyncAPI2DereferenceVisitor {
2472
2493
  // remove referencing reference from ancestors lineage
2473
2494
  directAncestors.delete(referencingElement);
2474
2495
  }
2475
- this.indirections.pop();
2476
2496
 
2477
2497
  /**
2478
2498
  * Creating a new version of Channel Item by merging fields from referenced Channel Item with referencing one.
@@ -2503,6 +2523,8 @@ class AsyncAPI2DereferenceVisitor {
2503
2523
  } catch (error) {
2504
2524
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref);
2505
2525
  this.handleError(`Error while dereferencing Channel Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
2526
+ } finally {
2527
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
2506
2528
  }
2507
2529
  }
2508
2530
  }
@@ -2786,16 +2808,22 @@ class OpenAPI2DereferenceVisitor {
2786
2808
  const type = referencingElement.element;
2787
2809
  const codeFrame = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement);
2788
2810
 
2789
- // find element location: tree search for entry documents, visitor path for external
2811
+ // find element location by identity in the document tree.
2812
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
2813
+ // falls back to visitorPath which may produce an incomplete path when
2814
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
2790
2815
  let location;
2791
- (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_7__.traverse)(this.reference.value.result, {
2792
- enter: p => {
2793
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
2794
- location = p.formatPath();
2795
- p.stop();
2816
+ const root = this.reference.value.result;
2817
+ if ((0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_1__.isElement)(root)) {
2818
+ (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_7__.traverse)(root, {
2819
+ enter: p => {
2820
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
2821
+ location = p.formatPath();
2822
+ p.stop();
2823
+ }
2796
2824
  }
2797
- }
2798
- });
2825
+ });
2826
+ }
2799
2827
  location ??= visitorPath.formatPath();
2800
2828
  const hop = {
2801
2829
  uri,
@@ -2863,6 +2891,7 @@ class OpenAPI2DereferenceVisitor {
2863
2891
  return;
2864
2892
  }
2865
2893
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_20__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
2894
+ const indirectionsSize = this.indirections.length;
2866
2895
  try {
2867
2896
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
2868
2897
  this.indirections.push(referencingElement);
@@ -2923,7 +2952,6 @@ class OpenAPI2DereferenceVisitor {
2923
2952
  });
2924
2953
  const replacer = this.options.dereference.strategyOpts['openapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
2925
2954
  const replacement = replacer(refElement);
2926
- this.indirections.pop();
2927
2955
  path.replaceWith(replacement);
2928
2956
  return;
2929
2957
  }
@@ -2955,7 +2983,6 @@ class OpenAPI2DereferenceVisitor {
2955
2983
  });
2956
2984
  directAncestors.delete(referencingElement);
2957
2985
  }
2958
- this.indirections.pop();
2959
2986
 
2960
2987
  /**
2961
2988
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -2976,6 +3003,8 @@ class OpenAPI2DereferenceVisitor {
2976
3003
  } catch (error) {
2977
3004
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref);
2978
3005
  this.handleError(`Error while dereferencing Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
3006
+ } finally {
3007
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
2979
3008
  }
2980
3009
  }
2981
3010
  async PathItemElement(path) {
@@ -3006,6 +3035,7 @@ class OpenAPI2DereferenceVisitor {
3006
3035
  return;
3007
3036
  }
3008
3037
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_20__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
3038
+ const indirectionsSize = this.indirections.length;
3009
3039
  try {
3010
3040
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
3011
3041
  this.indirections.push(referencingElement);
@@ -3056,7 +3086,6 @@ class OpenAPI2DereferenceVisitor {
3056
3086
  });
3057
3087
  const replacer = this.options.dereference.strategyOpts['openapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
3058
3088
  const replacement = replacer(refElement);
3059
- this.indirections.pop();
3060
3089
  path.replaceWith(replacement);
3061
3090
  return;
3062
3091
  }
@@ -3090,7 +3119,6 @@ class OpenAPI2DereferenceVisitor {
3090
3119
  // remove referencing reference from ancestors lineage
3091
3120
  directAncestors.delete(referencingElement);
3092
3121
  }
3093
- this.indirections.pop();
3094
3122
 
3095
3123
  /**
3096
3124
  * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
@@ -3122,6 +3150,8 @@ class OpenAPI2DereferenceVisitor {
3122
3150
  } catch (error) {
3123
3151
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref);
3124
3152
  this.handleError(`Error while dereferencing Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
3153
+ } finally {
3154
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
3125
3155
  }
3126
3156
  }
3127
3157
  async JSONReferenceElement(path) {
@@ -3149,6 +3179,7 @@ class OpenAPI2DereferenceVisitor {
3149
3179
  return;
3150
3180
  }
3151
3181
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_20__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
3182
+ const indirectionsSize = this.indirections.length;
3152
3183
  try {
3153
3184
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref));
3154
3185
  this.indirections.push(referencingElement);
@@ -3209,7 +3240,6 @@ class OpenAPI2DereferenceVisitor {
3209
3240
  });
3210
3241
  const replacer = this.options.dereference.strategyOpts['openapi-2']?.circularReplacer ?? this.options.dereference.circularReplacer;
3211
3242
  const replacement = replacer(refElement);
3212
- this.indirections.pop();
3213
3243
  path.replaceWith(replacement);
3214
3244
  return;
3215
3245
  }
@@ -3243,7 +3273,6 @@ class OpenAPI2DereferenceVisitor {
3243
3273
  // remove referencing reference from ancestors lineage
3244
3274
  directAncestors.delete(referencingElement);
3245
3275
  }
3246
- this.indirections.pop();
3247
3276
 
3248
3277
  /**
3249
3278
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -3264,6 +3293,8 @@ class OpenAPI2DereferenceVisitor {
3264
3293
  } catch (error) {
3265
3294
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(referencingElement.$ref);
3266
3295
  this.handleError(`Error while dereferencing JSON Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
3296
+ } finally {
3297
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
3267
3298
  }
3268
3299
  }
3269
3300
  }
@@ -3546,16 +3577,22 @@ class OpenAPI3_0DereferenceVisitor {
3546
3577
  const type = referencingElement.element;
3547
3578
  const codeFrame = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_6__["default"])(referencingElement);
3548
3579
 
3549
- // find element location: tree search for entry documents, visitor path for external
3580
+ // find element location by identity in the document tree.
3581
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
3582
+ // falls back to visitorPath which may produce an incomplete path when
3583
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
3550
3584
  let location;
3551
- (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_8__.traverse)(this.reference.value.result, {
3552
- enter: p => {
3553
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
3554
- location = p.formatPath();
3555
- p.stop();
3585
+ const root = this.reference.value.result;
3586
+ if ((0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__.isElement)(root)) {
3587
+ (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_8__.traverse)(root, {
3588
+ enter: p => {
3589
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
3590
+ location = p.formatPath();
3591
+ p.stop();
3592
+ }
3556
3593
  }
3557
- }
3558
- });
3594
+ });
3595
+ }
3559
3596
  location ??= visitorPath.formatPath();
3560
3597
  const hop = {
3561
3598
  uri,
@@ -3623,6 +3660,7 @@ class OpenAPI3_0DereferenceVisitor {
3623
3660
  return;
3624
3661
  }
3625
3662
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_17__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref));
3663
+ const indirectionsSize = this.indirections.length;
3626
3664
  try {
3627
3665
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref));
3628
3666
  this.indirections.push(referencingElement);
@@ -3683,7 +3721,6 @@ class OpenAPI3_0DereferenceVisitor {
3683
3721
  });
3684
3722
  const replacer = this.options.dereference.strategyOpts['openapi-3-0']?.circularReplacer ?? this.options.dereference.circularReplacer;
3685
3723
  const replacement = replacer(refElement);
3686
- this.indirections.pop();
3687
3724
  path.replaceWith(replacement);
3688
3725
  return;
3689
3726
  }
@@ -3717,7 +3754,6 @@ class OpenAPI3_0DereferenceVisitor {
3717
3754
  // remove referencing reference from ancestors lineage
3718
3755
  directAncestors.delete(referencingElement);
3719
3756
  }
3720
- this.indirections.pop();
3721
3757
 
3722
3758
  /**
3723
3759
  * Creating a new version of referenced element to avoid modifying the original one.
@@ -3738,6 +3774,8 @@ class OpenAPI3_0DereferenceVisitor {
3738
3774
  } catch (error) {
3739
3775
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref);
3740
3776
  this.handleError(`Error while dereferencing Reference Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
3777
+ } finally {
3778
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
3741
3779
  }
3742
3780
  }
3743
3781
  async PathItemElement(path) {
@@ -3768,6 +3806,7 @@ class OpenAPI3_0DereferenceVisitor {
3768
3806
  return;
3769
3807
  }
3770
3808
  const $refBaseURI = _util_url_ts__WEBPACK_IMPORTED_MODULE_17__.resolve(retrievalURI, (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref));
3809
+ const indirectionsSize = this.indirections.length;
3771
3810
  try {
3772
3811
  const reference = await this.toReference((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref));
3773
3812
  this.indirections.push(referencingElement);
@@ -3818,7 +3857,6 @@ class OpenAPI3_0DereferenceVisitor {
3818
3857
  });
3819
3858
  const replacer = this.options.dereference.strategyOpts['openapi-3-0']?.circularReplacer ?? this.options.dereference.circularReplacer;
3820
3859
  const replacement = replacer(refElement);
3821
- this.indirections.pop();
3822
3860
  path.replaceWith(replacement);
3823
3861
  return;
3824
3862
  }
@@ -3852,7 +3890,6 @@ class OpenAPI3_0DereferenceVisitor {
3852
3890
  // remove referencing reference from ancestors lineage
3853
3891
  directAncestors.delete(referencingElement);
3854
3892
  }
3855
- this.indirections.pop();
3856
3893
 
3857
3894
  /**
3858
3895
  * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
@@ -3883,6 +3920,8 @@ class OpenAPI3_0DereferenceVisitor {
3883
3920
  } catch (error) {
3884
3921
  const $ref = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_5__["default"])(referencingElement.$ref);
3885
3922
  this.handleError(`Error while dereferencing Path Item Object. Cannot resolve $ref "${$ref}": ${error.message}`, error, referencingElement, '$ref', $ref, path);
3923
+ } finally {
3924
+ if (this.indirections.length > indirectionsSize) this.indirections.pop();
3886
3925
  }
3887
3926
  }
3888
3927
  async LinkElement(path) {
@@ -4544,16 +4583,22 @@ class OpenAPI3_1DereferenceVisitor {
4544
4583
  const type = referencingElement.element;
4545
4584
  const codeFrame = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_8__["default"])(referencingElement);
4546
4585
 
4547
- // find element location: tree search for entry documents, visitor path for external
4586
+ // find element location by identity in the document tree.
4587
+ // guarded: this.reference.value may not be a ParseResultElement or may lack a result.
4588
+ // falls back to visitorPath which may produce an incomplete path when
4589
+ // dereferenceApiDOM is called with a fragment (cloneShallow creates a new root identity).
4548
4590
  let location;
4549
- (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_10__.traverse)(this.reference.value.result, {
4550
- enter: p => {
4551
- if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
4552
- location = p.formatPath();
4553
- p.stop();
4591
+ const root = this.reference.value.result;
4592
+ if ((0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_3__.isElement)(root)) {
4593
+ (0,_speclynx_apidom_traverse__WEBPACK_IMPORTED_MODULE_10__.traverse)(root, {
4594
+ enter: p => {
4595
+ if (p.node === referencingElement || this.refractCache.get(p.node) === referencingElement) {
4596
+ location = p.formatPath();
4597
+ p.stop();
4598
+ }
4554
4599
  }
4555
- }
4556
- });
4600
+ });
4601
+ }
4557
4602
  location ??= visitorPath.formatPath();
4558
4603
  const hop = {
4559
4604
  uri,
@@ -79730,11 +79775,10 @@ __webpack_require__.r(__webpack_exports__);
79730
79775
  /* harmony export */ });
79731
79776
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29498);
79732
79777
  /* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25162);
79733
- /* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12111);
79734
- /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(44673);
79735
- /* harmony import */ var _elements_PathItem_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(83419);
79736
- /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(26365);
79737
- /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(75107);
79778
+ /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(44673);
79779
+ /* harmony import */ var _elements_PathItem_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(83419);
79780
+ /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26365);
79781
+ /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(75107);
79738
79782
 
79739
79783
 
79740
79784
 
@@ -79744,23 +79788,22 @@ __webpack_require__.r(__webpack_exports__);
79744
79788
  /**
79745
79789
  * @public
79746
79790
  */
79747
- class PathItemVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_6__.BaseFixedFieldsVisitor {
79791
+ class PathItemVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_5__.BaseFixedFieldsVisitor {
79748
79792
  constructor(options) {
79749
79793
  super(options);
79750
- this.element = new _elements_PathItem_mjs__WEBPACK_IMPORTED_MODULE_4__["default"]();
79794
+ this.element = new _elements_PathItem_mjs__WEBPACK_IMPORTED_MODULE_3__["default"]();
79751
79795
  this.consumeSafe = true;
79752
79796
  this.specPath = (0,ramda__WEBPACK_IMPORTED_MODULE_0__["default"])(['document', 'objects', 'PathItem']);
79753
79797
  }
79754
79798
  ObjectElement(path) {
79755
- _bases_mjs__WEBPACK_IMPORTED_MODULE_6__.BaseFixedFieldsVisitor.prototype.ObjectElement.call(this, path);
79799
+ _bases_mjs__WEBPACK_IMPORTED_MODULE_5__.BaseFixedFieldsVisitor.prototype.ObjectElement.call(this, path);
79756
79800
 
79757
79801
  // decorate Operation elements with HTTP method
79758
- this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_5__.isOperationElement)
79802
+ this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_4__.isOperationElement)
79759
79803
  // @ts-ignore
79760
79804
  .forEach((operationElement, httpMethodElementCI) => {
79761
- const httpMethodElementCS = (0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__.cloneDeep)(httpMethodElementCI);
79762
- httpMethodElementCS.content = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__["default"])(httpMethodElementCS).toUpperCase();
79763
- operationElement.meta.set('http-method', httpMethodElementCS);
79805
+ const httpMethod = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_2__["default"])(httpMethodElementCI).toUpperCase();
79806
+ operationElement.meta.set('http-method', httpMethod);
79764
79807
  });
79765
79808
 
79766
79809
  // mark this PathItemElement with reference metadata
@@ -79783,7 +79826,7 @@ __webpack_require__.r(__webpack_exports__);
79783
79826
  /* harmony export */ });
79784
79827
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(53679);
79785
79828
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(29498);
79786
- /* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12111);
79829
+ /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(44673);
79787
79830
  /* harmony import */ var _elements_Paths_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(38253);
79788
79831
  /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(26365);
79789
79832
  /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(75107);
@@ -79814,7 +79857,7 @@ class PathsVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_5__.BasePatterned
79814
79857
  .forEach((pathItemElement, key) => {
79815
79858
  key.classes.push('openapi-path-template');
79816
79859
  key.classes.push('path-template');
79817
- pathItemElement.meta.set('path', (0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__.cloneDeep)(key));
79860
+ pathItemElement.meta.set('path', (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_2__["default"])(key));
79818
79861
  });
79819
79862
  }
79820
79863
  }
@@ -79999,13 +80042,11 @@ __webpack_require__.r(__webpack_exports__);
79999
80042
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29498);
80000
80043
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64066);
80001
80044
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(32343);
80002
- /* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(12111);
80003
- /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(44673);
80004
- /* harmony import */ var _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(31297);
80005
- /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(72880);
80006
- /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(26365);
80007
- /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(75107);
80008
-
80045
+ /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(44673);
80046
+ /* harmony import */ var _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(31297);
80047
+ /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(72880);
80048
+ /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(26365);
80049
+ /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(75107);
80009
80050
 
80010
80051
 
80011
80052
 
@@ -80015,32 +80056,32 @@ __webpack_require__.r(__webpack_exports__);
80015
80056
  /**
80016
80057
  * @public
80017
80058
  */
80018
- class ResponsesVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_8__.BaseMixedFieldsVisitor {
80059
+ class ResponsesVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_7__.BaseMixedFieldsVisitor {
80019
80060
  constructor(options) {
80020
80061
  super(options);
80021
- this.element = new _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_5__["default"]();
80062
+ this.element = new _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_4__["default"]();
80022
80063
  this.specPathFixedFields = (0,ramda__WEBPACK_IMPORTED_MODULE_0__["default"])(['document', 'objects', 'Responses']);
80023
80064
  this.canSupportSpecificationExtensions = true;
80024
80065
  this.specPathPatternedFields = element => {
80025
- return (0,_predicates_mjs__WEBPACK_IMPORTED_MODULE_6__.isReferenceLikeElement)(element) ? ['document', 'objects', 'Reference'] : ['document', 'objects', 'Response'];
80066
+ return (0,_predicates_mjs__WEBPACK_IMPORTED_MODULE_5__.isReferenceLikeElement)(element) ? ['document', 'objects', 'Reference'] : ['document', 'objects', 'Response'];
80026
80067
  };
80027
80068
  // @ts-ignore
80028
80069
  this.fieldPatternPredicate = (0,ramda__WEBPACK_IMPORTED_MODULE_2__["default"])(new RegExp(`^(1XX|2XX|3XX|4XX|5XX|${(0,ramda__WEBPACK_IMPORTED_MODULE_1__["default"])(100, 600).join('|')})$`));
80029
80070
  }
80030
80071
  ObjectElement(path) {
80031
- _bases_mjs__WEBPACK_IMPORTED_MODULE_8__.BaseMixedFieldsVisitor.prototype.ObjectElement.call(this, path);
80072
+ _bases_mjs__WEBPACK_IMPORTED_MODULE_7__.BaseMixedFieldsVisitor.prototype.ObjectElement.call(this, path);
80032
80073
 
80033
80074
  // decorate every ReferenceElement with metadata about their referencing type
80034
80075
  // @ts-ignore
80035
- this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_7__.isReferenceElement).forEach(referenceElement => {
80076
+ this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_6__.isReferenceElement).forEach(referenceElement => {
80036
80077
  referenceElement.meta.set('referenced-element', 'response');
80037
80078
  });
80038
80079
 
80039
80080
  // decorate every ResponseElement with metadata about their status code
80040
80081
  // @ts-ignore
80041
- this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_7__.isResponseElement).forEach((value, key) => {
80042
- const httpStatusCode = (0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_3__.cloneDeep)(key);
80043
- if (!this.fieldPatternPredicate((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_4__["default"])(httpStatusCode))) return;
80082
+ this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_6__.isResponseElement).forEach((value, key) => {
80083
+ const httpStatusCode = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__["default"])(key);
80084
+ if (!this.fieldPatternPredicate(httpStatusCode)) return;
80044
80085
  value.meta.set('http-status-code', httpStatusCode);
80045
80086
  });
80046
80087
  }
@@ -87829,13 +87870,11 @@ __webpack_require__.r(__webpack_exports__);
87829
87870
  /* harmony export */ });
87830
87871
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(29498);
87831
87872
  /* harmony import */ var ramda__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64066);
87832
- /* harmony import */ var _speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(12111);
87833
- /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(44673);
87834
- /* harmony import */ var _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(71767);
87835
- /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(21314);
87836
- /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(32131);
87837
- /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(74367);
87838
-
87873
+ /* harmony import */ var _speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(44673);
87874
+ /* harmony import */ var _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(71767);
87875
+ /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(21314);
87876
+ /* harmony import */ var _predicates_mjs__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(32131);
87877
+ /* harmony import */ var _bases_mjs__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(74367);
87839
87878
 
87840
87879
 
87841
87880
 
@@ -87848,29 +87887,29 @@ __webpack_require__.r(__webpack_exports__);
87848
87887
  /**
87849
87888
  * @public
87850
87889
  */
87851
- class ResponsesVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_7__.BaseMixedFieldsVisitor {
87890
+ class ResponsesVisitor extends _bases_mjs__WEBPACK_IMPORTED_MODULE_6__.BaseMixedFieldsVisitor {
87852
87891
  constructor(options) {
87853
87892
  super(options);
87854
- this.element = new _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_4__["default"]();
87893
+ this.element = new _elements_Responses_mjs__WEBPACK_IMPORTED_MODULE_3__["default"]();
87855
87894
  this.specPathFixedFields = (0,ramda__WEBPACK_IMPORTED_MODULE_0__["default"])(['document', 'objects', 'Responses']);
87856
87895
  this.canSupportSpecificationExtensions = true;
87857
- this.specPathPatternedFields = element => (0,_predicates_mjs__WEBPACK_IMPORTED_MODULE_5__.isReferenceLikeElement)(element) ? ['document', 'objects', 'Reference'] : ['document', 'objects', 'Response'];
87896
+ this.specPathPatternedFields = element => (0,_predicates_mjs__WEBPACK_IMPORTED_MODULE_4__.isReferenceLikeElement)(element) ? ['document', 'objects', 'Reference'] : ['document', 'objects', 'Response'];
87858
87897
  this.fieldPatternPredicate = value => new RegExp(`^(1XX|2XX|3XX|4XX|5XX|${(0,ramda__WEBPACK_IMPORTED_MODULE_1__["default"])(100, 600).join('|')})$`).test(String(value));
87859
87898
  }
87860
87899
  ObjectElement(path) {
87861
- _bases_mjs__WEBPACK_IMPORTED_MODULE_7__.BaseMixedFieldsVisitor.prototype.ObjectElement.call(this, path);
87900
+ _bases_mjs__WEBPACK_IMPORTED_MODULE_6__.BaseMixedFieldsVisitor.prototype.ObjectElement.call(this, path);
87862
87901
 
87863
87902
  // decorate every ReferenceElement with metadata about their referencing type
87864
87903
  // @ts-ignore
87865
- this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_6__.isReferenceElement).forEach(referenceElement => {
87904
+ this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_5__.isReferenceElement).forEach(referenceElement => {
87866
87905
  referenceElement.meta.set('referenced-element', 'response');
87867
87906
  });
87868
87907
 
87869
87908
  // decorate every ResponseElement with metadata about their status code
87870
87909
  // @ts-ignore
87871
- this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_6__.isResponseElement).forEach((value, key) => {
87872
- const httpStatusCode = (0,_speclynx_apidom_datamodel__WEBPACK_IMPORTED_MODULE_2__.cloneDeep)(key);
87873
- if (!this.fieldPatternPredicate((0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_3__["default"])(httpStatusCode))) return;
87910
+ this.element.filter(_predicates_mjs__WEBPACK_IMPORTED_MODULE_5__.isResponseElement).forEach((value, key) => {
87911
+ const httpStatusCode = (0,_speclynx_apidom_core__WEBPACK_IMPORTED_MODULE_2__["default"])(key);
87912
+ if (!this.fieldPatternPredicate(httpStatusCode)) return;
87874
87913
  value.meta.set('http-status-code', httpStatusCode);
87875
87914
  });
87876
87915
  }