source: node_modules/@swagger-api/apidom-reference/cjs/dereference/strategies/openapi-3-1/visitor.cjs

main
Last change on this file was d24f17c, checked in by Aleksandar Panovski <apano77@…>, 15 months ago

Initial commit

  • Property mode set to 100644
File size: 27.4 KB
Line 
1"use strict";
2
3var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5exports.__esModule = true;
6exports.default = void 0;
7var _stampit = _interopRequireDefault(require("stampit"));
8var _ramda = require("ramda");
9var _ramdaAdjunct = require("ramda-adjunct");
10var _apidomCore = require("@swagger-api/apidom-core");
11var _apidomError = require("@swagger-api/apidom-error");
12var _apidomJsonPointer = require("@swagger-api/apidom-json-pointer");
13var _apidomNsOpenapi = require("@swagger-api/apidom-ns-openapi-3-1");
14var _$anchor = require("./selectors/$anchor.cjs");
15var _uri = require("./selectors/uri.cjs");
16var _MaximumDereferenceDepthError = _interopRequireDefault(require("../../../errors/MaximumDereferenceDepthError.cjs"));
17var _MaximumResolveDepthError = _interopRequireDefault(require("../../../errors/MaximumResolveDepthError.cjs"));
18var url = _interopRequireWildcard(require("../../../util/url.cjs"));
19var _index = _interopRequireDefault(require("../../../parse/index.cjs"));
20var _Reference = _interopRequireDefault(require("../../../Reference.cjs"));
21var _File = _interopRequireDefault(require("../../../util/File.cjs"));
22var _util = require("../../../resolve/strategies/openapi-3-1/util.cjs");
23var _util2 = require("../../util.cjs");
24var _EvaluationJsonSchemaUriError = _interopRequireDefault(require("../../../errors/EvaluationJsonSchemaUriError.cjs"));
25// @ts-ignore
26const visitAsync = _apidomCore.visit[Symbol.for('nodejs.util.promisify.custom')];
27
28// initialize element identity manager
29const identityManager = (0, _apidomCore.IdentityManager)();
30
31/**
32 * Predicate for detecting if element was created by merging referencing
33 * element with particular element identity with a referenced element.
34 */
35const wasReferencedBy = referencingElement => element => element.meta.hasKey('ref-referencing-element-id') && element.meta.get('ref-referencing-element-id').equals((0, _apidomCore.toValue)(identityManager.identify(referencingElement)));
36
37// eslint-disable-next-line @typescript-eslint/naming-convention
38const OpenApi3_1DereferenceVisitor = (0, _stampit.default)({
39 props: {
40 indirections: null,
41 namespace: null,
42 reference: null,
43 options: null,
44 ancestors: null
45 },
46 init({
47 indirections = [],
48 reference,
49 namespace,
50 options,
51 ancestors = new _util2.AncestorLineage()
52 }) {
53 this.indirections = indirections;
54 this.namespace = namespace;
55 this.reference = reference;
56 this.options = options;
57 this.ancestors = new _util2.AncestorLineage(...ancestors);
58 },
59 methods: {
60 toBaseURI(uri) {
61 return url.resolve(this.reference.uri, url.sanitize(url.stripHash(uri)));
62 },
63 async toReference(uri) {
64 // detect maximum depth of resolution
65 if (this.reference.depth >= this.options.resolve.maxDepth) {
66 throw new _MaximumResolveDepthError.default(`Maximum resolution depth of ${this.options.resolve.maxDepth} has been exceeded by file "${this.reference.uri}"`);
67 }
68 const baseURI = this.toBaseURI(uri);
69 const {
70 refSet
71 } = this.reference;
72
73 // we've already processed this Reference in past
74 if (refSet.has(baseURI)) {
75 return refSet.find((0, _ramda.propEq)(baseURI, 'uri'));
76 }
77 const parseResult = await (0, _index.default)(url.unsanitize(baseURI), {
78 ...this.options,
79 parse: {
80 ...this.options.parse,
81 mediaType: 'text/plain'
82 }
83 });
84
85 // register new Reference with ReferenceSet
86 const reference = (0, _Reference.default)({
87 uri: baseURI,
88 value: parseResult,
89 depth: this.reference.depth + 1
90 });
91 refSet.add(reference);
92 return reference;
93 },
94 toAncestorLineage(ancestors) {
95 /**
96 * Compute full ancestors lineage.
97 * Ancestors are flatten to unwrap all Element instances.
98 */
99 const directAncestors = new Set(ancestors.filter(_apidomCore.isElement));
100 const ancestorsLineage = new _util2.AncestorLineage(...this.ancestors, directAncestors);
101 return [ancestorsLineage, directAncestors];
102 },
103 async ReferenceElement(referencingElement, key, parent, path, ancestors) {
104 const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
105
106 // detect possible cycle in traversal and avoid it
107 if (ancestorsLineage.includesCycle(referencingElement)) {
108 return false;
109 }
110 const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(referencingElement.$ref));
111
112 // ignore resolving external Reference Objects
113 if (!this.options.resolve.external && url.stripHash(this.reference.uri) !== retrievalURI) {
114 // skip traversing this reference element and all it's child elements
115 return false;
116 }
117 const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
118 const $refBaseURI = url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
119 this.indirections.push(referencingElement);
120 const jsonPointer = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
121
122 // possibly non-semantic fragment
123 let referencedElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
124
125 // applying semantics to a fragment
126 if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
127 const referencedElementType = (0, _apidomCore.toValue)(referencingElement.meta.get('referenced-element'));
128 if ((0, _apidomNsOpenapi.isReferenceLikeElement)(referencedElement)) {
129 // handling indirect references
130 referencedElement = _apidomNsOpenapi.ReferenceElement.refract(referencedElement);
131 referencedElement.setMetaProperty('referenced-element', referencedElementType);
132 } else {
133 // handling direct references
134 const ElementClass = this.namespace.getElementClass(referencedElementType);
135 referencedElement = ElementClass.refract(referencedElement);
136 }
137 }
138
139 // detect direct or indirect reference
140 if (this.indirections.includes(referencedElement)) {
141 throw new _apidomError.ApiDOMError('Recursive Reference Object detected');
142 }
143
144 // detect maximum depth of dereferencing
145 if (this.indirections.length > this.options.dereference.maxDepth) {
146 throw new _MaximumDereferenceDepthError.default(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
147 }
148
149 // append referencing reference to ancestors lineage
150 directAncestors.add(referencingElement);
151
152 // dive deep into the fragment
153 const visitor = OpenApi3_1DereferenceVisitor({
154 reference,
155 namespace: this.namespace,
156 indirections: [...this.indirections],
157 options: this.options,
158 ancestors: ancestorsLineage
159 });
160 referencedElement = await visitAsync(referencedElement, visitor, {
161 keyMap: _apidomNsOpenapi.keyMap,
162 nodeTypeGetter: _apidomNsOpenapi.getNodeType
163 });
164
165 // remove referencing reference from ancestors lineage
166 directAncestors.delete(referencingElement);
167 this.indirections.pop();
168 const mergeAndAnnotateReferencedElement = refedElement => {
169 const copy = (0, _apidomCore.cloneShallow)(refedElement);
170
171 // annotate fragment with info about original Reference element
172 copy.setMetaProperty('ref-fields', {
173 $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
174 // @ts-ignore
175 description: (0, _apidomCore.toValue)(referencingElement.description),
176 // @ts-ignore
177 summary: (0, _apidomCore.toValue)(referencingElement.summary)
178 });
179 // annotate fragment with info about origin
180 copy.setMetaProperty('ref-origin', reference.uri);
181 // annotate fragment with info about referencing element
182 copy.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
183
184 // override description and summary (outer has higher priority then inner)
185 if ((0, _apidomCore.isObjectElement)(refedElement)) {
186 if (referencingElement.hasKey('description') && 'description' in refedElement) {
187 // @ts-ignore
188 copy.remove('description');
189 // @ts-ignore
190 copy.set('description', referencingElement.get('description'));
191 }
192 if (referencingElement.hasKey('summary') && 'summary' in refedElement) {
193 // @ts-ignore
194 copy.remove('summary');
195 // @ts-ignore
196 copy.set('summary', referencingElement.get('summary'));
197 }
198 }
199 return copy;
200 };
201
202 // attempting to create cycle
203 if (ancestorsLineage.includes(referencingElement) || ancestorsLineage.includes(referencedElement)) {
204 var _ancestorsLineage$fin;
205 const replaceWith = (_ancestorsLineage$fin = ancestorsLineage.findItem(wasReferencedBy(referencingElement))) != null ? _ancestorsLineage$fin : mergeAndAnnotateReferencedElement(referencedElement);
206 if ((0, _apidomCore.isMemberElement)(parent)) {
207 parent.value = replaceWith; // eslint-disable-line no-param-reassign
208 } else if (Array.isArray(parent)) {
209 parent[key] = replaceWith; // eslint-disable-line no-param-reassign
210 }
211 return false;
212 }
213
214 // transclude the element for a fragment
215 return mergeAndAnnotateReferencedElement(referencedElement);
216 },
217 async PathItemElement(referencingElement, key, parent, path, ancestors) {
218 const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
219
220 // ignore PathItemElement without $ref field
221 if (!(0, _apidomCore.isStringElement)(referencingElement.$ref)) {
222 return undefined;
223 }
224
225 // detect possible cycle in traversal and avoid it
226 if (ancestorsLineage.includesCycle(referencingElement)) {
227 return false;
228 }
229 const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(referencingElement.$ref));
230
231 // ignore resolving external Path Item Objects
232 if (!this.options.resolve.external && url.stripHash(this.reference.uri) !== retrievalURI) {
233 // skip traversing this Path Item element but traverse all it's child elements
234 return undefined;
235 }
236 const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
237 const $refBaseURI = url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
238 this.indirections.push(referencingElement);
239 const jsonPointer = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
240
241 // possibly non-semantic referenced element
242 let referencedElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
243
244 // applying semantics to a referenced element
245 if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
246 referencedElement = _apidomNsOpenapi.PathItemElement.refract(referencedElement);
247 }
248
249 // detect direct or indirect reference
250 if (this.indirections.includes(referencedElement)) {
251 throw new _apidomError.ApiDOMError('Recursive Path Item Object reference detected');
252 }
253
254 // detect maximum depth of dereferencing
255 if (this.indirections.length > this.options.dereference.maxDepth) {
256 throw new _MaximumDereferenceDepthError.default(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
257 }
258
259 // append referencing path item to ancestors lineage
260 directAncestors.add(referencingElement);
261
262 // dive deep into the referenced element
263 const visitor = OpenApi3_1DereferenceVisitor({
264 reference,
265 namespace: this.namespace,
266 indirections: [...this.indirections],
267 options: this.options,
268 ancestors: ancestorsLineage
269 });
270 referencedElement = await visitAsync(referencedElement, visitor, {
271 keyMap: _apidomNsOpenapi.keyMap,
272 nodeTypeGetter: _apidomNsOpenapi.getNodeType
273 });
274
275 // remove referencing path item from ancestors lineage
276 directAncestors.delete(referencingElement);
277 this.indirections.pop();
278 const mergeAndAnnotateReferencedElement = refedElement => {
279 // merge fields from referenced Path Item with referencing one
280 const mergedElement = new _apidomNsOpenapi.PathItemElement([...refedElement.content], (0, _apidomCore.cloneDeep)(refedElement.meta), (0, _apidomCore.cloneDeep)(refedElement.attributes));
281 // existing keywords from referencing PathItemElement overrides ones from referenced element
282 referencingElement.forEach((value, keyElement, item) => {
283 mergedElement.remove((0, _apidomCore.toValue)(keyElement));
284 mergedElement.content.push(item);
285 });
286 mergedElement.remove('$ref');
287
288 // annotate referenced element with info about original referencing element
289 mergedElement.setMetaProperty('ref-fields', {
290 $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
291 });
292 // annotate referenced element with info about origin
293 mergedElement.setMetaProperty('ref-origin', reference.uri);
294 // annotate fragment with info about referencing element
295 mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
296 return mergedElement;
297 };
298
299 // attempting to create cycle
300 if (ancestorsLineage.includes(referencingElement) || ancestorsLineage.includes(referencedElement)) {
301 var _ancestorsLineage$fin2;
302 const replaceWith = (_ancestorsLineage$fin2 = ancestorsLineage.findItem(wasReferencedBy(referencingElement))) != null ? _ancestorsLineage$fin2 : mergeAndAnnotateReferencedElement(referencedElement);
303 if ((0, _apidomCore.isMemberElement)(parent)) {
304 parent.value = replaceWith; // eslint-disable-line no-param-reassign
305 } else if (Array.isArray(parent)) {
306 parent[key] = replaceWith; // eslint-disable-line no-param-reassign
307 }
308 return false;
309 }
310
311 // transclude referencing element with merged referenced element
312 return mergeAndAnnotateReferencedElement(referencedElement);
313 },
314 async LinkElement(linkElement) {
315 // ignore LinkElement without operationRef or operationId field
316 if (!(0, _apidomCore.isStringElement)(linkElement.operationRef) && !(0, _apidomCore.isStringElement)(linkElement.operationId)) {
317 return undefined;
318 }
319
320 // operationRef and operationId fields are mutually exclusive
321 if ((0, _apidomCore.isStringElement)(linkElement.operationRef) && (0, _apidomCore.isStringElement)(linkElement.operationId)) {
322 throw new _apidomError.ApiDOMError('LinkElement operationRef and operationId fields are mutually exclusive.');
323 }
324 let operationElement;
325 if ((0, _apidomCore.isStringElement)(linkElement.operationRef)) {
326 var _linkElementCopy$oper;
327 // possibly non-semantic referenced element
328 const jsonPointer = (0, _apidomJsonPointer.uriToPointer)((0, _apidomCore.toValue)(linkElement.operationRef));
329 const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(linkElement.operationRef));
330
331 // ignore resolving external Operation Object reference
332 if (!this.options.resolve.external && url.stripHash(this.reference.uri) !== retrievalURI) {
333 // skip traversing this Link element but traverse all it's child elements
334 return undefined;
335 }
336 const reference = await this.toReference((0, _apidomCore.toValue)(linkElement.operationRef));
337 operationElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
338 // applying semantics to a referenced element
339 if ((0, _apidomCore.isPrimitiveElement)(operationElement)) {
340 operationElement = _apidomNsOpenapi.OperationElement.refract(operationElement);
341 }
342 // create shallow clone to be able to annotate with metadata
343 operationElement = (0, _apidomCore.cloneShallow)(operationElement);
344 // annotate operation element with info about origin
345 operationElement.setMetaProperty('ref-origin', reference.uri);
346 const linkElementCopy = (0, _apidomCore.cloneShallow)(linkElement);
347 (_linkElementCopy$oper = linkElementCopy.operationRef) == null || _linkElementCopy$oper.meta.set('operation', operationElement);
348 return linkElementCopy;
349 }
350 if ((0, _apidomCore.isStringElement)(linkElement.operationId)) {
351 var _linkElementCopy$oper2;
352 const operationId = (0, _apidomCore.toValue)(linkElement.operationId);
353 const reference = await this.toReference(url.unsanitize(this.reference.uri));
354 operationElement = (0, _apidomCore.find)(e => (0, _apidomNsOpenapi.isOperationElement)(e) && (0, _apidomCore.isElement)(e.operationId) && e.operationId.equals(operationId), reference.value.result);
355 // OperationElement not found by its operationId
356 if ((0, _ramdaAdjunct.isUndefined)(operationElement)) {
357 throw new _apidomError.ApiDOMError(`OperationElement(operationId=${operationId}) not found.`);
358 }
359 const linkElementCopy = (0, _apidomCore.cloneShallow)(linkElement);
360 (_linkElementCopy$oper2 = linkElementCopy.operationId) == null || _linkElementCopy$oper2.meta.set('operation', operationElement);
361 return linkElementCopy;
362 }
363 return undefined;
364 },
365 async ExampleElement(exampleElement, key, parent, path, ancestors) {
366 const [ancestorsLineage] = this.toAncestorLineage([...ancestors, parent]);
367
368 // ignore ExampleElement without externalValue field
369 if (!(0, _apidomCore.isStringElement)(exampleElement.externalValue)) {
370 return undefined;
371 }
372
373 // detect possible cycle in traversal and avoid it
374 if (ancestorsLineage.includesCycle(exampleElement)) {
375 return false;
376 }
377
378 // value and externalValue fields are mutually exclusive
379 if (exampleElement.hasKey('value') && (0, _apidomCore.isStringElement)(exampleElement.externalValue)) {
380 throw new _apidomError.ApiDOMError('ExampleElement value and externalValue fields are mutually exclusive.');
381 }
382 const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(exampleElement.externalValue));
383
384 // ignore resolving external Example Objects
385 if (!this.options.resolve.external && url.stripHash(this.reference.uri) !== retrievalURI) {
386 // skip traversing this Example element but traverse all it's child elements
387 return undefined;
388 }
389 const reference = await this.toReference((0, _apidomCore.toValue)(exampleElement.externalValue));
390
391 // shallow clone of the referenced element
392 const valueElement = (0, _apidomCore.cloneShallow)(reference.value.result);
393 // annotate operation element with info about origin
394 valueElement.setMetaProperty('ref-origin', reference.uri);
395 const exampleElementCopy = (0, _apidomCore.cloneShallow)(exampleElement);
396 exampleElementCopy.value = valueElement;
397 return exampleElementCopy;
398 },
399 async SchemaElement(referencingElement, key, parent, path, ancestors) {
400 const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
401
402 // skip current referencing schema as $ref keyword was not defined
403 if (!(0, _apidomCore.isStringElement)(referencingElement.$ref)) {
404 // skip traversing this schema but traverse all it's child schemas
405 return undefined;
406 }
407
408 // detect possible cycle in traversal and avoid it
409 if (ancestorsLineage.includesCycle(referencingElement)) {
410 return false;
411 }
412
413 // compute baseURI using rules around $id and $ref keywords
414 let reference = await this.toReference(url.unsanitize(this.reference.uri));
415 let {
416 uri: retrievalURI
417 } = reference;
418 const $refBaseURI = (0, _util.resolveSchema$refField)(retrievalURI, referencingElement);
419 const $refBaseURIStrippedHash = url.stripHash($refBaseURI);
420 const file = (0, _File.default)({
421 uri: $refBaseURIStrippedHash
422 });
423 const isUnknownURI = (0, _ramda.none)(r => r.canRead(file), this.options.resolve.resolvers);
424 const isURL = !isUnknownURI;
425 const isExternalURL = uri => url.stripHash(this.reference.uri) !== uri;
426 this.indirections.push(referencingElement);
427
428 // determining reference, proper evaluation and selection mechanism
429 let referencedElement;
430 try {
431 if (isUnknownURI || isURL) {
432 // we're dealing with canonical URI or URL with possible fragment
433 const selector = $refBaseURI;
434 referencedElement = (0, _uri.evaluate)(selector,
435 // @ts-ignore
436 (0, _util.maybeRefractToSchemaElement)(reference.value.result));
437 } else {
438 // we're assuming here that we're dealing with JSON Pointer here
439 retrievalURI = this.toBaseURI((0, _apidomCore.toValue)($refBaseURI));
440
441 // ignore resolving external Schema Objects
442 if (!this.options.resolve.external && isExternalURL(retrievalURI)) {
443 // skip traversing this schema element but traverse all it's child elements
444 return undefined;
445 }
446 reference = await this.toReference(url.unsanitize($refBaseURI));
447 const selector = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
448 referencedElement = (0, _util.maybeRefractToSchemaElement)(
449 // @ts-ignore
450 (0, _apidomJsonPointer.evaluate)(selector, reference.value.result));
451 }
452 } catch (error) {
453 /**
454 * No SchemaElement($id=URL) was not found, so we're going to try to resolve
455 * the URL and assume the returned response is a JSON Schema.
456 */
457 if (isURL && error instanceof _EvaluationJsonSchemaUriError.default) {
458 if ((0, _$anchor.isAnchor)((0, _$anchor.uriToAnchor)($refBaseURI))) {
459 // we're dealing with JSON Schema $anchor here
460 retrievalURI = this.toBaseURI((0, _apidomCore.toValue)($refBaseURI));
461
462 // ignore resolving external Schema Objects
463 if (!this.options.resolve.external && isExternalURL(retrievalURI)) {
464 // skip traversing this schema element but traverse all it's child elements
465 return undefined;
466 }
467 reference = await this.toReference(url.unsanitize($refBaseURI));
468 const selector = (0, _$anchor.uriToAnchor)($refBaseURI);
469 referencedElement = (0, _$anchor.evaluate)(selector,
470 // @ts-ignore
471 (0, _util.maybeRefractToSchemaElement)(reference.value.result));
472 } else {
473 // we're assuming here that we're dealing with JSON Pointer here
474 retrievalURI = this.toBaseURI((0, _apidomCore.toValue)($refBaseURI));
475
476 // ignore resolving external Schema Objects
477 if (!this.options.resolve.external && isExternalURL(retrievalURI)) {
478 // skip traversing this schema element but traverse all it's child elements
479 return undefined;
480 }
481 reference = await this.toReference(url.unsanitize($refBaseURI));
482 const selector = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
483 referencedElement = (0, _util.maybeRefractToSchemaElement)(
484 // @ts-ignore
485 (0, _apidomJsonPointer.evaluate)(selector, reference.value.result));
486 }
487 } else {
488 throw error;
489 }
490 }
491
492 // detect direct or indirect reference
493 if (this.indirections.includes(referencedElement)) {
494 throw new _apidomError.ApiDOMError('Recursive Schema Object reference detected');
495 }
496
497 // detect maximum depth of dereferencing
498 if (this.indirections.length > this.options.dereference.maxDepth) {
499 throw new _MaximumDereferenceDepthError.default(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
500 }
501
502 // append referencing schema to ancestors lineage
503 directAncestors.add(referencingElement);
504
505 // dive deep into the fragment
506 const visitor = OpenApi3_1DereferenceVisitor({
507 reference,
508 namespace: this.namespace,
509 indirections: [...this.indirections],
510 options: this.options,
511 ancestors: ancestorsLineage
512 });
513 referencedElement = await visitAsync(referencedElement, visitor, {
514 keyMap: _apidomNsOpenapi.keyMap,
515 nodeTypeGetter: _apidomNsOpenapi.getNodeType
516 });
517
518 // remove referencing schema from ancestors lineage
519 directAncestors.delete(referencingElement);
520 this.indirections.pop();
521
522 // Boolean JSON Schemas
523 if ((0, _apidomNsOpenapi.isBooleanJsonSchemaElement)(referencedElement)) {
524 const booleanJsonSchemaElement = (0, _apidomCore.cloneDeep)(referencedElement);
525 // annotate referenced element with info about original referencing element
526 booleanJsonSchemaElement.setMetaProperty('ref-fields', {
527 $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
528 });
529 // annotate referenced element with info about origin
530 booleanJsonSchemaElement.setMetaProperty('ref-origin', reference.uri);
531 // annotate fragment with info about referencing element
532 booleanJsonSchemaElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
533 return booleanJsonSchemaElement;
534 }
535 const mergeAndAnnotateReferencedElement = refedElement => {
536 // Schema Object - merge keywords from referenced schema with referencing schema
537 const mergedElement = new _apidomNsOpenapi.SchemaElement([...refedElement.content], (0, _apidomCore.cloneDeep)(refedElement.meta), (0, _apidomCore.cloneDeep)(refedElement.attributes));
538 // existing keywords from referencing schema overrides ones from referenced schema
539 referencingElement.forEach((value, keyElement, item) => {
540 mergedElement.remove((0, _apidomCore.toValue)(keyElement));
541 mergedElement.content.push(item);
542 });
543 mergedElement.remove('$ref');
544 // annotate referenced element with info about original referencing element
545 mergedElement.setMetaProperty('ref-fields', {
546 $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
547 });
548 // annotate fragment with info about origin
549 mergedElement.setMetaProperty('ref-origin', reference.uri);
550 // annotate fragment with info about referencing element
551 mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
552 return mergedElement;
553 };
554
555 // attempting to create cycle
556 if (ancestorsLineage.includes(referencingElement) || ancestorsLineage.includes(referencedElement)) {
557 var _ancestorsLineage$fin3;
558 const replaceWith = (_ancestorsLineage$fin3 = ancestorsLineage.findItem(wasReferencedBy(referencingElement))) != null ? _ancestorsLineage$fin3 : mergeAndAnnotateReferencedElement(referencedElement);
559 if ((0, _apidomCore.isMemberElement)(parent)) {
560 parent.value = replaceWith; // eslint-disable-line no-param-reassign
561 } else if (Array.isArray(parent)) {
562 parent[key] = replaceWith; // eslint-disable-line no-param-reassign
563 }
564 return false;
565 }
566 return mergeAndAnnotateReferencedElement(referencedElement);
567 }
568 }
569});
570var _default = exports.default = OpenApi3_1DereferenceVisitor;
Note: See TracBrowser for help on using the repository browser.