@speclynx/apidom-reference 1.12.1 → 2.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.
Files changed (112) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/NOTICE +16 -7
  3. package/README.md +0 -33
  4. package/dist/167.apidom-reference.browser.min.js +1 -1
  5. package/dist/451.apidom-reference.browser.min.js +1 -1
  6. package/dist/apidom-reference.browser.js +24594 -23365
  7. package/dist/apidom-reference.browser.min.js +1 -1
  8. package/package.json +24 -57
  9. package/src/configuration/saturated.cjs +34 -42
  10. package/src/configuration/saturated.mjs +0 -8
  11. package/src/dereference/index.cjs +4 -4
  12. package/src/dereference/index.mjs +1 -1
  13. package/src/dereference/strategies/apidom/index.cjs +7 -7
  14. package/src/dereference/strategies/apidom/index.mjs +5 -6
  15. package/src/dereference/strategies/apidom/selectors/element-id.cjs +4 -2
  16. package/src/dereference/strategies/apidom/selectors/element-id.mjs +5 -3
  17. package/src/dereference/strategies/apidom/visitor.cjs +31 -17
  18. package/src/dereference/strategies/apidom/visitor.mjs +25 -12
  19. package/src/dereference/strategies/asyncapi-2/index.cjs +6 -9
  20. package/src/dereference/strategies/asyncapi-2/index.mjs +6 -10
  21. package/src/dereference/strategies/asyncapi-2/visitor.cjs +67 -80
  22. package/src/dereference/strategies/asyncapi-2/visitor.mjs +59 -72
  23. package/src/dereference/strategies/openapi-2/index.cjs +6 -9
  24. package/src/dereference/strategies/openapi-2/index.mjs +6 -10
  25. package/src/dereference/strategies/openapi-2/visitor.cjs +91 -100
  26. package/src/dereference/strategies/openapi-2/visitor.mjs +81 -90
  27. package/src/dereference/strategies/openapi-3-0/index.cjs +6 -9
  28. package/src/dereference/strategies/openapi-3-0/index.mjs +6 -10
  29. package/src/dereference/strategies/openapi-3-0/visitor.cjs +92 -115
  30. package/src/dereference/strategies/openapi-3-0/visitor.mjs +74 -97
  31. package/src/dereference/strategies/openapi-3-1/index.cjs +6 -9
  32. package/src/dereference/strategies/openapi-3-1/index.mjs +6 -10
  33. package/src/dereference/strategies/openapi-3-1/selectors/$anchor.cjs +2 -1
  34. package/src/dereference/strategies/openapi-3-1/selectors/$anchor.mjs +3 -2
  35. package/src/dereference/strategies/openapi-3-1/selectors/uri.cjs +2 -2
  36. package/src/dereference/strategies/openapi-3-1/selectors/uri.mjs +2 -2
  37. package/src/dereference/strategies/openapi-3-1/util.cjs +3 -2
  38. package/src/dereference/strategies/openapi-3-1/util.mjs +4 -3
  39. package/src/dereference/strategies/openapi-3-1/visitor.cjs +130 -156
  40. package/src/dereference/strategies/openapi-3-1/visitor.mjs +106 -132
  41. package/src/dereference/util.cjs +2 -2
  42. package/src/dereference/util.mjs +1 -1
  43. package/src/parse/parsers/apidom-json/index.cjs +5 -5
  44. package/src/parse/parsers/apidom-json/index.mjs +2 -2
  45. package/src/parse/parsers/arazzo-json-1/index.cjs +1 -2
  46. package/src/parse/parsers/arazzo-json-1/index.mjs +1 -2
  47. package/src/parse/parsers/asyncapi-json-2/index.cjs +1 -2
  48. package/src/parse/parsers/asyncapi-json-2/index.mjs +1 -2
  49. package/src/parse/parsers/binary/index-browser.cjs +3 -3
  50. package/src/parse/parsers/binary/index-browser.mjs +1 -1
  51. package/src/parse/parsers/binary/index-node.cjs +3 -3
  52. package/src/parse/parsers/binary/index-node.mjs +1 -1
  53. package/src/parse/parsers/json/index.cjs +1 -2
  54. package/src/parse/parsers/json/index.mjs +1 -2
  55. package/src/parse/parsers/openapi-json-2/index.cjs +1 -2
  56. package/src/parse/parsers/openapi-json-2/index.mjs +1 -2
  57. package/src/parse/parsers/openapi-json-3-0/index.cjs +1 -2
  58. package/src/parse/parsers/openapi-json-3-0/index.mjs +1 -2
  59. package/src/parse/parsers/openapi-json-3-1/index.cjs +1 -2
  60. package/src/parse/parsers/openapi-json-3-1/index.mjs +1 -2
  61. package/src/resolve/index.cjs +4 -4
  62. package/src/resolve/index.mjs +1 -1
  63. package/types/File.d.ts +1 -1
  64. package/types/Reference.d.ts +1 -1
  65. package/types/ReferenceSet.d.ts +1 -1
  66. package/types/apidom-reference.d.ts +8 -9
  67. package/types/bundle/index.d.ts +1 -1
  68. package/types/bundle/strategies/BundleStrategy.d.ts +1 -1
  69. package/types/bundle/strategies/openapi-3-1/index.d.ts +1 -1
  70. package/types/dereference/index.d.ts +1 -1
  71. package/types/dereference/strategies/DereferenceStrategy.d.ts +1 -1
  72. package/types/dereference/strategies/apidom/index.d.ts +1 -1
  73. package/types/dereference/strategies/apidom/selectors/element-id.d.ts +1 -1
  74. package/types/dereference/strategies/apidom/visitor.d.ts +3 -2
  75. package/types/dereference/strategies/asyncapi-2/index.d.ts +2 -2
  76. package/types/dereference/strategies/asyncapi-2/visitor.d.ts +5 -14
  77. package/types/dereference/strategies/openapi-2/index.d.ts +2 -2
  78. package/types/dereference/strategies/openapi-2/visitor.d.ts +6 -17
  79. package/types/dereference/strategies/openapi-3-0/index.d.ts +2 -2
  80. package/types/dereference/strategies/openapi-3-0/visitor.d.ts +7 -20
  81. package/types/dereference/strategies/openapi-3-1/index.d.ts +2 -2
  82. package/types/dereference/strategies/openapi-3-1/selectors/$anchor.d.ts +1 -1
  83. package/types/dereference/strategies/openapi-3-1/selectors/uri.d.ts +1 -1
  84. package/types/dereference/strategies/openapi-3-1/util.d.ts +1 -1
  85. package/types/dereference/strategies/openapi-3-1/visitor.d.ts +8 -23
  86. package/types/dereference/util.d.ts +1 -1
  87. package/types/index.d.ts +1 -1
  88. package/types/options/index.d.ts +1 -1
  89. package/types/parse/index.d.ts +1 -1
  90. package/types/parse/parsers/Parser.d.ts +1 -1
  91. package/types/parse/parsers/apidom-json/index.d.ts +1 -1
  92. package/types/parse/parsers/arazzo-json-1/index.d.ts +1 -2
  93. package/types/parse/parsers/arazzo-yaml-1/index.d.ts +1 -1
  94. package/types/parse/parsers/asyncapi-json-2/index.d.ts +1 -2
  95. package/types/parse/parsers/asyncapi-yaml-2/index.d.ts +1 -1
  96. package/types/parse/parsers/binary/index-browser.d.ts +1 -1
  97. package/types/parse/parsers/binary/index-node.d.ts +1 -1
  98. package/types/parse/parsers/json/index.d.ts +1 -2
  99. package/types/parse/parsers/openapi-json-2/index.d.ts +1 -2
  100. package/types/parse/parsers/openapi-json-3-0/index.d.ts +1 -2
  101. package/types/parse/parsers/openapi-json-3-1/index.d.ts +1 -2
  102. package/types/parse/parsers/openapi-yaml-2/index.d.ts +1 -1
  103. package/types/parse/parsers/openapi-yaml-3-0/index.d.ts +1 -1
  104. package/types/parse/parsers/openapi-yaml-3-1/index.d.ts +1 -1
  105. package/types/parse/parsers/yaml-1-2/index.d.ts +1 -1
  106. package/types/resolve/index.d.ts +1 -1
  107. package/src/parse/parsers/api-design-systems-json/index.cjs +0 -55
  108. package/src/parse/parsers/api-design-systems-json/index.mjs +0 -49
  109. package/src/parse/parsers/api-design-systems-yaml/index.cjs +0 -54
  110. package/src/parse/parsers/api-design-systems-yaml/index.mjs +0 -48
  111. package/types/parse/parsers/api-design-systems-json/index.d.ts +0 -21
  112. package/types/parse/parsers/api-design-systems-yaml/index.d.ts +0 -20
