@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.
- package/CHANGELOG.md +25 -0
- package/NOTICE +16 -7
- package/README.md +0 -33
- package/dist/167.apidom-reference.browser.min.js +1 -1
- package/dist/451.apidom-reference.browser.min.js +1 -1
- package/dist/apidom-reference.browser.js +24594 -23365
- package/dist/apidom-reference.browser.min.js +1 -1
- package/package.json +24 -57
- package/src/configuration/saturated.cjs +34 -42
- package/src/configuration/saturated.mjs +0 -8
- package/src/dereference/index.cjs +4 -4
- package/src/dereference/index.mjs +1 -1
- package/src/dereference/strategies/apidom/index.cjs +7 -7
- package/src/dereference/strategies/apidom/index.mjs +5 -6
- package/src/dereference/strategies/apidom/selectors/element-id.cjs +4 -2
- package/src/dereference/strategies/apidom/selectors/element-id.mjs +5 -3
- package/src/dereference/strategies/apidom/visitor.cjs +31 -17
- package/src/dereference/strategies/apidom/visitor.mjs +25 -12
- package/src/dereference/strategies/asyncapi-2/index.cjs +6 -9
- package/src/dereference/strategies/asyncapi-2/index.mjs +6 -10
- package/src/dereference/strategies/asyncapi-2/visitor.cjs +67 -80
- package/src/dereference/strategies/asyncapi-2/visitor.mjs +59 -72
- package/src/dereference/strategies/openapi-2/index.cjs +6 -9
- package/src/dereference/strategies/openapi-2/index.mjs +6 -10
- package/src/dereference/strategies/openapi-2/visitor.cjs +91 -100
- package/src/dereference/strategies/openapi-2/visitor.mjs +81 -90
- package/src/dereference/strategies/openapi-3-0/index.cjs +6 -9
- package/src/dereference/strategies/openapi-3-0/index.mjs +6 -10
- package/src/dereference/strategies/openapi-3-0/visitor.cjs +92 -115
- package/src/dereference/strategies/openapi-3-0/visitor.mjs +74 -97
- package/src/dereference/strategies/openapi-3-1/index.cjs +6 -9
- package/src/dereference/strategies/openapi-3-1/index.mjs +6 -10
- package/src/dereference/strategies/openapi-3-1/selectors/$anchor.cjs +2 -1
- package/src/dereference/strategies/openapi-3-1/selectors/$anchor.mjs +3 -2
- package/src/dereference/strategies/openapi-3-1/selectors/uri.cjs +2 -2
- package/src/dereference/strategies/openapi-3-1/selectors/uri.mjs +2 -2
- package/src/dereference/strategies/openapi-3-1/util.cjs +3 -2
- package/src/dereference/strategies/openapi-3-1/util.mjs +4 -3
- package/src/dereference/strategies/openapi-3-1/visitor.cjs +130 -156
- package/src/dereference/strategies/openapi-3-1/visitor.mjs +106 -132
- package/src/dereference/util.cjs +2 -2
- package/src/dereference/util.mjs +1 -1
- package/src/parse/parsers/apidom-json/index.cjs +5 -5
- package/src/parse/parsers/apidom-json/index.mjs +2 -2
- package/src/parse/parsers/arazzo-json-1/index.cjs +1 -2
- package/src/parse/parsers/arazzo-json-1/index.mjs +1 -2
- package/src/parse/parsers/asyncapi-json-2/index.cjs +1 -2
- package/src/parse/parsers/asyncapi-json-2/index.mjs +1 -2
- package/src/parse/parsers/binary/index-browser.cjs +3 -3
- package/src/parse/parsers/binary/index-browser.mjs +1 -1
- package/src/parse/parsers/binary/index-node.cjs +3 -3
- package/src/parse/parsers/binary/index-node.mjs +1 -1
- package/src/parse/parsers/json/index.cjs +1 -2
- package/src/parse/parsers/json/index.mjs +1 -2
- package/src/parse/parsers/openapi-json-2/index.cjs +1 -2
- package/src/parse/parsers/openapi-json-2/index.mjs +1 -2
- package/src/parse/parsers/openapi-json-3-0/index.cjs +1 -2
- package/src/parse/parsers/openapi-json-3-0/index.mjs +1 -2
- package/src/parse/parsers/openapi-json-3-1/index.cjs +1 -2
- package/src/parse/parsers/openapi-json-3-1/index.mjs +1 -2
- package/src/resolve/index.cjs +4 -4
- package/src/resolve/index.mjs +1 -1
- package/types/File.d.ts +1 -1
- package/types/Reference.d.ts +1 -1
- package/types/ReferenceSet.d.ts +1 -1
- package/types/apidom-reference.d.ts +8 -9
- package/types/bundle/index.d.ts +1 -1
- package/types/bundle/strategies/BundleStrategy.d.ts +1 -1
- package/types/bundle/strategies/openapi-3-1/index.d.ts +1 -1
- package/types/dereference/index.d.ts +1 -1
- package/types/dereference/strategies/DereferenceStrategy.d.ts +1 -1
- package/types/dereference/strategies/apidom/index.d.ts +1 -1
- package/types/dereference/strategies/apidom/selectors/element-id.d.ts +1 -1
- package/types/dereference/strategies/apidom/visitor.d.ts +3 -2
- package/types/dereference/strategies/asyncapi-2/index.d.ts +2 -2
- package/types/dereference/strategies/asyncapi-2/visitor.d.ts +5 -14
- package/types/dereference/strategies/openapi-2/index.d.ts +2 -2
- package/types/dereference/strategies/openapi-2/visitor.d.ts +6 -17
- package/types/dereference/strategies/openapi-3-0/index.d.ts +2 -2
- package/types/dereference/strategies/openapi-3-0/visitor.d.ts +7 -20
- package/types/dereference/strategies/openapi-3-1/index.d.ts +2 -2
- package/types/dereference/strategies/openapi-3-1/selectors/$anchor.d.ts +1 -1
- package/types/dereference/strategies/openapi-3-1/selectors/uri.d.ts +1 -1
- package/types/dereference/strategies/openapi-3-1/util.d.ts +1 -1
- package/types/dereference/strategies/openapi-3-1/visitor.d.ts +8 -23
- package/types/dereference/util.d.ts +1 -1
- package/types/index.d.ts +1 -1
- package/types/options/index.d.ts +1 -1
- package/types/parse/index.d.ts +1 -1
- package/types/parse/parsers/Parser.d.ts +1 -1
- package/types/parse/parsers/apidom-json/index.d.ts +1 -1
- package/types/parse/parsers/arazzo-json-1/index.d.ts +1 -2
- package/types/parse/parsers/arazzo-yaml-1/index.d.ts +1 -1
- package/types/parse/parsers/asyncapi-json-2/index.d.ts +1 -2
- package/types/parse/parsers/asyncapi-yaml-2/index.d.ts +1 -1
- package/types/parse/parsers/binary/index-browser.d.ts +1 -1
- package/types/parse/parsers/binary/index-node.d.ts +1 -1
- package/types/parse/parsers/json/index.d.ts +1 -2
- package/types/parse/parsers/openapi-json-2/index.d.ts +1 -2
- package/types/parse/parsers/openapi-json-3-0/index.d.ts +1 -2
- package/types/parse/parsers/openapi-json-3-1/index.d.ts +1 -2
- package/types/parse/parsers/openapi-yaml-2/index.d.ts +1 -1
- package/types/parse/parsers/openapi-yaml-3-0/index.d.ts +1 -1
- package/types/parse/parsers/openapi-yaml-3-1/index.d.ts +1 -1
- package/types/parse/parsers/yaml-1-2/index.d.ts +1 -1
- package/types/resolve/index.d.ts +1 -1
- package/src/parse/parsers/api-design-systems-json/index.cjs +0 -55
- package/src/parse/parsers/api-design-systems-json/index.mjs +0 -49
- package/src/parse/parsers/api-design-systems-yaml/index.cjs +0 -54
- package/src/parse/parsers/api-design-systems-yaml/index.mjs +0 -48
- package/types/parse/parsers/api-design-systems-json/index.d.ts +0 -21
- package/types/parse/parsers/api-design-systems-yaml/index.d.ts +0 -20
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { propEq, none } from 'ramda';
|
|
2
2
|
import { isUndefined } from 'ramda-adjunct';
|
|
3
|
-
import { isElement, isPrimitiveElement, isStringElement,
|
|
3
|
+
import { isElement, isPrimitiveElement, isStringElement, isObjectElement, RefElement, cloneShallow, cloneDeep } from '@speclynx/apidom-datamodel';
|
|
4
|
+
import { IdentityManager, toValue } from '@speclynx/apidom-core';
|
|
4
5
|
import { ApiDOMError } from '@speclynx/apidom-error';
|
|
6
|
+
import { traverseAsync, find } from '@speclynx/apidom-traverse';
|
|
5
7
|
import { evaluate as jsonPointerEvaluate, URIFragmentIdentifier } from '@speclynx/apidom-json-pointer';
|
|
6
|
-
import {
|
|
8
|
+
import { isReferenceLikeElement, isPathItemElement, isReferenceElement, isSchemaElement, isOperationElement, isBooleanJsonSchemaElement, refract, refractReference, refractPathItem, refractOperation } from '@speclynx/apidom-ns-openapi-3-1';
|
|
7
9
|
import { isAnchor, uriToAnchor, evaluate as $anchorEvaluate } from "./selectors/$anchor.mjs";
|
|
8
10
|
import { evaluate as uriEvaluate } from "./selectors/uri.mjs";
|
|
9
11
|
import MaximumDereferenceDepthError from "../../../errors/MaximumDereferenceDepthError.mjs";
|
|
@@ -15,24 +17,9 @@ import File from "../../../File.mjs";
|
|
|
15
17
|
import { resolveSchema$refField, maybeRefractToSchemaElement } from "./util.mjs";
|
|
16
18
|
import { AncestorLineage } from "../../util.mjs";
|
|
17
19
|
import EvaluationJsonSchemaUriError from "../../../errors/EvaluationJsonSchemaUriError.mjs";
|
|
18
|
-
// @ts-ignore
|
|
19
|
-
const visitAsync = visit[Symbol.for('nodejs.util.promisify.custom')];
|
|
20
|
-
|
|
21
20
|
// initialize element identity manager
|
|
22
21
|
const identityManager = new IdentityManager();
|
|
23
22
|
|
|
24
|
-
/**
|
|
25
|
-
* Custom mutation replacer.
|
|
26
|
-
* @public
|
|
27
|
-
*/
|
|
28
|
-
export const mutationReplacer = (newElement, oldElement, key, parent) => {
|
|
29
|
-
if (isMemberElement(parent)) {
|
|
30
|
-
parent.value = newElement;
|
|
31
|
-
} else if (Array.isArray(parent)) {
|
|
32
|
-
parent[key] = newElement;
|
|
33
|
-
}
|
|
34
|
-
};
|
|
35
|
-
|
|
36
23
|
/**
|
|
37
24
|
* @public
|
|
38
25
|
*/
|
|
@@ -105,21 +92,25 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
105
92
|
}
|
|
106
93
|
return mutableReference;
|
|
107
94
|
}
|
|
108
|
-
toAncestorLineage(
|
|
95
|
+
toAncestorLineage(path) {
|
|
109
96
|
/**
|
|
110
97
|
* Compute full ancestors lineage.
|
|
111
98
|
* Ancestors are flatten to unwrap all Element instances.
|
|
112
99
|
*/
|
|
113
|
-
const
|
|
100
|
+
const ancestorNodes = path.getAncestorNodes();
|
|
101
|
+
const directAncestors = new Set(ancestorNodes.filter(isElement));
|
|
114
102
|
const ancestorsLineage = new AncestorLineage(...this.ancestors, directAncestors);
|
|
115
103
|
return [ancestorsLineage, directAncestors];
|
|
116
104
|
}
|
|
117
|
-
async ReferenceElement(
|
|
105
|
+
async ReferenceElement(path) {
|
|
106
|
+
const referencingElement = path.node;
|
|
107
|
+
|
|
118
108
|
// skip current referencing element as it's already been access
|
|
119
109
|
if (this.indirections.includes(referencingElement)) {
|
|
120
|
-
|
|
110
|
+
path.skip();
|
|
111
|
+
return;
|
|
121
112
|
}
|
|
122
|
-
const [ancestorsLineage, directAncestors] = this.toAncestorLineage(
|
|
113
|
+
const [ancestorsLineage, directAncestors] = this.toAncestorLineage(path);
|
|
123
114
|
const retrievalURI = this.toBaseURI(toValue(referencingElement.$ref));
|
|
124
115
|
const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
|
|
125
116
|
const isExternalReference = !isInternalReference;
|
|
@@ -127,12 +118,14 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
127
118
|
// ignore resolving internal Reference Objects
|
|
128
119
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
129
120
|
// skip traversing this reference element and all it's child elements
|
|
130
|
-
|
|
121
|
+
path.skip();
|
|
122
|
+
return;
|
|
131
123
|
}
|
|
132
124
|
// ignore resolving external Reference Objects
|
|
133
125
|
if (!this.options.resolve.external && isExternalReference) {
|
|
134
126
|
// skip traversing this reference element and all it's child elements
|
|
135
|
-
|
|
127
|
+
path.skip();
|
|
128
|
+
return;
|
|
136
129
|
}
|
|
137
130
|
const reference = await this.toReference(toValue(referencingElement.$ref));
|
|
138
131
|
const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
|
|
@@ -151,13 +144,14 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
151
144
|
referencedElement = this.refractCache.get(cacheKey);
|
|
152
145
|
} else if (isReferenceLikeElement(referencedElement)) {
|
|
153
146
|
// handling indirect references
|
|
154
|
-
referencedElement =
|
|
155
|
-
referencedElement.
|
|
147
|
+
referencedElement = refractReference(referencedElement);
|
|
148
|
+
referencedElement.meta.set('referenced-element', referencedElementType);
|
|
156
149
|
this.refractCache.set(cacheKey, referencedElement);
|
|
157
150
|
} else {
|
|
158
151
|
// handling direct references
|
|
159
|
-
|
|
160
|
-
|
|
152
|
+
referencedElement = refract(referencedElement, {
|
|
153
|
+
element: referencedElementType
|
|
154
|
+
});
|
|
161
155
|
this.refractCache.set(cacheKey, referencedElement);
|
|
162
156
|
}
|
|
163
157
|
}
|
|
@@ -185,8 +179,9 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
185
179
|
});
|
|
186
180
|
const replacer = this.options.dereference.strategyOpts['openapi-3-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
|
|
187
181
|
const replacement = replacer(refElement);
|
|
188
|
-
|
|
189
|
-
|
|
182
|
+
this.indirections.pop();
|
|
183
|
+
path.replaceWith(replacement);
|
|
184
|
+
return;
|
|
190
185
|
}
|
|
191
186
|
}
|
|
192
187
|
|
|
@@ -212,9 +207,8 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
212
207
|
refractCache: this.refractCache,
|
|
213
208
|
ancestors: ancestorsLineage
|
|
214
209
|
});
|
|
215
|
-
referencedElement = await
|
|
216
|
-
|
|
217
|
-
nodeTypeGetter: getNodeType
|
|
210
|
+
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
211
|
+
mutable: true
|
|
218
212
|
});
|
|
219
213
|
|
|
220
214
|
// remove referencing reference from ancestors lineage
|
|
@@ -227,9 +221,9 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
227
221
|
*/
|
|
228
222
|
const mergedElement = cloneShallow(referencedElement);
|
|
229
223
|
// assign unique id to merged element
|
|
230
|
-
mergedElement.
|
|
224
|
+
mergedElement.meta.set('id', identityManager.generateId());
|
|
231
225
|
// annotate fragment with info about original Reference element
|
|
232
|
-
mergedElement.
|
|
226
|
+
mergedElement.meta.set('ref-fields', {
|
|
233
227
|
$ref: toValue(referencingElement.$ref),
|
|
234
228
|
// @ts-ignore
|
|
235
229
|
description: toValue(referencingElement.description),
|
|
@@ -237,9 +231,9 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
237
231
|
summary: toValue(referencingElement.summary)
|
|
238
232
|
});
|
|
239
233
|
// annotate fragment with info about origin
|
|
240
|
-
mergedElement.
|
|
234
|
+
mergedElement.meta.set('ref-origin', reference.uri);
|
|
241
235
|
// annotate fragment with info about referencing element
|
|
242
|
-
mergedElement.
|
|
236
|
+
mergedElement.meta.set('ref-referencing-element-id', cloneDeep(identityManager.identify(referencingElement)));
|
|
243
237
|
|
|
244
238
|
// override description and summary (outer has higher priority then inner)
|
|
245
239
|
if (isObjectElement(referencedElement) && isObjectElement(mergedElement)) {
|
|
@@ -256,37 +250,35 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
256
250
|
/**
|
|
257
251
|
* Transclude referencing element with merged referenced element.
|
|
258
252
|
*/
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
/**
|
|
262
|
-
* We're at the root of the tree, so we're just replacing the entire tree.
|
|
263
|
-
*/
|
|
264
|
-
return !parent ? mergedElement : false;
|
|
253
|
+
path.replaceWith(mergedElement);
|
|
265
254
|
}
|
|
266
|
-
async PathItemElement(
|
|
255
|
+
async PathItemElement(path) {
|
|
256
|
+
const referencingElement = path.node;
|
|
257
|
+
|
|
267
258
|
// ignore PathItemElement without $ref field
|
|
268
259
|
if (!isStringElement(referencingElement.$ref)) {
|
|
269
|
-
return
|
|
260
|
+
return;
|
|
270
261
|
}
|
|
271
262
|
|
|
272
263
|
// skip current referencing element as it's already been access
|
|
273
264
|
if (this.indirections.includes(referencingElement)) {
|
|
274
|
-
|
|
265
|
+
path.skip();
|
|
266
|
+
return;
|
|
275
267
|
}
|
|
276
|
-
const [ancestorsLineage, directAncestors] = this.toAncestorLineage(
|
|
268
|
+
const [ancestorsLineage, directAncestors] = this.toAncestorLineage(path);
|
|
277
269
|
const retrievalURI = this.toBaseURI(toValue(referencingElement.$ref));
|
|
278
270
|
const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
|
|
279
271
|
const isExternalReference = !isInternalReference;
|
|
280
272
|
|
|
281
|
-
// ignore resolving
|
|
273
|
+
// ignore resolving internal Path Item Objects
|
|
282
274
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
283
275
|
// skip traversing this Path Item element but traverse all it's child elements
|
|
284
|
-
return
|
|
276
|
+
return;
|
|
285
277
|
}
|
|
286
278
|
// ignore resolving external Path Item Objects
|
|
287
279
|
if (!this.options.resolve.external && isExternalReference) {
|
|
288
280
|
// skip traversing this Path Item element but traverse all it's child elements
|
|
289
|
-
return
|
|
281
|
+
return;
|
|
290
282
|
}
|
|
291
283
|
const reference = await this.toReference(toValue(referencingElement.$ref));
|
|
292
284
|
const $refBaseURI = url.resolve(retrievalURI, toValue(referencingElement.$ref));
|
|
@@ -305,7 +297,7 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
305
297
|
if (this.refractCache.has(cacheKey)) {
|
|
306
298
|
referencedElement = this.refractCache.get(cacheKey);
|
|
307
299
|
} else {
|
|
308
|
-
referencedElement =
|
|
300
|
+
referencedElement = refractPathItem(referencedElement);
|
|
309
301
|
this.refractCache.set(cacheKey, referencedElement);
|
|
310
302
|
}
|
|
311
303
|
}
|
|
@@ -333,8 +325,9 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
333
325
|
});
|
|
334
326
|
const replacer = this.options.dereference.strategyOpts['openapi-3-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
|
|
335
327
|
const replacement = replacer(refElement);
|
|
336
|
-
|
|
337
|
-
|
|
328
|
+
this.indirections.pop();
|
|
329
|
+
path.replaceWith(replacement);
|
|
330
|
+
return;
|
|
338
331
|
}
|
|
339
332
|
}
|
|
340
333
|
|
|
@@ -360,9 +353,8 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
360
353
|
refractCache: this.refractCache,
|
|
361
354
|
ancestors: ancestorsLineage
|
|
362
355
|
});
|
|
363
|
-
referencedElement = await
|
|
364
|
-
|
|
365
|
-
nodeTypeGetter: getNodeType
|
|
356
|
+
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
357
|
+
mutable: true
|
|
366
358
|
});
|
|
367
359
|
|
|
368
360
|
// remove referencing reference from ancestors lineage
|
|
@@ -374,9 +366,9 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
374
366
|
* Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
|
|
375
367
|
*/
|
|
376
368
|
if (isPathItemElement(referencedElement)) {
|
|
377
|
-
const mergedElement =
|
|
369
|
+
const mergedElement = cloneShallow(referencedElement);
|
|
378
370
|
// assign unique id to merged element
|
|
379
|
-
mergedElement.
|
|
371
|
+
mergedElement.meta.set('id', identityManager.generateId());
|
|
380
372
|
// existing keywords from referencing PathItemElement overrides ones from referenced element
|
|
381
373
|
referencingElement.forEach((value, keyElement, item) => {
|
|
382
374
|
mergedElement.remove(toValue(keyElement));
|
|
@@ -385,30 +377,27 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
385
377
|
mergedElement.remove('$ref');
|
|
386
378
|
|
|
387
379
|
// annotate referenced element with info about original referencing element
|
|
388
|
-
mergedElement.
|
|
380
|
+
mergedElement.meta.set('ref-fields', {
|
|
389
381
|
$ref: toValue(referencingElement.$ref)
|
|
390
382
|
});
|
|
391
383
|
// annotate referenced element with info about origin
|
|
392
|
-
mergedElement.
|
|
384
|
+
mergedElement.meta.set('ref-origin', reference.uri);
|
|
393
385
|
// annotate fragment with info about referencing element
|
|
394
|
-
mergedElement.
|
|
386
|
+
mergedElement.meta.set('ref-referencing-element-id', cloneDeep(identityManager.identify(referencingElement)));
|
|
395
387
|
referencedElement = mergedElement;
|
|
396
388
|
}
|
|
397
389
|
|
|
398
390
|
/**
|
|
399
391
|
* Transclude referencing element with merged referenced element.
|
|
400
392
|
*/
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
/**
|
|
404
|
-
* We're at the root of the tree, so we're just replacing the entire tree.
|
|
405
|
-
*/
|
|
406
|
-
return !parent ? referencedElement : undefined;
|
|
393
|
+
path.replaceWith(referencedElement);
|
|
407
394
|
}
|
|
408
|
-
async LinkElement(
|
|
395
|
+
async LinkElement(path) {
|
|
396
|
+
const linkElement = path.node;
|
|
397
|
+
|
|
409
398
|
// ignore LinkElement without operationRef or operationId field
|
|
410
399
|
if (!isStringElement(linkElement.operationRef) && !isStringElement(linkElement.operationId)) {
|
|
411
|
-
return
|
|
400
|
+
return;
|
|
412
401
|
}
|
|
413
402
|
|
|
414
403
|
// operationRef and operationId fields are mutually exclusive
|
|
@@ -426,12 +415,12 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
426
415
|
// ignore resolving internal Operation Object reference
|
|
427
416
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
428
417
|
// skip traversing this Link element but traverse all it's child elements
|
|
429
|
-
return
|
|
418
|
+
return;
|
|
430
419
|
}
|
|
431
420
|
// ignore resolving external Operation Object reference
|
|
432
421
|
if (!this.options.resolve.external && isExternalReference) {
|
|
433
422
|
// skip traversing this Link element but traverse all it's child elements
|
|
434
|
-
return
|
|
423
|
+
return;
|
|
435
424
|
}
|
|
436
425
|
const reference = await this.toReference(toValue(linkElement.operationRef));
|
|
437
426
|
operationElement = jsonPointerEvaluate(reference.value.result, jsonPointer);
|
|
@@ -441,31 +430,27 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
441
430
|
if (this.refractCache.has(cacheKey)) {
|
|
442
431
|
operationElement = this.refractCache.get(cacheKey);
|
|
443
432
|
} else {
|
|
444
|
-
operationElement =
|
|
433
|
+
operationElement = refractOperation(operationElement);
|
|
445
434
|
this.refractCache.set(cacheKey, operationElement);
|
|
446
435
|
}
|
|
447
436
|
}
|
|
448
437
|
// create shallow clone to be able to annotate with metadata
|
|
449
438
|
operationElement = cloneShallow(operationElement);
|
|
450
439
|
// annotate operation element with info about origin
|
|
451
|
-
operationElement.
|
|
440
|
+
operationElement.meta.set('ref-origin', reference.uri);
|
|
452
441
|
const linkElementCopy = cloneShallow(linkElement);
|
|
453
442
|
linkElementCopy.operationRef?.meta.set('operation', operationElement);
|
|
454
443
|
|
|
455
444
|
/**
|
|
456
445
|
* Transclude Link Object containing Operation Object in its meta.
|
|
457
446
|
*/
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* We're at the root of the tree, so we're just replacing the entire tree.
|
|
462
|
-
*/
|
|
463
|
-
return !parent ? linkElementCopy : undefined;
|
|
447
|
+
path.replaceWith(linkElementCopy);
|
|
448
|
+
return;
|
|
464
449
|
}
|
|
465
450
|
if (isStringElement(linkElement.operationId)) {
|
|
466
451
|
const operationId = toValue(linkElement.operationId);
|
|
467
452
|
const reference = await this.toReference(url.unsanitize(this.reference.uri));
|
|
468
|
-
operationElement = find(e => isOperationElement(e) && isElement(e.operationId) && e.operationId.equals(operationId)
|
|
453
|
+
operationElement = find(reference.value.result, e => isOperationElement(e) && isElement(e.operationId) && e.operationId.equals(operationId));
|
|
469
454
|
// OperationElement not found by its operationId
|
|
470
455
|
if (isUndefined(operationElement)) {
|
|
471
456
|
throw new ApiDOMError(`OperationElement(operationId=${operationId}) not found.`);
|
|
@@ -476,19 +461,15 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
476
461
|
/**
|
|
477
462
|
* Transclude Link Object containing Operation Object in its meta.
|
|
478
463
|
*/
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
/**
|
|
482
|
-
* We're at the root of the tree, so we're just replacing the entire tree.
|
|
483
|
-
*/
|
|
484
|
-
return !parent ? linkElementCopy : undefined;
|
|
464
|
+
path.replaceWith(linkElementCopy);
|
|
485
465
|
}
|
|
486
|
-
return undefined;
|
|
487
466
|
}
|
|
488
|
-
async ExampleElement(
|
|
467
|
+
async ExampleElement(path) {
|
|
468
|
+
const exampleElement = path.node;
|
|
469
|
+
|
|
489
470
|
// ignore ExampleElement without externalValue field
|
|
490
471
|
if (!isStringElement(exampleElement.externalValue)) {
|
|
491
|
-
return
|
|
472
|
+
return;
|
|
492
473
|
}
|
|
493
474
|
|
|
494
475
|
// value and externalValue fields are mutually exclusive
|
|
@@ -502,43 +483,41 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
502
483
|
// ignore resolving internal Example Objects
|
|
503
484
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
504
485
|
// skip traversing this Example element but traverse all it's child elements
|
|
505
|
-
return
|
|
486
|
+
return;
|
|
506
487
|
}
|
|
507
488
|
// ignore resolving external Example Objects
|
|
508
489
|
if (!this.options.resolve.external && isExternalReference) {
|
|
509
490
|
// skip traversing this Example element but traverse all it's child elements
|
|
510
|
-
return
|
|
491
|
+
return;
|
|
511
492
|
}
|
|
512
493
|
const reference = await this.toReference(toValue(exampleElement.externalValue));
|
|
513
494
|
|
|
514
495
|
// shallow clone of the referenced element
|
|
515
496
|
const valueElement = cloneShallow(reference.value.result);
|
|
516
497
|
// annotate operation element with info about origin
|
|
517
|
-
valueElement.
|
|
498
|
+
valueElement.meta.set('ref-origin', reference.uri);
|
|
518
499
|
const exampleElementCopy = cloneShallow(exampleElement);
|
|
519
500
|
exampleElementCopy.value = valueElement;
|
|
520
501
|
|
|
521
502
|
/**
|
|
522
503
|
* Transclude Example Object containing external value.
|
|
523
504
|
*/
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
/**
|
|
527
|
-
* We're at the root of the tree, so we're just replacing the entire tree.
|
|
528
|
-
*/
|
|
529
|
-
return !parent ? exampleElementCopy : undefined;
|
|
505
|
+
path.replaceWith(exampleElementCopy);
|
|
530
506
|
}
|
|
531
|
-
async SchemaElement(
|
|
507
|
+
async SchemaElement(path) {
|
|
508
|
+
const referencingElement = path.node;
|
|
509
|
+
|
|
532
510
|
// skip current referencing schema as $ref keyword was not defined
|
|
533
511
|
if (!isStringElement(referencingElement.$ref)) {
|
|
534
|
-
return
|
|
512
|
+
return;
|
|
535
513
|
}
|
|
536
514
|
|
|
537
515
|
// skip current referencing element as it's already been access
|
|
538
516
|
if (this.indirections.includes(referencingElement)) {
|
|
539
|
-
|
|
517
|
+
path.skip();
|
|
518
|
+
return;
|
|
540
519
|
}
|
|
541
|
-
const [ancestorsLineage, directAncestors] = this.toAncestorLineage(
|
|
520
|
+
const [ancestorsLineage, directAncestors] = this.toAncestorLineage(path);
|
|
542
521
|
|
|
543
522
|
// compute baseURI using rules around $id and $ref keywords
|
|
544
523
|
let reference = await this.toReference(url.unsanitize(this.reference.uri));
|
|
@@ -571,12 +550,12 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
571
550
|
// ignore resolving internal Schema Objects
|
|
572
551
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
573
552
|
// skip traversing this schema element but traverse all it's child elements
|
|
574
|
-
return
|
|
553
|
+
return;
|
|
575
554
|
}
|
|
576
555
|
// ignore resolving external Schema Objects
|
|
577
556
|
if (!this.options.resolve.external && isExternalReference) {
|
|
578
557
|
// skip traversing this schema element but traverse all it's child elements
|
|
579
|
-
return
|
|
558
|
+
return;
|
|
580
559
|
}
|
|
581
560
|
} else {
|
|
582
561
|
// we're assuming here that we're dealing with JSON Pointer here
|
|
@@ -587,12 +566,12 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
587
566
|
// ignore resolving internal Schema Objects
|
|
588
567
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
589
568
|
// skip traversing this schema element but traverse all it's child elements
|
|
590
|
-
return
|
|
569
|
+
return;
|
|
591
570
|
}
|
|
592
571
|
// ignore resolving external Schema Objects
|
|
593
572
|
if (!this.options.resolve.external && isExternalReference) {
|
|
594
573
|
// skip traversing this schema element but traverse all it's child elements
|
|
595
|
-
return
|
|
574
|
+
return;
|
|
596
575
|
}
|
|
597
576
|
reference = await this.toReference(url.unsanitize($refBaseURI));
|
|
598
577
|
const selector = URIFragmentIdentifier.fromURIReference($refBaseURI);
|
|
@@ -615,12 +594,12 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
615
594
|
// ignore resolving internal Schema Objects
|
|
616
595
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
617
596
|
// skip traversing this schema element but traverse all it's child elements
|
|
618
|
-
return
|
|
597
|
+
return;
|
|
619
598
|
}
|
|
620
599
|
// ignore resolving external Schema Objects
|
|
621
600
|
if (!this.options.resolve.external && isExternalReference) {
|
|
622
601
|
// skip traversing this schema element but traverse all it's child elements
|
|
623
|
-
return
|
|
602
|
+
return;
|
|
624
603
|
}
|
|
625
604
|
reference = await this.toReference(url.unsanitize($refBaseURI));
|
|
626
605
|
const selector = uriToAnchor($refBaseURI);
|
|
@@ -637,12 +616,12 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
637
616
|
// ignore resolving internal Schema Objects
|
|
638
617
|
if (!this.options.resolve.internal && isInternalReference) {
|
|
639
618
|
// skip traversing this schema element but traverse all it's child elements
|
|
640
|
-
return
|
|
619
|
+
return;
|
|
641
620
|
}
|
|
642
621
|
// ignore resolving external Schema Objects
|
|
643
622
|
if (!this.options.resolve.external && isExternalReference) {
|
|
644
623
|
// skip traversing this schema element but traverse all it's child elements
|
|
645
|
-
return
|
|
624
|
+
return;
|
|
646
625
|
}
|
|
647
626
|
reference = await this.toReference(url.unsanitize($refBaseURI));
|
|
648
627
|
const selector = URIFragmentIdentifier.fromURIReference($refBaseURI);
|
|
@@ -679,8 +658,9 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
679
658
|
});
|
|
680
659
|
const replacer = this.options.dereference.strategyOpts['openapi-3-1']?.circularReplacer ?? this.options.dereference.circularReplacer;
|
|
681
660
|
const replacement = replacer(refElement);
|
|
682
|
-
|
|
683
|
-
|
|
661
|
+
this.indirections.pop();
|
|
662
|
+
path.replaceWith(replacement);
|
|
663
|
+
return;
|
|
684
664
|
}
|
|
685
665
|
}
|
|
686
666
|
|
|
@@ -706,9 +686,8 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
706
686
|
refractCache: this.refractCache,
|
|
707
687
|
ancestors: ancestorsLineage
|
|
708
688
|
});
|
|
709
|
-
referencedElement = await
|
|
710
|
-
|
|
711
|
-
nodeTypeGetter: getNodeType
|
|
689
|
+
referencedElement = await traverseAsync(referencedElement, visitor, {
|
|
690
|
+
mutable: true
|
|
712
691
|
});
|
|
713
692
|
|
|
714
693
|
// remove referencing reference from ancestors lineage
|
|
@@ -720,26 +699,26 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
720
699
|
if (isBooleanJsonSchemaElement(referencedElement)) {
|
|
721
700
|
const booleanJsonSchemaElement = cloneDeep(referencedElement);
|
|
722
701
|
// assign unique id to merged element
|
|
723
|
-
booleanJsonSchemaElement.
|
|
702
|
+
booleanJsonSchemaElement.meta.set('id', identityManager.generateId());
|
|
724
703
|
// annotate referenced element with info about original referencing element
|
|
725
|
-
booleanJsonSchemaElement.
|
|
704
|
+
booleanJsonSchemaElement.meta.set('ref-fields', {
|
|
726
705
|
$ref: toValue(referencingElement.$ref)
|
|
727
706
|
});
|
|
728
707
|
// annotate referenced element with info about origin
|
|
729
|
-
booleanJsonSchemaElement.
|
|
708
|
+
booleanJsonSchemaElement.meta.set('ref-origin', reference.uri);
|
|
730
709
|
// annotate fragment with info about referencing element
|
|
731
|
-
booleanJsonSchemaElement.
|
|
732
|
-
|
|
733
|
-
return
|
|
710
|
+
booleanJsonSchemaElement.meta.set('ref-referencing-element-id', cloneDeep(identityManager.identify(referencingElement)));
|
|
711
|
+
path.replaceWith(booleanJsonSchemaElement);
|
|
712
|
+
return;
|
|
734
713
|
}
|
|
735
714
|
|
|
736
715
|
/**
|
|
737
716
|
* Creating a new version of Schema Object by merging fields from referenced Schema Object with referencing one.
|
|
738
717
|
*/
|
|
739
718
|
if (isSchemaElement(referencedElement)) {
|
|
740
|
-
const mergedElement =
|
|
719
|
+
const mergedElement = cloneShallow(referencedElement);
|
|
741
720
|
// assign unique id to merged element
|
|
742
|
-
mergedElement.
|
|
721
|
+
mergedElement.meta.set('id', identityManager.generateId());
|
|
743
722
|
// existing keywords from referencing schema overrides ones from referenced schema
|
|
744
723
|
referencingElement.forEach((value, keyElement, item) => {
|
|
745
724
|
mergedElement.remove(toValue(keyElement));
|
|
@@ -747,24 +726,19 @@ class OpenAPI3_1DereferenceVisitor {
|
|
|
747
726
|
});
|
|
748
727
|
mergedElement.remove('$ref');
|
|
749
728
|
// annotate referenced element with info about original referencing element
|
|
750
|
-
mergedElement.
|
|
729
|
+
mergedElement.meta.set('ref-fields', {
|
|
751
730
|
$ref: toValue(referencingElement.$ref)
|
|
752
731
|
});
|
|
753
732
|
// annotate fragment with info about origin
|
|
754
|
-
mergedElement.
|
|
733
|
+
mergedElement.meta.set('ref-origin', reference.uri);
|
|
755
734
|
// annotate fragment with info about referencing element
|
|
756
|
-
mergedElement.
|
|
735
|
+
mergedElement.meta.set('ref-referencing-element-id', cloneDeep(identityManager.identify(referencingElement)));
|
|
757
736
|
referencedElement = mergedElement;
|
|
758
737
|
}
|
|
759
738
|
/**
|
|
760
739
|
* Transclude referencing element with merged referenced element.
|
|
761
740
|
*/
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* We're at the root of the tree, so we're just replacing the entire tree.
|
|
766
|
-
*/
|
|
767
|
-
return !parent ? referencedElement : undefined;
|
|
741
|
+
path.replaceWith(referencedElement);
|
|
768
742
|
}
|
|
769
743
|
}
|
|
770
744
|
export default OpenAPI3_1DereferenceVisitor;
|
package/src/dereference/util.cjs
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
exports.__esModule = true;
|
|
4
4
|
exports.AncestorLineage = void 0;
|
|
5
|
-
var
|
|
5
|
+
var _apidomDatamodel = require("@speclynx/apidom-datamodel");
|
|
6
6
|
/**
|
|
7
7
|
* @public
|
|
8
8
|
*/
|
|
@@ -20,7 +20,7 @@ class AncestorLineage extends Array {
|
|
|
20
20
|
findItem(predicate) {
|
|
21
21
|
for (const set of this) {
|
|
22
22
|
for (const item of set) {
|
|
23
|
-
if ((0,
|
|
23
|
+
if ((0, _apidomDatamodel.isElement)(item) && predicate(item)) {
|
|
24
24
|
return item;
|
|
25
25
|
}
|
|
26
26
|
}
|
package/src/dereference/util.mjs
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
|
|
4
4
|
exports.__esModule = true;
|
|
5
5
|
exports.default = void 0;
|
|
6
|
-
var
|
|
6
|
+
var _apidomDatamodel = require("@speclynx/apidom-datamodel");
|
|
7
7
|
var _ParserError = _interopRequireDefault(require("../../../errors/ParserError.cjs"));
|
|
8
8
|
var _Parser = _interopRequireDefault(require("../Parser.cjs"));
|
|
9
9
|
/**
|
|
@@ -20,7 +20,7 @@ class ApiDOMJSONParser extends _Parser.default {
|
|
|
20
20
|
const {
|
|
21
21
|
fileExtensions = [],
|
|
22
22
|
mediaTypes = ['application/vnd.apidom', 'application/vnd.apidom+json'],
|
|
23
|
-
namespace =
|
|
23
|
+
namespace = new _apidomDatamodel.Namespace(),
|
|
24
24
|
...rest
|
|
25
25
|
} = options ?? {};
|
|
26
26
|
super({
|
|
@@ -51,13 +51,13 @@ class ApiDOMJSONParser extends _Parser.default {
|
|
|
51
51
|
|
|
52
52
|
// allow empty files
|
|
53
53
|
if (this.allowEmpty && source.trim() === '') {
|
|
54
|
-
return new
|
|
54
|
+
return new _apidomDatamodel.ParseResultElement();
|
|
55
55
|
}
|
|
56
56
|
try {
|
|
57
57
|
const element = namespace.fromRefract(JSON.parse(source));
|
|
58
|
-
if (!(0,
|
|
58
|
+
if (!(0, _apidomDatamodel.isParseResultElement)(element)) {
|
|
59
59
|
element.classes.push('result');
|
|
60
|
-
return new
|
|
60
|
+
return new _apidomDatamodel.ParseResultElement([element]);
|
|
61
61
|
}
|
|
62
62
|
return element;
|
|
63
63
|
} catch (error) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ParseResultElement, isParseResultElement
|
|
1
|
+
import { Namespace, ParseResultElement, isParseResultElement } from '@speclynx/apidom-datamodel';
|
|
2
2
|
import ParserError from "../../../errors/ParserError.mjs";
|
|
3
3
|
import Parser from "../Parser.mjs";
|
|
4
4
|
/**
|
|
@@ -14,7 +14,7 @@ class ApiDOMJSONParser extends Parser {
|
|
|
14
14
|
const {
|
|
15
15
|
fileExtensions = [],
|
|
16
16
|
mediaTypes = ['application/vnd.apidom', 'application/vnd.apidom+json'],
|
|
17
|
-
namespace =
|
|
17
|
+
namespace = new Namespace(),
|
|
18
18
|
...rest
|
|
19
19
|
} = options ?? {};
|
|
20
20
|
super({
|
|
@@ -15,7 +15,6 @@ var _Parser = _interopRequireDefault(require("../Parser.cjs"));
|
|
|
15
15
|
* @public
|
|
16
16
|
*/
|
|
17
17
|
class ArazzoJSON1Parser extends _Parser.default {
|
|
18
|
-
syntacticAnalysis;
|
|
19
18
|
refractorOpts;
|
|
20
19
|
constructor(options) {
|
|
21
20
|
const {
|
|
@@ -43,7 +42,7 @@ class ArazzoJSON1Parser extends _Parser.default {
|
|
|
43
42
|
async parse(file) {
|
|
44
43
|
const source = file.toString();
|
|
45
44
|
try {
|
|
46
|
-
const parserOpts = (0, _ramda.pick)(['sourceMap', '
|
|
45
|
+
const parserOpts = (0, _ramda.pick)(['sourceMap', 'refractorOpts'], this);
|
|
47
46
|
return await (0, _apidomParserAdapterArazzoJson.parse)(source, parserOpts);
|
|
48
47
|
} catch (error) {
|
|
49
48
|
throw new _ParserError.default(`Error parsing "${file.uri}"`, {
|