@@ -3,11 +3,13 @@
3
3
  var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
4
  var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5
5
  exports.__esModule = true;
6
- exports.mutationReplacer = exports.default = void 0;
6
+ exports.default = void 0;
7
7
  var _ramda = require("ramda");
8
8
  var _ramdaAdjunct = require("ramda-adjunct");
9
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
9
10
  var _apidomCore = require("@speclynx/apidom-core");
10
11
  var _apidomError = require("@speclynx/apidom-error");
12
+ var _apidomTraverse = require("@speclynx/apidom-traverse");
11
13
  var _apidomJsonPointer = require("@speclynx/apidom-json-pointer");
12
14
  var _apidomNsOpenapi = require("@speclynx/apidom-ns-openapi-3-1");
13
15
  var _$anchor = require("./selectors/$anchor.cjs");
@@ -21,28 +23,13 @@ var _File = _interopRequireDefault(require("../../../File.cjs"));
21
23
  var _util = require("./util.cjs");
22
24
  var _util2 = require("../../util.cjs");
23
25
  var _EvaluationJsonSchemaUriError = _interopRequireDefault(require("../../../errors/EvaluationJsonSchemaUriError.cjs"));
24
- // @ts-ignore
25
- const visitAsync = _apidomCore.visit[Symbol.for('nodejs.util.promisify.custom')];
26
-
27
26
  // initialize element identity manager
28
27
  const identityManager = new _apidomCore.IdentityManager();
29
28
 
30
29
  /**
31
- * Custom mutation replacer.
32
30
  * @public
33
31
  */
34
- const mutationReplacer = (newElement, oldElement, key, parent) => {
35
- if ((0, _apidomCore.isMemberElement)(parent)) {
36
- parent.value = newElement;
37
- } else if (Array.isArray(parent)) {
38
- parent[key] = newElement;
39
- }
40
- };
41
32
 
42
- /**
43
- * @public
44
- */
45
- exports.mutationReplacer = mutationReplacer;
46
33
  /**
47
34
  * @public
48
35
  */
@@ -96,7 +83,7 @@ class OpenAPI3_1DereferenceVisitor {
96
83
  // register new mutable reference with a refSet
97
84
  const mutableReference = new _Reference.default({
98
85
  uri: baseURI,
99
- value: (0, _apidomCore.cloneDeep)(parseResult),
86
+ value: (0, _apidomDatamodel.cloneDeep)(parseResult),
100
87
  depth: this.reference.depth + 1
101
88
  });
102
89
  refSet.add(mutableReference);
@@ -111,21 +98,25 @@ class OpenAPI3_1DereferenceVisitor {
111
98
  }
112
99
  return mutableReference;
113
100
  }
114
- toAncestorLineage(ancestors) {
101
+ toAncestorLineage(path) {
115
102
  /**
116
103
  * Compute full ancestors lineage.
117
104
  * Ancestors are flatten to unwrap all Element instances.
118
105
  */
119
- const directAncestors = new Set(ancestors.filter(_apidomCore.isElement));
106
+ const ancestorNodes = path.getAncestorNodes();
107
+ const directAncestors = new Set(ancestorNodes.filter(_apidomDatamodel.isElement));
120
108
  const ancestorsLineage = new _util2.AncestorLineage(...this.ancestors, directAncestors);
121
109
  return [ancestorsLineage, directAncestors];
122
110
  }
123
- async ReferenceElement(referencingElement, key, parent, path, ancestors, link) {
111
+ async ReferenceElement(path) {
112
+ const referencingElement = path.node;
113
+
124
114
  // skip current referencing element as it's already been access
125
115
  if (this.indirections.includes(referencingElement)) {
126
- return false;
116
+ path.skip();
117
+ return;
127
118
  }
128
- const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
119
+ const [ancestorsLineage, directAncestors] = this.toAncestorLineage(path);
129
120
  const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(referencingElement.$ref));
130
121
  const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
131
122
  const isExternalReference = !isInternalReference;
@@ -133,12 +124,14 @@ class OpenAPI3_1DereferenceVisitor {
133
124
  // ignore resolving internal Reference Objects
134
125
  if (!this.options.resolve.internal && isInternalReference) {
135
126
  // skip traversing this reference element and all it's child elements
136
- return false;
127
+ path.skip();
128
+ return;
137
129
  }
138
130
  // ignore resolving external Reference Objects
139
131
  if (!this.options.resolve.external && isExternalReference) {
140
132
  // skip traversing this reference element and all it's child elements
141
- return false;
133
+ path.skip();
134
+ return;
142
135
  }
143
136
  const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
144
137
  const $refBaseURI = url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
@@ -150,20 +143,21 @@ class OpenAPI3_1DereferenceVisitor {
150
143
  referencedElement.id = identityManager.identify(referencedElement);
151
144
 
152
145
  // applying semantics to a fragment
153
- if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
146
+ if ((0, _apidomDatamodel.isPrimitiveElement)(referencedElement)) {
154
147
  const referencedElementType = (0, _apidomCore.toValue)(referencingElement.meta.get('referenced-element'));
155
148
  const cacheKey = `${referencedElementType}-${(0, _apidomCore.toValue)(identityManager.identify(referencedElement))}`;
156
149
  if (this.refractCache.has(cacheKey)) {
157
150
  referencedElement = this.refractCache.get(cacheKey);
158
151
  } else if ((0, _apidomNsOpenapi.isReferenceLikeElement)(referencedElement)) {
159
152
  // handling indirect references
160
- referencedElement = _apidomNsOpenapi.ReferenceElement.refract(referencedElement);
161
- referencedElement.setMetaProperty('referenced-element', referencedElementType);
153
+ referencedElement = (0, _apidomNsOpenapi.refractReference)(referencedElement);
154
+ referencedElement.meta.set('referenced-element', referencedElementType);
162
155
  this.refractCache.set(cacheKey, referencedElement);
163
156
  } else {
164
157
  // handling direct references
165
- const ElementClass = this.namespace.getElementClass(referencedElementType);
166
- referencedElement = ElementClass.refract(referencedElement);
158
+ referencedElement = (0, _apidomNsOpenapi.refract)(referencedElement, {
159
+ element: referencedElementType
160
+ });
167
161
  this.refractCache.set(cacheKey, referencedElement);
168
162
  }
169
163
  }
@@ -184,15 +178,16 @@ class OpenAPI3_1DereferenceVisitor {
184
178
  if (this.options.dereference.circular === 'error') {
185
179
  throw new _apidomError.ApiDOMError('Circular reference detected');
186
180
  } else if (this.options.dereference.circular === 'replace') {
187
- const refElement = new _apidomCore.RefElement(referencedElement.id, {
181
+ const refElement = new _apidomDatamodel.RefElement(referencedElement.id, {
188
182
  type: 'reference',
189
183
  uri: reference.uri,
190
184
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
191
185
  });
192
186
  const replacer = this.options.dereference.strategyOpts['openapi-3-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
193
187
  const replacement = replacer(refElement);
194
- link.replaceWith(replacement, mutationReplacer);
195
- return !parent ? replacement : false;
188
+ this.indirections.pop();
189
+ path.replaceWith(replacement);
190
+ return;
196
191
  }
197
192
  }
198
193
 
@@ -218,9 +213,8 @@ class OpenAPI3_1DereferenceVisitor {
218
213
  refractCache: this.refractCache,
219
214
  ancestors: ancestorsLineage
220
215
  });
221
- referencedElement = await visitAsync(referencedElement, visitor, {
222
- keyMap: _apidomNsOpenapi.keyMap,
223
- nodeTypeGetter: _apidomNsOpenapi.getNodeType
216
+ referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
217
+ mutable: true
224
218
  });
225
219
 
226
220
  // remove referencing reference from ancestors lineage
@@ -231,11 +225,11 @@ class OpenAPI3_1DereferenceVisitor {
231
225
  /**
232
226
  * Creating a new version of referenced element to avoid modifying the original one.
233
227
  */
234
- const mergedElement = (0, _apidomCore.cloneShallow)(referencedElement);
228
+ const mergedElement = (0, _apidomDatamodel.cloneShallow)(referencedElement);
235
229
  // assign unique id to merged element
236
- mergedElement.setMetaProperty('id', identityManager.generateId());
230
+ mergedElement.meta.set('id', identityManager.generateId());
237
231
  // annotate fragment with info about original Reference element
238
- mergedElement.setMetaProperty('ref-fields', {
232
+ mergedElement.meta.set('ref-fields', {
239
233
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
240
234
  // @ts-ignore
241
235
  description: (0, _apidomCore.toValue)(referencingElement.description),
@@ -243,12 +237,12 @@ class OpenAPI3_1DereferenceVisitor {
243
237
  summary: (0, _apidomCore.toValue)(referencingElement.summary)
244
238
  });
245
239
  // annotate fragment with info about origin
246
- mergedElement.setMetaProperty('ref-origin', reference.uri);
240
+ mergedElement.meta.set('ref-origin', reference.uri);
247
241
  // annotate fragment with info about referencing element
248
- mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
242
+ mergedElement.meta.set('ref-referencing-element-id', (0, _apidomDatamodel.cloneDeep)(identityManager.identify(referencingElement)));
249
243
 
250
244
  // override description and summary (outer has higher priority then inner)
251
- if ((0, _apidomCore.isObjectElement)(referencedElement) && (0, _apidomCore.isObjectElement)(mergedElement)) {
245
+ if ((0, _apidomDatamodel.isObjectElement)(referencedElement) && (0, _apidomDatamodel.isObjectElement)(mergedElement)) {
252
246
  if (referencingElement.hasKey('description') && 'description' in referencedElement) {
253
247
  mergedElement.remove('description');
254
248
  mergedElement.set('description', referencingElement.get('description'));
@@ -262,37 +256,35 @@ class OpenAPI3_1DereferenceVisitor {
262
256
  /**
263
257
  * Transclude referencing element with merged referenced element.
264
258
  */
265
- link.replaceWith(mergedElement, mutationReplacer);
266
-
267
- /**
268
- * We're at the root of the tree, so we're just replacing the entire tree.
269
- */
270
- return !parent ? mergedElement : false;
259
+ path.replaceWith(mergedElement);
271
260
  }
272
- async PathItemElement(referencingElement, key, parent, path, ancestors, link) {
261
+ async PathItemElement(path) {
262
+ const referencingElement = path.node;
263
+
273
264
  // ignore PathItemElement without $ref field
274
- if (!(0, _apidomCore.isStringElement)(referencingElement.$ref)) {
275
- return undefined;
265
+ if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
266
+ return;
276
267
  }
277
268
 
278
269
  // skip current referencing element as it's already been access
279
270
  if (this.indirections.includes(referencingElement)) {
280
- return false;
271
+ path.skip();
272
+ return;
281
273
  }
282
- const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
274
+ const [ancestorsLineage, directAncestors] = this.toAncestorLineage(path);
283
275
  const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(referencingElement.$ref));
284
276
  const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
285
277
  const isExternalReference = !isInternalReference;
286
278
 
287
- // ignore resolving external Path Item Objects
279
+ // ignore resolving internal Path Item Objects
288
280
  if (!this.options.resolve.internal && isInternalReference) {
289
281
  // skip traversing this Path Item element but traverse all it's child elements
290
- return undefined;
282
+ return;
291
283
  }
292
284
  // ignore resolving external Path Item Objects
293
285
  if (!this.options.resolve.external && isExternalReference) {
294
286
  // skip traversing this Path Item element but traverse all it's child elements
295
- return undefined;
287
+ return;
296
288
  }
297
289
  const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
298
290
  const $refBaseURI = url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
@@ -306,12 +298,12 @@ class OpenAPI3_1DereferenceVisitor {
306
298
  /**
307
299
  * Applying semantics to a referenced element if semantics are missing.
308
300
  */
309
- if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
301
+ if ((0, _apidomDatamodel.isPrimitiveElement)(referencedElement)) {
310
302
  const cacheKey = `path-item-${(0, _apidomCore.toValue)(identityManager.identify(referencedElement))}`;
311
303
  if (this.refractCache.has(cacheKey)) {
312
304
  referencedElement = this.refractCache.get(cacheKey);
313
305
  } else {
314
- referencedElement = _apidomNsOpenapi.PathItemElement.refract(referencedElement);
306
+ referencedElement = (0, _apidomNsOpenapi.refractPathItem)(referencedElement);
315
307
  this.refractCache.set(cacheKey, referencedElement);
316
308
  }
317
309
  }
@@ -332,15 +324,16 @@ class OpenAPI3_1DereferenceVisitor {
332
324
  if (this.options.dereference.circular === 'error') {
333
325
  throw new _apidomError.ApiDOMError('Circular reference detected');
334
326
  } else if (this.options.dereference.circular === 'replace') {
335
- const refElement = new _apidomCore.RefElement(referencedElement.id, {
327
+ const refElement = new _apidomDatamodel.RefElement(referencedElement.id, {
336
328
  type: 'path-item',
337
329
  uri: reference.uri,
338
330
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
339
331
  });
340
332
  const replacer = this.options.dereference.strategyOpts['openapi-3-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
341
333
  const replacement = replacer(refElement);
342
- link.replaceWith(replacement, mutationReplacer);
343
- return !parent ? replacement : false;
334
+ this.indirections.pop();
335
+ path.replaceWith(replacement);
336
+ return;
344
337
  }
345
338
  }
346
339
 
@@ -355,7 +348,7 @@ class OpenAPI3_1DereferenceVisitor {
355
348
  */
356
349
  const isNonRootDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
357
350
  const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
358
- if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isPathItemElement)(referencedElement) && (0, _apidomCore.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
351
+ if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isPathItemElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
359
352
  // append referencing reference to ancestors lineage
360
353
  directAncestors.add(referencingElement);
361
354
  const visitor = new OpenAPI3_1DereferenceVisitor({
@@ -366,9 +359,8 @@ class OpenAPI3_1DereferenceVisitor {
366
359
  refractCache: this.refractCache,
367
360
  ancestors: ancestorsLineage
368
361
  });
369
- referencedElement = await visitAsync(referencedElement, visitor, {
370
- keyMap: _apidomNsOpenapi.keyMap,
371
- nodeTypeGetter: _apidomNsOpenapi.getNodeType
362
+ referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
363
+ mutable: true
372
364
  });
373
365
 
374
366
  // remove referencing reference from ancestors lineage
@@ -380,9 +372,9 @@ class OpenAPI3_1DereferenceVisitor {
380
372
  * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
381
373
  */
382
374
  if ((0, _apidomNsOpenapi.isPathItemElement)(referencedElement)) {
383
- const mergedElement = new _apidomNsOpenapi.PathItemElement([...referencedElement.content], (0, _apidomCore.cloneDeep)(referencedElement.meta), (0, _apidomCore.cloneDeep)(referencedElement.attributes));
375
+ const mergedElement = (0, _apidomDatamodel.cloneShallow)(referencedElement);
384
376
  // assign unique id to merged element
385
- mergedElement.setMetaProperty('id', identityManager.generateId());
377
+ mergedElement.meta.set('id', identityManager.generateId());
386
378
  // existing keywords from referencing PathItemElement overrides ones from referenced element
387
379
  referencingElement.forEach((value, keyElement, item) => {
388
380
  mergedElement.remove((0, _apidomCore.toValue)(keyElement));
@@ -391,38 +383,35 @@ class OpenAPI3_1DereferenceVisitor {
391
383
  mergedElement.remove('$ref');
392
384
 
393
385
  // annotate referenced element with info about original referencing element
394
- mergedElement.setMetaProperty('ref-fields', {
386
+ mergedElement.meta.set('ref-fields', {
395
387
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
396
388
  });
397
389
  // annotate referenced element with info about origin
398
- mergedElement.setMetaProperty('ref-origin', reference.uri);
390
+ mergedElement.meta.set('ref-origin', reference.uri);
399
391
  // annotate fragment with info about referencing element
400
- mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
392
+ mergedElement.meta.set('ref-referencing-element-id', (0, _apidomDatamodel.cloneDeep)(identityManager.identify(referencingElement)));
401
393
  referencedElement = mergedElement;
402
394
  }
403
395
 
404
396
  /**
405
397
  * Transclude referencing element with merged referenced element.
406
398
  */
407
- link.replaceWith(referencedElement, mutationReplacer);
408
-
409
- /**
410
- * We're at the root of the tree, so we're just replacing the entire tree.
411
- */
412
- return !parent ? referencedElement : undefined;
399
+ path.replaceWith(referencedElement);
413
400
  }
414
- async LinkElement(linkElement, key, parent, path, ancestors, link) {
401
+ async LinkElement(path) {
402
+ const linkElement = path.node;
403
+
415
404
  // ignore LinkElement without operationRef or operationId field
416
- if (!(0, _apidomCore.isStringElement)(linkElement.operationRef) && !(0, _apidomCore.isStringElement)(linkElement.operationId)) {
417
- return undefined;
405
+ if (!(0, _apidomDatamodel.isStringElement)(linkElement.operationRef) && !(0, _apidomDatamodel.isStringElement)(linkElement.operationId)) {
406
+ return;
418
407
  }
419
408
 
420
409
  // operationRef and operationId fields are mutually exclusive
421
- if ((0, _apidomCore.isStringElement)(linkElement.operationRef) && (0, _apidomCore.isStringElement)(linkElement.operationId)) {
410
+ if ((0, _apidomDatamodel.isStringElement)(linkElement.operationRef) && (0, _apidomDatamodel.isStringElement)(linkElement.operationId)) {
422
411
  throw new _apidomError.ApiDOMError('LinkElement operationRef and operationId fields are mutually exclusive.');
423
412
  }
424
413
  let operationElement;
425
- if ((0, _apidomCore.isStringElement)(linkElement.operationRef)) {
414
+ if ((0, _apidomDatamodel.isStringElement)(linkElement.operationRef)) {
426
415
  // possibly non-semantic referenced element
427
416
  const jsonPointer = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference((0, _apidomCore.toValue)(linkElement.operationRef));
428
417
  const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(linkElement.operationRef));
@@ -432,73 +421,65 @@ class OpenAPI3_1DereferenceVisitor {
432
421
  // ignore resolving internal Operation Object reference
433
422
  if (!this.options.resolve.internal && isInternalReference) {
434
423
  // skip traversing this Link element but traverse all it's child elements
435
- return undefined;
424
+ return;
436
425
  }
437
426
  // ignore resolving external Operation Object reference
438
427
  if (!this.options.resolve.external && isExternalReference) {
439
428
  // skip traversing this Link element but traverse all it's child elements
440
- return undefined;
429
+ return;
441
430
  }
442
431
  const reference = await this.toReference((0, _apidomCore.toValue)(linkElement.operationRef));
443
432
  operationElement = (0, _apidomJsonPointer.evaluate)(reference.value.result, jsonPointer);
444
433
  // applying semantics to a referenced element
445
- if ((0, _apidomCore.isPrimitiveElement)(operationElement)) {
434
+ if ((0, _apidomDatamodel.isPrimitiveElement)(operationElement)) {
446
435
  const cacheKey = `operation-${(0, _apidomCore.toValue)(identityManager.identify(operationElement))}`;
447
436
  if (this.refractCache.has(cacheKey)) {
448
437
  operationElement = this.refractCache.get(cacheKey);
449
438
  } else {
450
- operationElement = _apidomNsOpenapi.OperationElement.refract(operationElement);
439
+ operationElement = (0, _apidomNsOpenapi.refractOperation)(operationElement);
451
440
  this.refractCache.set(cacheKey, operationElement);
452
441
  }
453
442
  }
454
443
  // create shallow clone to be able to annotate with metadata
455
- operationElement = (0, _apidomCore.cloneShallow)(operationElement);
444
+ operationElement = (0, _apidomDatamodel.cloneShallow)(operationElement);
456
445
  // annotate operation element with info about origin
457
- operationElement.setMetaProperty('ref-origin', reference.uri);
458
- const linkElementCopy = (0, _apidomCore.cloneShallow)(linkElement);
446
+ operationElement.meta.set('ref-origin', reference.uri);
447
+ const linkElementCopy = (0, _apidomDatamodel.cloneShallow)(linkElement);
459
448
  linkElementCopy.operationRef?.meta.set('operation', operationElement);
460
449
 
461
450
  /**
462
451
  * Transclude Link Object containing Operation Object in its meta.
463
452
  */
464
- link.replaceWith(linkElementCopy, mutationReplacer);
465
-
466
- /**
467
- * We're at the root of the tree, so we're just replacing the entire tree.
468
- */
469
- return !parent ? linkElementCopy : undefined;
453
+ path.replaceWith(linkElementCopy);
454
+ return;
470
455
  }
471
- if ((0, _apidomCore.isStringElement)(linkElement.operationId)) {
456
+ if ((0, _apidomDatamodel.isStringElement)(linkElement.operationId)) {
472
457
  const operationId = (0, _apidomCore.toValue)(linkElement.operationId);
473
458
  const reference = await this.toReference(url.unsanitize(this.reference.uri));
474
- operationElement = (0, _apidomCore.find)(e => (0, _apidomNsOpenapi.isOperationElement)(e) && (0, _apidomCore.isElement)(e.operationId) && e.operationId.equals(operationId), reference.value.result);
459
+ operationElement = (0, _apidomTraverse.find)(reference.value.result, e => (0, _apidomNsOpenapi.isOperationElement)(e) && (0, _apidomDatamodel.isElement)(e.operationId) && e.operationId.equals(operationId));
475
460
  // OperationElement not found by its operationId
476
461
  if ((0, _ramdaAdjunct.isUndefined)(operationElement)) {
477
462
  throw new _apidomError.ApiDOMError(`OperationElement(operationId=${operationId}) not found.`);
478
463
  }
479
- const linkElementCopy = (0, _apidomCore.cloneShallow)(linkElement);
464
+ const linkElementCopy = (0, _apidomDatamodel.cloneShallow)(linkElement);
480
465
  linkElementCopy.operationId?.meta.set('operation', operationElement);
481
466
 
482
467
  /**
483
468
  * Transclude Link Object containing Operation Object in its meta.
484
469
  */
485
- link.replaceWith(linkElementCopy, mutationReplacer);
486
-
487
- /**
488
- * We're at the root of the tree, so we're just replacing the entire tree.
489
- */
490
- return !parent ? linkElementCopy : undefined;
470
+ path.replaceWith(linkElementCopy);
491
471
  }
492
- return undefined;
493
472
  }
494
- async ExampleElement(exampleElement, key, parent, path, ancestors, link) {
473
+ async ExampleElement(path) {
474
+ const exampleElement = path.node;
475
+
495
476
  // ignore ExampleElement without externalValue field
496
- if (!(0, _apidomCore.isStringElement)(exampleElement.externalValue)) {
497
- return undefined;
477
+ if (!(0, _apidomDatamodel.isStringElement)(exampleElement.externalValue)) {
478
+ return;
498
479
  }
499
480
 
500
481
  // value and externalValue fields are mutually exclusive
501
- if (exampleElement.hasKey('value') && (0, _apidomCore.isStringElement)(exampleElement.externalValue)) {
482
+ if (exampleElement.hasKey('value') && (0, _apidomDatamodel.isStringElement)(exampleElement.externalValue)) {
502
483
  throw new _apidomError.ApiDOMError('ExampleElement value and externalValue fields are mutually exclusive.');
503
484
  }
504
485
  const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(exampleElement.externalValue));
@@ -508,43 +489,41 @@ class OpenAPI3_1DereferenceVisitor {
508
489
  // ignore resolving internal Example Objects
509
490
  if (!this.options.resolve.internal && isInternalReference) {
510
491
  // skip traversing this Example element but traverse all it's child elements
511
- return undefined;
492
+ return;
512
493
  }
513
494
  // ignore resolving external Example Objects
514
495
  if (!this.options.resolve.external && isExternalReference) {
515
496
  // skip traversing this Example element but traverse all it's child elements
516
- return undefined;
497
+ return;
517
498
  }
518
499
  const reference = await this.toReference((0, _apidomCore.toValue)(exampleElement.externalValue));
519
500
 
520
501
  // shallow clone of the referenced element
521
- const valueElement = (0, _apidomCore.cloneShallow)(reference.value.result);
502
+ const valueElement = (0, _apidomDatamodel.cloneShallow)(reference.value.result);
522
503
  // annotate operation element with info about origin
523
- valueElement.setMetaProperty('ref-origin', reference.uri);
524
- const exampleElementCopy = (0, _apidomCore.cloneShallow)(exampleElement);
504
+ valueElement.meta.set('ref-origin', reference.uri);
505
+ const exampleElementCopy = (0, _apidomDatamodel.cloneShallow)(exampleElement);
525
506
  exampleElementCopy.value = valueElement;
526
507
 
527
508
  /**
528
509
  * Transclude Example Object containing external value.
529
510
  */
530
- link.replaceWith(exampleElementCopy, mutationReplacer);
531
-
532
- /**
533
- * We're at the root of the tree, so we're just replacing the entire tree.
534
- */
535
- return !parent ? exampleElementCopy : undefined;
511
+ path.replaceWith(exampleElementCopy);
536
512
  }
537
- async SchemaElement(referencingElement, key, parent, path, ancestors, link) {
513
+ async SchemaElement(path) {
514
+ const referencingElement = path.node;
515
+
538
516
  // skip current referencing schema as $ref keyword was not defined
539
- if (!(0, _apidomCore.isStringElement)(referencingElement.$ref)) {
540
- return undefined;
517
+ if (!(0, _apidomDatamodel.isStringElement)(referencingElement.$ref)) {
518
+ return;
541
519
  }
542
520
 
543
521
  // skip current referencing element as it's already been access
544
522
  if (this.indirections.includes(referencingElement)) {
545
- return false;
523
+ path.skip();
524
+ return;
546
525
  }
547
- const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
526
+ const [ancestorsLineage, directAncestors] = this.toAncestorLineage(path);
548
527
 
549
528
  // compute baseURI using rules around $id and $ref keywords
550
529
  let reference = await this.toReference(url.unsanitize(this.reference.uri));
@@ -577,12 +556,12 @@ class OpenAPI3_1DereferenceVisitor {
577
556
  // ignore resolving internal Schema Objects
578
557
  if (!this.options.resolve.internal && isInternalReference) {
579
558
  // skip traversing this schema element but traverse all it's child elements
580
- return undefined;
559
+ return;
581
560
  }
582
561
  // ignore resolving external Schema Objects
583
562
  if (!this.options.resolve.external && isExternalReference) {
584
563
  // skip traversing this schema element but traverse all it's child elements
585
- return undefined;
564
+ return;
586
565
  }
587
566
  } else {
588
567
  // we're assuming here that we're dealing with JSON Pointer here
@@ -593,12 +572,12 @@ class OpenAPI3_1DereferenceVisitor {
593
572
  // ignore resolving internal Schema Objects
594
573
  if (!this.options.resolve.internal && isInternalReference) {
595
574
  // skip traversing this schema element but traverse all it's child elements
596
- return undefined;
575
+ return;
597
576
  }
598
577
  // ignore resolving external Schema Objects
599
578
  if (!this.options.resolve.external && isExternalReference) {
600
579
  // skip traversing this schema element but traverse all it's child elements
601
- return undefined;
580
+ return;
602
581
  }
603
582
  reference = await this.toReference(url.unsanitize($refBaseURI));
604
583
  const selector = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference($refBaseURI);
@@ -621,12 +600,12 @@ class OpenAPI3_1DereferenceVisitor {
621
600
  // ignore resolving internal Schema Objects
622
601
  if (!this.options.resolve.internal && isInternalReference) {
623
602
  // skip traversing this schema element but traverse all it's child elements
624
- return undefined;
603
+ return;
625
604
  }
626
605
  // ignore resolving external Schema Objects
627
606
  if (!this.options.resolve.external && isExternalReference) {
628
607
  // skip traversing this schema element but traverse all it's child elements
629
- return undefined;
608
+ return;
630
609
  }
631
610
  reference = await this.toReference(url.unsanitize($refBaseURI));
632
611
  const selector = (0, _$anchor.uriToAnchor)($refBaseURI);
@@ -643,12 +622,12 @@ class OpenAPI3_1DereferenceVisitor {
643
622
  // ignore resolving internal Schema Objects
644
623
  if (!this.options.resolve.internal && isInternalReference) {
645
624
  // skip traversing this schema element but traverse all it's child elements
646
- return undefined;
625
+ return;
647
626
  }
648
627
  // ignore resolving external Schema Objects
649
628
  if (!this.options.resolve.external && isExternalReference) {
650
629
  // skip traversing this schema element but traverse all it's child elements
651
- return undefined;
630
+ return;
652
631
  }
653
632
  reference = await this.toReference(url.unsanitize($refBaseURI));
654
633
  const selector = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference($refBaseURI);
@@ -678,15 +657,16 @@ class OpenAPI3_1DereferenceVisitor {
678
657
  if (this.options.dereference.circular === 'error') {
679
658
  throw new _apidomError.ApiDOMError('Circular reference detected');
680
659
  } else if (this.options.dereference.circular === 'replace') {
681
- const refElement = new _apidomCore.RefElement(referencedElement.id, {
660
+ const refElement = new _apidomDatamodel.RefElement(referencedElement.id, {
682
661
  type: 'json-schema',
683
662
  uri: reference.uri,
684
663
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
685
664
  });
686
665
  const replacer = this.options.dereference.strategyOpts['openapi-3-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
687
666
  const replacement = replacer(refElement);
688
- link.replaceWith(replacement, mutationReplacer);
689
- return !parent ? replacement : false;
667
+ this.indirections.pop();
668
+ path.replaceWith(replacement);
669
+ return;
690
670
  }
691
671
  }
692
672
 
@@ -701,7 +681,7 @@ class OpenAPI3_1DereferenceVisitor {
701
681
  */
702
682
  const isNonRootDocument = url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
703
683
  const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
704
- if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isSchemaElement)(referencedElement) && (0, _apidomCore.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
684
+ if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isSchemaElement)(referencedElement) && (0, _apidomDatamodel.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
705
685
  // append referencing reference to ancestors lineage
706
686
  directAncestors.add(referencingElement);
707
687
  const visitor = new OpenAPI3_1DereferenceVisitor({
@@ -712,9 +692,8 @@ class OpenAPI3_1DereferenceVisitor {
712
692
  refractCache: this.refractCache,
713
693
  ancestors: ancestorsLineage
714
694
  });
715
- referencedElement = await visitAsync(referencedElement, visitor, {
716
- keyMap: _apidomNsOpenapi.keyMap,
717
- nodeTypeGetter: _apidomNsOpenapi.getNodeType
695
+ referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
696
+ mutable: true
718
697
  });
719
698
 
720
699
  // remove referencing reference from ancestors lineage
@@ -724,28 +703,28 @@ class OpenAPI3_1DereferenceVisitor {
724
703
 
725
704
  // Boolean JSON Schemas
726
705
  if ((0, _apidomNsOpenapi.isBooleanJsonSchemaElement)(referencedElement)) {
727
- const booleanJsonSchemaElement = (0, _apidomCore.cloneDeep)(referencedElement);
706
+ const booleanJsonSchemaElement = (0, _apidomDatamodel.cloneDeep)(referencedElement);
728
707
  // assign unique id to merged element
729
- booleanJsonSchemaElement.setMetaProperty('id', identityManager.generateId());
708
+ booleanJsonSchemaElement.meta.set('id', identityManager.generateId());
730
709
  // annotate referenced element with info about original referencing element
731
- booleanJsonSchemaElement.setMetaProperty('ref-fields', {
710
+ booleanJsonSchemaElement.meta.set('ref-fields', {
732
711
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
733
712
  });
734
713
  // annotate referenced element with info about origin
735
- booleanJsonSchemaElement.setMetaProperty('ref-origin', reference.uri);
714
+ booleanJsonSchemaElement.meta.set('ref-origin', reference.uri);
736
715
  // annotate fragment with info about referencing element
737
- booleanJsonSchemaElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
738
- link.replaceWith(booleanJsonSchemaElement, mutationReplacer);
739
- return !parent ? booleanJsonSchemaElement : false;
716
+ booleanJsonSchemaElement.meta.set('ref-referencing-element-id', (0, _apidomDatamodel.cloneDeep)(identityManager.identify(referencingElement)));
717
+ path.replaceWith(booleanJsonSchemaElement);
718
+ return;
740
719
  }
741
720
 
742
721
  /**
743
722
  * Creating a new version of Schema Object by merging fields from referenced Schema Object with referencing one.
744
723
  */
745
724
  if ((0, _apidomNsOpenapi.isSchemaElement)(referencedElement)) {
746
- const mergedElement = new _apidomNsOpenapi.SchemaElement([...referencedElement.content], (0, _apidomCore.cloneDeep)(referencedElement.meta), (0, _apidomCore.cloneDeep)(referencedElement.attributes));
725
+ const mergedElement = (0, _apidomDatamodel.cloneShallow)(referencedElement);
747
726
  // assign unique id to merged element
748
- mergedElement.setMetaProperty('id', identityManager.generateId());
727
+ mergedElement.meta.set('id', identityManager.generateId());
749
728
  // existing keywords from referencing schema overrides ones from referenced schema
750
729
  referencingElement.forEach((value, keyElement, item) => {
751
730
  mergedElement.remove((0, _apidomCore.toValue)(keyElement));
@@ -753,24 +732,19 @@ class OpenAPI3_1DereferenceVisitor {
753
732
  });
754
733
  mergedElement.remove('$ref');
755
734
  // annotate referenced element with info about original referencing element
756
- mergedElement.setMetaProperty('ref-fields', {
735
+ mergedElement.meta.set('ref-fields', {
757
736
  $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
758
737
  });
759
738
  // annotate fragment with info about origin
760
- mergedElement.setMetaProperty('ref-origin', reference.uri);
739
+ mergedElement.meta.set('ref-origin', reference.uri);
761
740
  // annotate fragment with info about referencing element
762
- mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
741
+ mergedElement.meta.set('ref-referencing-element-id', (0, _apidomDatamodel.cloneDeep)(identityManager.identify(referencingElement)));
763
742
  referencedElement = mergedElement;
764
743
  }
765
744
  /**
766
745
  * Transclude referencing element with merged referenced element.
767
746
  */
768
- link.replaceWith(referencedElement, mutationReplacer);
769
-
770
- /**
771
- * We're at the root of the tree, so we're just replacing the entire tree.
772
- */
773
- return !parent ? referencedElement : undefined;
747
+ path.replaceWith(referencedElement);
774
748
  }
775
749
  }
776
750
  var _default = exports.default = OpenAPI3_1DereferenceVisitor;