swagger-client 3.27.9 → 3.28.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 (32) hide show
  1. package/dist/swagger-client.browser.js +12494 -12585
  2. package/dist/swagger-client.browser.min.js +1 -1
  3. package/dist/swagger-client.browser.min.js.map +1 -1
  4. package/es/index.js +2 -2
  5. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/index.js +81 -119
  6. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/all-of.js +66 -69
  7. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js +569 -588
  8. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/parameters.js +31 -34
  9. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/properties.js +25 -28
  10. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/root.js +45 -0
  11. package/es/resolver/apidom/reference/parse/parsers/json/index.js +43 -42
  12. package/es/resolver/apidom/reference/parse/parsers/openapi-json-3-1/index.js +46 -45
  13. package/es/resolver/apidom/reference/parse/parsers/openapi-yaml-3-1/index.js +46 -45
  14. package/es/resolver/apidom/reference/parse/parsers/yaml-1-2/index.js +44 -43
  15. package/es/resolver/apidom/reference/resolve/resolvers/http-swagger-client/index.js +62 -60
  16. package/es/resolver/strategies/openapi-3-1-apidom/resolve.js +18 -18
  17. package/lib/index.js +1 -1
  18. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/index.js +79 -117
  19. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/all-of.js +66 -69
  20. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/dereference.js +568 -587
  21. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/parameters.js +31 -34
  22. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/properties.js +25 -28
  23. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitors/root.js +51 -0
  24. package/lib/resolver/apidom/reference/parse/parsers/json/index.js +43 -42
  25. package/lib/resolver/apidom/reference/parse/parsers/openapi-json-3-1/index.js +46 -45
  26. package/lib/resolver/apidom/reference/parse/parsers/openapi-yaml-3-1/index.js +46 -45
  27. package/lib/resolver/apidom/reference/parse/parsers/yaml-1-2/index.js +44 -43
  28. package/lib/resolver/apidom/reference/resolve/resolvers/http-swagger-client/index.js +61 -59
  29. package/lib/resolver/strategies/openapi-3-1-apidom/resolve.js +11 -11
  30. package/package.json +23 -22
  31. package/es/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/utils/compose.js +0 -5
  32. package/lib/resolver/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/utils/compose.js +0 -11
@@ -23,420 +23,456 @@ const {
23
23
  const visitAsync = _apidomCore.visit[Symbol.for('nodejs.util.promisify.custom')];
24
24
 
25
25
  // initialize element identity manager
26
- const identityManager = (0, _apidomCore.IdentityManager)();
27
- const OpenApi3_1SwaggerClientDereferenceVisitor = _openapi.OpenApi3_1DereferenceVisitor.compose({
28
- props: {
29
- useCircularStructures: true,
30
- allowMetaPatches: false,
31
- basePath: null
32
- },
33
- init({
34
- allowMetaPatches = this.allowMetaPatches,
35
- useCircularStructures = this.useCircularStructures,
36
- basePath = this.basePath
26
+ const identityManager = new _apidomCore.IdentityManager();
27
+
28
+ // custom mutation replacer
29
+ const mutationReplacer = (newElement, oldElement, key, parent) => {
30
+ if ((0, _apidomCore.isMemberElement)(parent)) {
31
+ parent.value = newElement; // eslint-disable-line no-param-reassign
32
+ } else if (Array.isArray(parent)) {
33
+ parent[key] = newElement; // eslint-disable-line no-param-reassign
34
+ }
35
+ };
36
+ class OpenAPI3_1SwaggerClientDereferenceVisitor extends _openapi.OpenAPI3_1DereferenceVisitor {
37
+ useCircularStructures;
38
+ allowMetaPatches;
39
+ basePath;
40
+ constructor({
41
+ allowMetaPatches = true,
42
+ useCircularStructures = false,
43
+ basePath = null,
44
+ ...rest
37
45
  }) {
46
+ super(rest);
38
47
  this.allowMetaPatches = allowMetaPatches;
39
48
  this.useCircularStructures = useCircularStructures;
40
49
  this.basePath = basePath;
41
- },
42
- methods: {
43
- async ReferenceElement(referencingElement, key, parent, path, ancestors) {
44
- try {
45
- // skip current referencing element as it's already been access
46
- if (this.indirections.includes(referencingElement)) {
47
- return false;
48
- }
49
- const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
50
- const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(referencingElement.$ref));
51
- const isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
52
- const isExternalReference = !isInternalReference;
53
-
54
- // ignore resolving internal Reference Objects
55
- if (!this.options.resolve.internal && isInternalReference) {
56
- return false;
57
- }
58
- // ignore resolving external Reference Objects
59
- if (!this.options.resolve.external && isExternalReference) {
60
- return false;
61
- }
62
- const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
63
- const $refBaseURI = _empty.url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
64
- this.indirections.push(referencingElement);
65
- const jsonPointer = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
66
-
67
- // possibly non-semantic fragment
68
- let referencedElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
69
- referencedElement.id = identityManager.identify(referencedElement);
70
-
71
- // applying semantics to a fragment
72
- if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
73
- const referencedElementType = (0, _apidomCore.toValue)(referencingElement.meta.get('referenced-element'));
74
- const cacheKey = `${referencedElementType}-${(0, _apidomCore.toValue)(identityManager.identify(referencedElement))}`;
75
- if (this.refractCache.has(cacheKey)) {
76
- referencedElement = this.refractCache.get(cacheKey);
77
- } else if ((0, _apidomNsOpenapi.isReferenceLikeElement)(referencedElement)) {
78
- // handling indirect references
79
- referencedElement = _apidomNsOpenapi.ReferenceElement.refract(referencedElement);
80
- referencedElement.setMetaProperty('referenced-element', referencedElementType);
81
- this.refractCache.set(cacheKey, referencedElement);
82
- } else {
83
- // handling direct references
84
- const ElementClass = this.namespace.getElementClass(referencedElementType);
85
- referencedElement = ElementClass.refract(referencedElement);
86
- this.refractCache.set(cacheKey, referencedElement);
87
- }
88
- }
89
-
90
- // detect direct or indirect reference
91
- if (referencingElement === referencedElement) {
92
- throw new _apidomError.ApiDOMError('Recursive Reference Object detected');
50
+ }
51
+ async ReferenceElement(referencingElement, key, parent, path, ancestors, link) {
52
+ try {
53
+ // skip current referencing element as it's already been access
54
+ if (this.indirections.includes(referencingElement)) {
55
+ return false;
56
+ }
57
+ const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
58
+ const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(referencingElement.$ref));
59
+ const isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
60
+ const isExternalReference = !isInternalReference;
61
+
62
+ // ignore resolving internal Reference Objects
63
+ if (!this.options.resolve.internal && isInternalReference) {
64
+ return false;
65
+ }
66
+ // ignore resolving external Reference Objects
67
+ if (!this.options.resolve.external && isExternalReference) {
68
+ return false;
69
+ }
70
+ const reference = await this.toReference((0, _apidomCore.toValue)(referencingElement.$ref));
71
+ const $refBaseURI = _empty.url.resolve(retrievalURI, (0, _apidomCore.toValue)(referencingElement.$ref));
72
+ this.indirections.push(referencingElement);
73
+ const jsonPointer = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
74
+
75
+ // possibly non-semantic fragment
76
+ let referencedElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
77
+ referencedElement.id = identityManager.identify(referencedElement);
78
+
79
+ // applying semantics to a fragment
80
+ if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
81
+ const referencedElementType = (0, _apidomCore.toValue)(referencingElement.meta.get('referenced-element'));
82
+ const cacheKey = `${referencedElementType}-${(0, _apidomCore.toValue)(identityManager.identify(referencedElement))}`;
83
+ if (this.refractCache.has(cacheKey)) {
84
+ referencedElement = this.refractCache.get(cacheKey);
85
+ } else if ((0, _apidomNsOpenapi.isReferenceLikeElement)(referencedElement)) {
86
+ // handling indirect references
87
+ referencedElement = _apidomNsOpenapi.ReferenceElement.refract(referencedElement);
88
+ referencedElement.setMetaProperty('referenced-element', referencedElementType);
89
+ this.refractCache.set(cacheKey, referencedElement);
90
+ } else {
91
+ // handling direct references
92
+ const ElementClass = this.namespace.getElementClass(referencedElementType);
93
+ referencedElement = ElementClass.refract(referencedElement);
94
+ this.refractCache.set(cacheKey, referencedElement);
93
95
  }
96
+ }
94
97
 
95
- // detect maximum depth of dereferencing
96
- if (this.indirections.length > this.options.dereference.maxDepth) {
97
- throw new _empty.MaximumDereferenceDepthError(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
98
- }
98
+ // detect direct or indirect reference
99
+ if (referencingElement === referencedElement) {
100
+ throw new _apidomError.ApiDOMError('Recursive Reference Object detected');
101
+ }
99
102
 
100
- // detect second deep dive into the same fragment and avoid it
101
- if (ancestorsLineage.includes(referencedElement)) {
102
- reference.refSet.circular = true;
103
- if (this.options.dereference.circular === 'error') {
104
- throw new _apidomError.ApiDOMError('Circular reference detected');
105
- } else if (this.options.dereference.circular === 'replace') {
106
- var _this$options$derefer, _this$options$derefer2;
107
- const refElement = new _apidomCore.RefElement(referencedElement.id, {
108
- type: 'reference',
109
- uri: reference.uri,
110
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
111
- baseURI: $refBaseURI,
112
- referencingElement
113
- });
114
- const replacer = (_this$options$derefer = (_this$options$derefer2 = this.options.dereference.strategyOpts['openapi-3-1']) == null ? void 0 : _this$options$derefer2.circularReplacer) != null ? _this$options$derefer : this.options.dereference.circularReplacer;
115
- const replacement = replacer(refElement);
116
- if ((0, _apidomCore.isMemberElement)(parent)) {
117
- parent.value = replacement; // eslint-disable-line no-param-reassign
118
- } else if (Array.isArray(parent)) {
119
- parent[key] = replacement; // eslint-disable-line no-param-reassign
120
- }
121
- return !parent ? replacement : false;
122
- }
123
- }
103
+ // detect maximum depth of dereferencing
104
+ if (this.indirections.length > this.options.dereference.maxDepth) {
105
+ throw new _empty.MaximumDereferenceDepthError(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
106
+ }
124
107
 
125
- /**
126
- * Dive deep into the fragment.
127
- *
128
- * Cases to consider:
129
- * 1. We're crossing document boundary
130
- * 2. Fragment is from non-root document
131
- * 3. Fragment is a Reference Object. We need to follow it to get the eventual value
132
- * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
133
- */
134
- const isNonRootDocument = _empty.url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
135
- const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
136
- if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isReferenceElement)(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
137
- var _this$basePath;
138
- // append referencing reference to ancestors lineage
139
- directAncestors.add(referencingElement);
140
- const visitor = OpenApi3_1SwaggerClientDereferenceVisitor({
141
- reference,
142
- namespace: this.namespace,
143
- indirections: [...this.indirections],
144
- options: this.options,
145
- refractCache: this.refractCache,
146
- ancestors: ancestorsLineage,
147
- allowMetaPatches: this.allowMetaPatches,
148
- useCircularStructures: this.useCircularStructures,
149
- basePath: (_this$basePath = this.basePath) != null ? _this$basePath : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref']
150
- });
151
- referencedElement = await visitAsync(referencedElement, visitor, {
152
- keyMap: _apidomNsOpenapi.keyMap,
153
- nodeTypeGetter: _apidomNsOpenapi.getNodeType
108
+ // detect second deep dive into the same fragment and avoid it
109
+ if (ancestorsLineage.includes(referencedElement)) {
110
+ reference.refSet.circular = true;
111
+ if (this.options.dereference.circular === 'error') {
112
+ throw new _apidomError.ApiDOMError('Circular reference detected');
113
+ } else if (this.options.dereference.circular === 'replace') {
114
+ var _this$options$derefer, _this$options$derefer2;
115
+ const refElement = new _apidomCore.RefElement(referencedElement.id, {
116
+ type: 'reference',
117
+ uri: reference.uri,
118
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
119
+ baseURI: $refBaseURI,
120
+ referencingElement
154
121
  });
155
-
156
- // remove referencing reference from ancestors lineage
157
- directAncestors.delete(referencingElement);
122
+ const replacer = (_this$options$derefer = (_this$options$derefer2 = this.options.dereference.strategyOpts['openapi-3-1']) == null ? void 0 : _this$options$derefer2.circularReplacer) != null ? _this$options$derefer : this.options.dereference.circularReplacer;
123
+ const replacement = replacer(refElement);
124
+ link.replaceWith(refElement, mutationReplacer);
125
+ return !parent ? replacement : false;
158
126
  }
159
- this.indirections.pop();
160
- const mergedElement = (0, _apidomCore.cloneShallow)(referencedElement);
127
+ }
161
128
 
162
- // annotate fragment with info about original Reference element
163
- mergedElement.setMetaProperty('ref-fields', {
164
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
165
- description: (0, _apidomCore.toValue)(referencingElement.description),
166
- summary: (0, _apidomCore.toValue)(referencingElement.summary)
129
+ /**
130
+ * Dive deep into the fragment.
131
+ *
132
+ * Cases to consider:
133
+ * 1. We're crossing document boundary
134
+ * 2. Fragment is from non-root document
135
+ * 3. Fragment is a Reference Object. We need to follow it to get the eventual value
136
+ * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
137
+ */
138
+ const isNonRootDocument = _empty.url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
139
+ const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
140
+ if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isReferenceElement)(referencedElement) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
141
+ var _this$basePath;
142
+ // append referencing reference to ancestors lineage
143
+ directAncestors.add(referencingElement);
144
+ const visitor = new OpenAPI3_1SwaggerClientDereferenceVisitor({
145
+ reference,
146
+ namespace: this.namespace,
147
+ indirections: [...this.indirections],
148
+ options: this.options,
149
+ refractCache: this.refractCache,
150
+ ancestors: ancestorsLineage,
151
+ allowMetaPatches: this.allowMetaPatches,
152
+ useCircularStructures: this.useCircularStructures,
153
+ basePath: (_this$basePath = this.basePath) != null ? _this$basePath : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref']
154
+ });
155
+ referencedElement = await visitAsync(referencedElement, visitor, {
156
+ keyMap: _apidomNsOpenapi.keyMap,
157
+ nodeTypeGetter: _apidomNsOpenapi.getNodeType
167
158
  });
168
- // annotate fragment with info about origin
169
- mergedElement.setMetaProperty('ref-origin', reference.uri);
170
- // annotate fragment with info about referencing element
171
- mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
172
159
 
173
- // override description and summary (outer has higher priority then inner)
174
- if ((0, _apidomCore.isObjectElement)(referencedElement)) {
175
- if (referencingElement.hasKey('description') && 'description' in referencedElement) {
176
- mergedElement.remove('description');
177
- mergedElement.set('description', referencingElement.get('description'));
178
- }
179
- if (referencingElement.hasKey('summary') && 'summary' in referencedElement) {
180
- mergedElement.remove('summary');
181
- mergedElement.set('summary', referencingElement.get('summary'));
182
- }
160
+ // remove referencing reference from ancestors lineage
161
+ directAncestors.delete(referencingElement);
162
+ }
163
+ this.indirections.pop();
164
+ const mergedElement = (0, _apidomCore.cloneShallow)(referencedElement);
165
+
166
+ // annotate fragment with info about original Reference element
167
+ mergedElement.setMetaProperty('ref-fields', {
168
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
169
+ description: (0, _apidomCore.toValue)(referencingElement.description),
170
+ summary: (0, _apidomCore.toValue)(referencingElement.summary)
171
+ });
172
+ // annotate fragment with info about origin
173
+ mergedElement.setMetaProperty('ref-origin', reference.uri);
174
+ // annotate fragment with info about referencing element
175
+ mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
176
+
177
+ // override description and summary (outer has higher priority then inner)
178
+ if ((0, _apidomCore.isObjectElement)(referencedElement)) {
179
+ if (referencingElement.hasKey('description') && 'description' in referencedElement) {
180
+ mergedElement.remove('description');
181
+ mergedElement.set('description', referencingElement.get('description'));
182
+ }
183
+ if (referencingElement.hasKey('summary') && 'summary' in referencedElement) {
184
+ mergedElement.remove('summary');
185
+ mergedElement.set('summary', referencingElement.get('summary'));
183
186
  }
187
+ }
184
188
 
185
- // apply meta patches
186
- if (this.allowMetaPatches && (0, _apidomCore.isObjectElement)(mergedElement)) {
187
- // apply meta patch only when not already applied
188
- if (!mergedElement.hasKey('$$ref')) {
189
- const baseURI = _empty.url.resolve(retrievalURI, $refBaseURI);
190
- mergedElement.set('$$ref', baseURI);
191
- }
189
+ // apply meta patches
190
+ if (this.allowMetaPatches && (0, _apidomCore.isObjectElement)(mergedElement)) {
191
+ // apply meta patch only when not already applied
192
+ if (!mergedElement.hasKey('$$ref')) {
193
+ const baseURI = _empty.url.resolve(retrievalURI, $refBaseURI);
194
+ mergedElement.set('$$ref', baseURI);
192
195
  }
196
+ }
193
197
 
194
- /**
195
- * Transclude referencing element with merged referenced element.
196
- */
197
- if ((0, _apidomCore.isMemberElement)(parent)) {
198
- parent.value = mergedElement; // eslint-disable-line no-param-reassign
199
- } else if (Array.isArray(parent)) {
200
- parent[key] = mergedElement; // eslint-disable-line no-param-reassign
201
- }
198
+ /**
199
+ * Transclude referencing element with merged referenced element.
200
+ */
201
+ link.replaceWith(mergedElement, mutationReplacer);
202
202
 
203
- /**
204
- * We're at the root of the tree, so we're just replacing the entire tree.
205
- */
206
- return !parent ? mergedElement : false;
207
- } catch (error) {
208
- var _this$basePath2, _this$options$derefer3;
209
- const rootCause = (0, _getRootCause.default)(error);
210
- const wrappedError = wrapError(rootCause, {
211
- baseDoc: this.reference.uri,
212
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
213
- pointer: (0, _apidomJsonPointer.uriToPointer)((0, _apidomCore.toValue)(referencingElement.$ref)),
214
- fullPath: (_this$basePath2 = this.basePath) != null ? _this$basePath2 : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref']
215
- });
216
- (_this$options$derefer3 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer3 = _this$options$derefer3.errors) == null || _this$options$derefer3.push == null || _this$options$derefer3.push(wrappedError);
203
+ /**
204
+ * We're at the root of the tree, so we're just replacing the entire tree.
205
+ */
206
+ return !parent ? mergedElement : false;
207
+ } catch (error) {
208
+ var _this$basePath2, _this$options$derefer3;
209
+ const rootCause = (0, _getRootCause.default)(error);
210
+ const wrappedError = wrapError(rootCause, {
211
+ baseDoc: this.reference.uri,
212
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
213
+ pointer: (0, _apidomJsonPointer.uriToPointer)((0, _apidomCore.toValue)(referencingElement.$ref)),
214
+ fullPath: (_this$basePath2 = this.basePath) != null ? _this$basePath2 : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref']
215
+ });
216
+ (_this$options$derefer3 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer3 = _this$options$derefer3.errors) == null || _this$options$derefer3.push == null || _this$options$derefer3.push(wrappedError);
217
+ return undefined;
218
+ }
219
+ }
220
+ async PathItemElement(pathItemElement, key, parent, path, ancestors, link) {
221
+ try {
222
+ // ignore PathItemElement without $ref field
223
+ if (!(0, _apidomCore.isStringElement)(pathItemElement.$ref)) {
217
224
  return undefined;
218
225
  }
219
- },
220
- async PathItemElement(pathItemElement, key, parent, path, ancestors) {
221
- try {
222
- // ignore PathItemElement without $ref field
223
- if (!(0, _apidomCore.isStringElement)(pathItemElement.$ref)) {
224
- return undefined;
225
- }
226
226
 
227
- // skip current referencing element as it's already been access
228
- if (this.indirections.includes(pathItemElement)) {
229
- return false;
230
- }
227
+ // skip current referencing element as it's already been access
228
+ if (this.indirections.includes(pathItemElement)) {
229
+ return false;
230
+ }
231
231
 
232
- // skip already identified cycled Path Item Objects
233
- if ((0, _apidomCore.includesClasses)(['cycle'], pathItemElement.$ref)) {
234
- return false;
235
- }
236
- const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
237
- const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(pathItemElement.$ref));
238
- const isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
239
- const isExternalReference = !isInternalReference;
240
-
241
- // ignore resolving internal Path Item Elements
242
- if (!this.options.resolve.internal && isInternalReference) {
243
- return undefined;
244
- }
245
- // ignore resolving external Path Item Elements
246
- if (!this.options.resolve.external && isExternalReference) {
247
- return undefined;
248
- }
249
- const reference = await this.toReference((0, _apidomCore.toValue)(pathItemElement.$ref));
250
- const $refBaseURI = _empty.url.resolve(retrievalURI, (0, _apidomCore.toValue)(pathItemElement.$ref));
251
- this.indirections.push(pathItemElement);
252
- const jsonPointer = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
253
-
254
- // possibly non-semantic referenced element
255
- let referencedElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
256
- referencedElement.id = identityManager.identify(referencedElement);
257
-
258
- // applying semantics to a referenced element
259
- if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
260
- const cacheKey = `path-item-${(0, _apidomCore.toValue)(identityManager.identify(referencedElement))}`;
261
- if (this.refractCache.has(cacheKey)) {
262
- referencedElement = this.refractCache.get(cacheKey);
263
- } else {
264
- referencedElement = _apidomNsOpenapi.PathItemElement.refract(referencedElement);
265
- this.refractCache.set(cacheKey, referencedElement);
266
- }
267
- }
232
+ // skip already identified cycled Path Item Objects
233
+ if ((0, _apidomCore.includesClasses)(['cycle'], pathItemElement.$ref)) {
234
+ return false;
235
+ }
236
+ const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
237
+ const retrievalURI = this.toBaseURI((0, _apidomCore.toValue)(pathItemElement.$ref));
238
+ const isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
239
+ const isExternalReference = !isInternalReference;
268
240
 
269
- // detect direct or indirect reference
270
- if (pathItemElement === referencedElement) {
271
- throw new _apidomError.ApiDOMError('Recursive Path Item Object reference detected');
241
+ // ignore resolving internal Path Item Elements
242
+ if (!this.options.resolve.internal && isInternalReference) {
243
+ return undefined;
244
+ }
245
+ // ignore resolving external Path Item Elements
246
+ if (!this.options.resolve.external && isExternalReference) {
247
+ return undefined;
248
+ }
249
+ const reference = await this.toReference((0, _apidomCore.toValue)(pathItemElement.$ref));
250
+ const $refBaseURI = _empty.url.resolve(retrievalURI, (0, _apidomCore.toValue)(pathItemElement.$ref));
251
+ this.indirections.push(pathItemElement);
252
+ const jsonPointer = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
253
+
254
+ // possibly non-semantic referenced element
255
+ let referencedElement = (0, _apidomJsonPointer.evaluate)(jsonPointer, reference.value.result);
256
+ referencedElement.id = identityManager.identify(referencedElement);
257
+
258
+ // applying semantics to a referenced element
259
+ if ((0, _apidomCore.isPrimitiveElement)(referencedElement)) {
260
+ const cacheKey = `path-item-${(0, _apidomCore.toValue)(identityManager.identify(referencedElement))}`;
261
+ if (this.refractCache.has(cacheKey)) {
262
+ referencedElement = this.refractCache.get(cacheKey);
263
+ } else {
264
+ referencedElement = _apidomNsOpenapi.PathItemElement.refract(referencedElement);
265
+ this.refractCache.set(cacheKey, referencedElement);
272
266
  }
267
+ }
273
268
 
274
- // detect maximum depth of dereferencing
275
- if (this.indirections.length > this.options.dereference.maxDepth) {
276
- throw new _empty.MaximumDereferenceDepthError(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
277
- }
269
+ // detect direct or indirect reference
270
+ if (pathItemElement === referencedElement) {
271
+ throw new _apidomError.ApiDOMError('Recursive Path Item Object reference detected');
272
+ }
278
273
 
279
- // detect second deep dive into the same fragment and avoid it
280
- if (ancestorsLineage.includes(referencedElement)) {
281
- reference.refSet.circular = true;
282
- if (this.options.dereference.circular === 'error') {
283
- throw new _apidomError.ApiDOMError('Circular reference detected');
284
- } else if (this.options.dereference.circular === 'replace') {
285
- var _this$options$derefer4, _this$options$derefer5;
286
- const refElement = new _apidomCore.RefElement(referencedElement.id, {
287
- type: 'path-item',
288
- uri: reference.uri,
289
- $ref: (0, _apidomCore.toValue)(pathItemElement.$ref),
290
- baseURI: $refBaseURI,
291
- referencingElement: pathItemElement
292
- });
293
- const replacer = (_this$options$derefer4 = (_this$options$derefer5 = this.options.dereference.strategyOpts['openapi-3-1']) == null ? void 0 : _this$options$derefer5.circularReplacer) != null ? _this$options$derefer4 : this.options.dereference.circularReplacer;
294
- const replacement = replacer(refElement);
295
- if ((0, _apidomCore.isMemberElement)(parent)) {
296
- parent.value = replacement; // eslint-disable-line no-param-reassign
297
- } else if (Array.isArray(parent)) {
298
- parent[key] = replacement; // eslint-disable-line no-param-reassign
299
- }
300
- return !parent ? replacement : false;
301
- }
302
- }
274
+ // detect maximum depth of dereferencing
275
+ if (this.indirections.length > this.options.dereference.maxDepth) {
276
+ throw new _empty.MaximumDereferenceDepthError(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
277
+ }
303
278
 
304
- /**
305
- * Dive deep into the fragment.
306
- *
307
- * Cases to consider:
308
- * 1. We're crossing document boundary
309
- * 2. Fragment is from non-root document
310
- * 3. Fragment is a Path Item Object with $ref field. We need to follow it to get the eventual value
311
- * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
312
- */
313
- const isNonRootDocument = _empty.url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
314
- const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
315
- if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isPathItemElement)(referencedElement) && (0, _apidomCore.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
316
- var _this$basePath3;
317
- // append referencing schema to ancestors lineage
318
- directAncestors.add(pathItemElement);
319
-
320
- // dive deep into the referenced element
321
- const visitor = OpenApi3_1SwaggerClientDereferenceVisitor({
322
- reference,
323
- namespace: this.namespace,
324
- indirections: [...this.indirections],
325
- options: this.options,
326
- ancestors: ancestorsLineage,
327
- allowMetaPatches: this.allowMetaPatches,
328
- useCircularStructures: this.useCircularStructures,
329
- basePath: (_this$basePath3 = this.basePath) != null ? _this$basePath3 : [...(0, _toPath.default)([...ancestors, parent, pathItemElement]), '$ref']
330
- });
331
- referencedElement = await visitAsync(referencedElement, visitor, {
332
- keyMap: _apidomNsOpenapi.keyMap,
333
- nodeTypeGetter: _apidomNsOpenapi.getNodeType
279
+ // detect second deep dive into the same fragment and avoid it
280
+ if (ancestorsLineage.includes(referencedElement)) {
281
+ reference.refSet.circular = true;
282
+ if (this.options.dereference.circular === 'error') {
283
+ throw new _apidomError.ApiDOMError('Circular reference detected');
284
+ } else if (this.options.dereference.circular === 'replace') {
285
+ var _this$options$derefer4, _this$options$derefer5;
286
+ const refElement = new _apidomCore.RefElement(referencedElement.id, {
287
+ type: 'path-item',
288
+ uri: reference.uri,
289
+ $ref: (0, _apidomCore.toValue)(pathItemElement.$ref),
290
+ baseURI: $refBaseURI,
291
+ referencingElement: pathItemElement
334
292
  });
335
-
336
- // remove referencing schema from ancestors lineage
337
- directAncestors.delete(pathItemElement);
293
+ const replacer = (_this$options$derefer4 = (_this$options$derefer5 = this.options.dereference.strategyOpts['openapi-3-1']) == null ? void 0 : _this$options$derefer5.circularReplacer) != null ? _this$options$derefer4 : this.options.dereference.circularReplacer;
294
+ const replacement = replacer(refElement);
295
+ link.replaceWith(refElement, mutationReplacer);
296
+ return !parent ? replacement : false;
338
297
  }
339
- this.indirections.pop();
298
+ }
340
299
 
341
- /**
342
- * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
343
- */
344
- if ((0, _apidomNsOpenapi.isPathItemElement)(referencedElement)) {
345
- const mergedElement = new _apidomNsOpenapi.PathItemElement([...referencedElement.content], (0, _apidomCore.cloneDeep)(referencedElement.meta), (0, _apidomCore.cloneDeep)(referencedElement.attributes));
346
- // existing keywords from referencing PathItemElement overrides ones from referenced element
347
- pathItemElement.forEach((value, keyElement, item) => {
348
- mergedElement.remove((0, _apidomCore.toValue)(keyElement));
349
- mergedElement.content.push(item);
350
- });
351
- mergedElement.remove('$ref');
300
+ /**
301
+ * Dive deep into the fragment.
302
+ *
303
+ * Cases to consider:
304
+ * 1. We're crossing document boundary
305
+ * 2. Fragment is from non-root document
306
+ * 3. Fragment is a Path Item Object with $ref field. We need to follow it to get the eventual value
307
+ * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
308
+ */
309
+ const isNonRootDocument = _empty.url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
310
+ const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
311
+ if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isPathItemElement)(referencedElement) && (0, _apidomCore.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
312
+ var _this$basePath3;
313
+ // append referencing schema to ancestors lineage
314
+ directAncestors.add(pathItemElement);
315
+
316
+ // dive deep into the referenced element
317
+ const visitor = new OpenAPI3_1SwaggerClientDereferenceVisitor({
318
+ reference,
319
+ namespace: this.namespace,
320
+ indirections: [...this.indirections],
321
+ options: this.options,
322
+ ancestors: ancestorsLineage,
323
+ allowMetaPatches: this.allowMetaPatches,
324
+ useCircularStructures: this.useCircularStructures,
325
+ basePath: (_this$basePath3 = this.basePath) != null ? _this$basePath3 : [...(0, _toPath.default)([...ancestors, parent, pathItemElement]), '$ref']
326
+ });
327
+ referencedElement = await visitAsync(referencedElement, visitor, {
328
+ keyMap: _apidomNsOpenapi.keyMap,
329
+ nodeTypeGetter: _apidomNsOpenapi.getNodeType
330
+ });
352
331
 
353
- // annotate referenced element with info about original referencing element
354
- mergedElement.setMetaProperty('ref-fields', {
355
- $ref: (0, _apidomCore.toValue)(pathItemElement.$ref)
356
- });
357
- // annotate referenced element with info about origin
358
- mergedElement.setMetaProperty('ref-origin', reference.uri);
359
- // annotate fragment with info about referencing element
360
- mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(pathItemElement)));
361
-
362
- // apply meta patches
363
- if (this.allowMetaPatches) {
364
- // apply meta patch only when not already applied
365
- if (typeof mergedElement.get('$$ref') === 'undefined') {
366
- const baseURI = _empty.url.resolve(retrievalURI, $refBaseURI);
367
- mergedElement.set('$$ref', baseURI);
368
- }
332
+ // remove referencing schema from ancestors lineage
333
+ directAncestors.delete(pathItemElement);
334
+ }
335
+ this.indirections.pop();
336
+
337
+ /**
338
+ * Creating a new version of Path Item by merging fields from referenced Path Item with referencing one.
339
+ */
340
+ if ((0, _apidomNsOpenapi.isPathItemElement)(referencedElement)) {
341
+ const mergedElement = new _apidomNsOpenapi.PathItemElement([...referencedElement.content], (0, _apidomCore.cloneDeep)(referencedElement.meta), (0, _apidomCore.cloneDeep)(referencedElement.attributes));
342
+ // existing keywords from referencing PathItemElement overrides ones from referenced element
343
+ pathItemElement.forEach((value, keyElement, item) => {
344
+ mergedElement.remove((0, _apidomCore.toValue)(keyElement));
345
+ mergedElement.content.push(item);
346
+ });
347
+ mergedElement.remove('$ref');
348
+
349
+ // annotate referenced element with info about original referencing element
350
+ mergedElement.setMetaProperty('ref-fields', {
351
+ $ref: (0, _apidomCore.toValue)(pathItemElement.$ref)
352
+ });
353
+ // annotate referenced element with info about origin
354
+ mergedElement.setMetaProperty('ref-origin', reference.uri);
355
+ // annotate fragment with info about referencing element
356
+ mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(pathItemElement)));
357
+
358
+ // apply meta patches
359
+ if (this.allowMetaPatches) {
360
+ // apply meta patch only when not already applied
361
+ if (typeof mergedElement.get('$$ref') === 'undefined') {
362
+ const baseURI = _empty.url.resolve(retrievalURI, $refBaseURI);
363
+ mergedElement.set('$$ref', baseURI);
369
364
  }
370
- referencedElement = mergedElement;
371
365
  }
366
+ referencedElement = mergedElement;
367
+ }
372
368
 
373
- /**
374
- * Transclude referencing element with merged referenced element.
375
- */
376
- if ((0, _apidomCore.isMemberElement)(parent)) {
377
- parent.value = referencedElement; // eslint-disable-line no-param-reassign
378
- } else if (Array.isArray(parent)) {
379
- parent[key] = referencedElement; // eslint-disable-line no-param-reassign
380
- }
369
+ /**
370
+ * Transclude referencing element with merged referenced element.
371
+ */
372
+ link.replaceWith(referencedElement, mutationReplacer);
381
373
 
382
- /**
383
- * We're at the root of the tree, so we're just replacing the entire tree.
384
- */
385
- return !parent ? referencedElement : undefined;
386
- } catch (error) {
387
- var _this$basePath4, _this$options$derefer6;
388
- const rootCause = (0, _getRootCause.default)(error);
389
- const wrappedError = wrapError(rootCause, {
390
- baseDoc: this.reference.uri,
391
- $ref: (0, _apidomCore.toValue)(pathItemElement.$ref),
392
- pointer: (0, _apidomJsonPointer.uriToPointer)((0, _apidomCore.toValue)(pathItemElement.$ref)),
393
- fullPath: (_this$basePath4 = this.basePath) != null ? _this$basePath4 : [...(0, _toPath.default)([...ancestors, parent, pathItemElement]), '$ref']
394
- });
395
- (_this$options$derefer6 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer6 = _this$options$derefer6.errors) == null || _this$options$derefer6.push == null || _this$options$derefer6.push(wrappedError);
374
+ /**
375
+ * We're at the root of the tree, so we're just replacing the entire tree.
376
+ */
377
+ return !parent ? referencedElement : undefined;
378
+ } catch (error) {
379
+ var _this$basePath4, _this$options$derefer6;
380
+ const rootCause = (0, _getRootCause.default)(error);
381
+ const wrappedError = wrapError(rootCause, {
382
+ baseDoc: this.reference.uri,
383
+ $ref: (0, _apidomCore.toValue)(pathItemElement.$ref),
384
+ pointer: (0, _apidomJsonPointer.uriToPointer)((0, _apidomCore.toValue)(pathItemElement.$ref)),
385
+ fullPath: (_this$basePath4 = this.basePath) != null ? _this$basePath4 : [...(0, _toPath.default)([...ancestors, parent, pathItemElement]), '$ref']
386
+ });
387
+ (_this$options$derefer6 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer6 = _this$options$derefer6.errors) == null || _this$options$derefer6.push == null || _this$options$derefer6.push(wrappedError);
388
+ return undefined;
389
+ }
390
+ }
391
+ async SchemaElement(referencingElement, key, parent, path, ancestors, link) {
392
+ try {
393
+ // skip current referencing schema as $ref keyword was not defined
394
+ if (!(0, _apidomCore.isStringElement)(referencingElement.$ref)) {
395
+ // skip traversing this schema but traverse all it's child schemas
396
396
  return undefined;
397
397
  }
398
- },
399
- async SchemaElement(referencingElement, key, parent, path, ancestors) {
400
- try {
401
- // skip current referencing schema as $ref keyword was not defined
402
- if (!(0, _apidomCore.isStringElement)(referencingElement.$ref)) {
403
- // skip traversing this schema but traverse all it's child schemas
404
- return undefined;
405
- }
406
398
 
407
- // skip current referencing element as it's already been access
408
- if (this.indirections.includes(referencingElement)) {
409
- return false;
399
+ // skip current referencing element as it's already been access
400
+ if (this.indirections.includes(referencingElement)) {
401
+ return false;
402
+ }
403
+ const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
404
+
405
+ // compute baseURI using rules around $id and $ref keywords
406
+ let reference = await this.toReference(_empty.url.unsanitize(this.reference.uri));
407
+ let {
408
+ uri: retrievalURI
409
+ } = reference;
410
+ const $refBaseURI = (0, _openapi.resolveSchema$refField)(retrievalURI, referencingElement);
411
+ const $refBaseURIStrippedHash = _empty.url.stripHash($refBaseURI);
412
+ const file = new _empty.File({
413
+ uri: $refBaseURIStrippedHash
414
+ });
415
+ const isUnknownURI = !this.options.resolve.resolvers.some(r => r.canRead(file));
416
+ const isURL = !isUnknownURI;
417
+ let isInternalReference = _empty.url.stripHash(this.reference.uri) === $refBaseURI;
418
+ let isExternalReference = !isInternalReference;
419
+ this.indirections.push(referencingElement);
420
+
421
+ // determining reference, proper evaluation and selection mechanism
422
+ let referencedElement;
423
+ try {
424
+ if (isUnknownURI || isURL) {
425
+ // we're dealing with canonical URI or URL with possible fragment
426
+ retrievalURI = this.toBaseURI($refBaseURI);
427
+ const selector = $refBaseURI;
428
+ const referenceAsSchema = (0, _openapi.maybeRefractToSchemaElement)(reference.value.result);
429
+ referencedElement = (0, _uri.evaluate)(selector, referenceAsSchema);
430
+ referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
431
+ referencedElement.id = identityManager.identify(referencedElement);
432
+
433
+ // ignore resolving internal Schema Objects
434
+ if (!this.options.resolve.internal && isInternalReference) {
435
+ // skip traversing this schema element but traverse all it's child elements
436
+ return undefined;
437
+ }
438
+ // ignore resolving external Schema Objects
439
+ if (!this.options.resolve.external && isExternalReference) {
440
+ // skip traversing this schema element but traverse all it's child elements
441
+ return undefined;
442
+ }
443
+ } else {
444
+ // we're assuming here that we're dealing with JSON Pointer here
445
+ retrievalURI = this.toBaseURI($refBaseURI);
446
+ isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
447
+ isExternalReference = !isInternalReference;
448
+
449
+ // ignore resolving internal Schema Objects
450
+ if (!this.options.resolve.internal && isInternalReference) {
451
+ // skip traversing this schema element but traverse all it's child elements
452
+ return undefined;
453
+ }
454
+ // ignore resolving external Schema Objects
455
+ if (!this.options.resolve.external && isExternalReference) {
456
+ // skip traversing this schema element but traverse all it's child elements
457
+ return undefined;
458
+ }
459
+ reference = await this.toReference(_empty.url.unsanitize($refBaseURI));
460
+ const selector = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
461
+ const referenceAsSchema = (0, _openapi.maybeRefractToSchemaElement)(reference.value.result);
462
+ referencedElement = (0, _apidomJsonPointer.evaluate)(selector, referenceAsSchema);
463
+ referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
464
+ referencedElement.id = identityManager.identify(referencedElement);
410
465
  }
411
- const [ancestorsLineage, directAncestors] = this.toAncestorLineage([...ancestors, parent]);
412
-
413
- // compute baseURI using rules around $id and $ref keywords
414
- let reference = await this.toReference(_empty.url.unsanitize(this.reference.uri));
415
- let {
416
- uri: retrievalURI
417
- } = reference;
418
- const $refBaseURI = (0, _openapi.resolveSchema$refField)(retrievalURI, referencingElement);
419
- const $refBaseURIStrippedHash = _empty.url.stripHash($refBaseURI);
420
- const file = (0, _empty.File)({
421
- uri: $refBaseURIStrippedHash
422
- });
423
- const isUnknownURI = !this.options.resolve.resolvers.some(r => r.canRead(file));
424
- const isURL = !isUnknownURI;
425
- let isInternalReference = _empty.url.stripHash(this.reference.uri) === $refBaseURI;
426
- let isExternalReference = !isInternalReference;
427
- this.indirections.push(referencingElement);
428
-
429
- // determining reference, proper evaluation and selection mechanism
430
- let referencedElement;
431
- try {
432
- if (isUnknownURI || isURL) {
433
- // we're dealing with canonical URI or URL with possible fragment
434
- retrievalURI = this.toBaseURI($refBaseURI);
435
- const selector = $refBaseURI;
436
- const referenceAsSchema = (0, _openapi.maybeRefractToSchemaElement)(reference.value.result);
437
- referencedElement = (0, _uri.evaluate)(selector, referenceAsSchema);
438
- referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
439
- referencedElement.id = identityManager.identify(referencedElement);
466
+ } catch (error) {
467
+ /**
468
+ * No SchemaElement($id=URL) was not found, so we're going to try to resolve
469
+ * the URL and assume the returned response is a JSON Schema.
470
+ */
471
+ if (isURL && error instanceof _uri.EvaluationJsonSchemaUriError) {
472
+ if ((0, _$anchor.isAnchor)((0, _$anchor.uriToAnchor)($refBaseURI))) {
473
+ // we're dealing with JSON Schema $anchor here
474
+ isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
475
+ isExternalReference = !isInternalReference;
440
476
 
441
477
  // ignore resolving internal Schema Objects
442
478
  if (!this.options.resolve.internal && isInternalReference) {
@@ -448,9 +484,15 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = _openapi.OpenApi3_1Dereference
448
484
  // skip traversing this schema element but traverse all it's child elements
449
485
  return undefined;
450
486
  }
487
+ reference = await this.toReference(_empty.url.unsanitize($refBaseURI));
488
+ const selector = (0, _$anchor.uriToAnchor)($refBaseURI);
489
+ const referenceAsSchema = (0, _openapi.maybeRefractToSchemaElement)(reference.value.result);
490
+ referencedElement = (0, _$anchor.evaluate)(selector, referenceAsSchema);
491
+ referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
492
+ referencedElement.id = identityManager.identify(referencedElement);
451
493
  } else {
452
494
  // we're assuming here that we're dealing with JSON Pointer here
453
- retrievalURI = this.toBaseURI($refBaseURI);
495
+ retrievalURI = this.toBaseURI((0, _apidomCore.toValue)($refBaseURI));
454
496
  isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
455
497
  isExternalReference = !isInternalReference;
456
498
 
@@ -471,232 +513,171 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = _openapi.OpenApi3_1Dereference
471
513
  referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
472
514
  referencedElement.id = identityManager.identify(referencedElement);
473
515
  }
474
- } catch (error) {
475
- /**
476
- * No SchemaElement($id=URL) was not found, so we're going to try to resolve
477
- * the URL and assume the returned response is a JSON Schema.
478
- */
479
- if (isURL && error instanceof _uri.EvaluationJsonSchemaUriError) {
480
- if ((0, _$anchor.isAnchor)((0, _$anchor.uriToAnchor)($refBaseURI))) {
481
- // we're dealing with JSON Schema $anchor here
482
- isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
483
- isExternalReference = !isInternalReference;
484
-
485
- // ignore resolving internal Schema Objects
486
- if (!this.options.resolve.internal && isInternalReference) {
487
- // skip traversing this schema element but traverse all it's child elements
488
- return undefined;
489
- }
490
- // ignore resolving external Schema Objects
491
- if (!this.options.resolve.external && isExternalReference) {
492
- // skip traversing this schema element but traverse all it's child elements
493
- return undefined;
494
- }
495
- reference = await this.toReference(_empty.url.unsanitize($refBaseURI));
496
- const selector = (0, _$anchor.uriToAnchor)($refBaseURI);
497
- const referenceAsSchema = (0, _openapi.maybeRefractToSchemaElement)(reference.value.result);
498
- referencedElement = (0, _$anchor.evaluate)(selector, referenceAsSchema);
499
- referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
500
- referencedElement.id = identityManager.identify(referencedElement);
501
- } else {
502
- // we're assuming here that we're dealing with JSON Pointer here
503
- retrievalURI = this.toBaseURI((0, _apidomCore.toValue)($refBaseURI));
504
- isInternalReference = _empty.url.stripHash(this.reference.uri) === retrievalURI;
505
- isExternalReference = !isInternalReference;
506
-
507
- // ignore resolving internal Schema Objects
508
- if (!this.options.resolve.internal && isInternalReference) {
509
- // skip traversing this schema element but traverse all it's child elements
510
- return undefined;
511
- }
512
- // ignore resolving external Schema Objects
513
- if (!this.options.resolve.external && isExternalReference) {
514
- // skip traversing this schema element but traverse all it's child elements
515
- return undefined;
516
- }
517
- reference = await this.toReference(_empty.url.unsanitize($refBaseURI));
518
- const selector = (0, _apidomJsonPointer.uriToPointer)($refBaseURI);
519
- const referenceAsSchema = (0, _openapi.maybeRefractToSchemaElement)(reference.value.result);
520
- referencedElement = (0, _apidomJsonPointer.evaluate)(selector, referenceAsSchema);
521
- referencedElement = (0, _openapi.maybeRefractToSchemaElement)(referencedElement);
522
- referencedElement.id = identityManager.identify(referencedElement);
523
- }
524
- } else {
525
- throw error;
526
- }
516
+ } else {
517
+ throw error;
527
518
  }
519
+ }
528
520
 
529
- // detect direct or indirect reference
530
- if (referencingElement === referencedElement) {
531
- throw new _apidomError.ApiDOMError('Recursive Schema Object reference detected');
532
- }
521
+ // detect direct or indirect reference
522
+ if (referencingElement === referencedElement) {
523
+ throw new _apidomError.ApiDOMError('Recursive Schema Object reference detected');
524
+ }
533
525
 
534
- // detect maximum depth of dereferencing
535
- if (this.indirections.length > this.options.dereference.maxDepth) {
536
- throw new _empty.MaximumDereferenceDepthError(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
537
- }
526
+ // detect maximum depth of dereferencing
527
+ if (this.indirections.length > this.options.dereference.maxDepth) {
528
+ throw new _empty.MaximumDereferenceDepthError(`Maximum dereference depth of "${this.options.dereference.maxDepth}" has been exceeded in file "${this.reference.uri}"`);
529
+ }
538
530
 
539
- // detect second deep dive into the same fragment and avoid it
540
- if (ancestorsLineage.includes(referencedElement)) {
541
- reference.refSet.circular = true;
542
- if (this.options.dereference.circular === 'error') {
543
- throw new _apidomError.ApiDOMError('Circular reference detected');
544
- } else if (this.options.dereference.circular === 'replace') {
545
- var _this$options$derefer7, _this$options$derefer8;
546
- const refElement = new _apidomCore.RefElement(referencedElement.id, {
547
- type: 'json-schema',
548
- uri: reference.uri,
549
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
550
- baseURI: _empty.url.resolve(retrievalURI, $refBaseURI),
551
- referencingElement
552
- });
553
- const replacer = (_this$options$derefer7 = (_this$options$derefer8 = this.options.dereference.strategyOpts['openapi-3-1']) == null ? void 0 : _this$options$derefer8.circularReplacer) != null ? _this$options$derefer7 : this.options.dereference.circularReplacer;
554
- const replacement = replacer(refElement);
555
- if ((0, _apidomCore.isMemberElement)(parent)) {
556
- parent.value = replacement; // eslint-disable-line no-param-reassign
557
- } else if (Array.isArray(parent)) {
558
- parent[key] = replacement; // eslint-disable-line no-param-reassign
559
- }
560
- return !parent ? replacement : false;
561
- }
531
+ // detect second deep dive into the same fragment and avoid it
532
+ if (ancestorsLineage.includes(referencedElement)) {
533
+ reference.refSet.circular = true;
534
+ if (this.options.dereference.circular === 'error') {
535
+ throw new _apidomError.ApiDOMError('Circular reference detected');
536
+ } else if (this.options.dereference.circular === 'replace') {
537
+ var _this$options$derefer7, _this$options$derefer8;
538
+ const refElement = new _apidomCore.RefElement(referencedElement.id, {
539
+ type: 'json-schema',
540
+ uri: reference.uri,
541
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
542
+ baseURI: _empty.url.resolve(retrievalURI, $refBaseURI),
543
+ referencingElement
544
+ });
545
+ const replacer = (_this$options$derefer7 = (_this$options$derefer8 = this.options.dereference.strategyOpts['openapi-3-1']) == null ? void 0 : _this$options$derefer8.circularReplacer) != null ? _this$options$derefer7 : this.options.dereference.circularReplacer;
546
+ const replacement = replacer(refElement);
547
+ link.replaceWith(replacement, mutationReplacer);
548
+ return !parent ? replacement : false;
562
549
  }
550
+ }
563
551
 
564
- /**
565
- * Dive deep into the fragment.
566
- *
567
- * Cases to consider:
568
- * 1. We're crossing document boundary
569
- * 2. Fragment is from non-root document
570
- * 3. Fragment is a Schema Object with $ref field. We need to follow it to get the eventual value
571
- * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
572
- */
573
- const isNonRootDocument = _empty.url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
574
- const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
575
- if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isSchemaElement)(referencedElement) && (0, _apidomCore.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
576
- var _this$basePath5;
577
- // append referencing schema to ancestors lineage
578
- directAncestors.add(referencingElement);
579
-
580
- // dive deep into the fragment
581
- const mergeVisitor = OpenApi3_1SwaggerClientDereferenceVisitor({
582
- reference,
583
- namespace: this.namespace,
584
- indirections: [...this.indirections],
585
- options: this.options,
586
- useCircularStructures: this.useCircularStructures,
587
- allowMetaPatches: this.allowMetaPatches,
588
- ancestors: ancestorsLineage,
589
- basePath: (_this$basePath5 = this.basePath) != null ? _this$basePath5 : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref']
590
- });
591
- referencedElement = await visitAsync(referencedElement, mergeVisitor, {
592
- keyMap: _apidomNsOpenapi.keyMap,
593
- nodeTypeGetter: _apidomNsOpenapi.getNodeType
594
- });
552
+ /**
553
+ * Dive deep into the fragment.
554
+ *
555
+ * Cases to consider:
556
+ * 1. We're crossing document boundary
557
+ * 2. Fragment is from non-root document
558
+ * 3. Fragment is a Schema Object with $ref field. We need to follow it to get the eventual value
559
+ * 4. We are dereferencing the fragment lazily/eagerly depending on circular mode
560
+ */
561
+ const isNonRootDocument = _empty.url.stripHash(reference.refSet.rootRef.uri) !== reference.uri;
562
+ const shouldDetectCircular = ['error', 'replace'].includes(this.options.dereference.circular);
563
+ if ((isExternalReference || isNonRootDocument || (0, _apidomNsOpenapi.isSchemaElement)(referencedElement) && (0, _apidomCore.isStringElement)(referencedElement.$ref) || shouldDetectCircular) && !ancestorsLineage.includesCycle(referencedElement)) {
564
+ var _this$basePath5;
565
+ // append referencing schema to ancestors lineage
566
+ directAncestors.add(referencingElement);
567
+
568
+ // dive deep into the fragment
569
+ const mergeVisitor = new OpenAPI3_1SwaggerClientDereferenceVisitor({
570
+ reference,
571
+ namespace: this.namespace,
572
+ indirections: [...this.indirections],
573
+ options: this.options,
574
+ useCircularStructures: this.useCircularStructures,
575
+ allowMetaPatches: this.allowMetaPatches,
576
+ ancestors: ancestorsLineage,
577
+ basePath: (_this$basePath5 = this.basePath) != null ? _this$basePath5 : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref']
578
+ });
579
+ referencedElement = await visitAsync(referencedElement, mergeVisitor, {
580
+ keyMap: _apidomNsOpenapi.keyMap,
581
+ nodeTypeGetter: _apidomNsOpenapi.getNodeType
582
+ });
595
583
 
596
- // remove referencing schema from ancestors lineage
597
- directAncestors.delete(referencingElement);
598
- }
599
- this.indirections.pop();
600
- if ((0, _apidomNsOpenapi.isBooleanJsonSchemaElement)(referencedElement)) {
601
- const booleanJsonSchemaElement = (0, _apidomCore.cloneDeep)(referencedElement);
602
- // annotate referenced element with info about original referencing element
603
- booleanJsonSchemaElement.setMetaProperty('ref-fields', {
604
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
605
- });
606
- // annotate referenced element with info about origin
607
- booleanJsonSchemaElement.setMetaProperty('ref-origin', reference.uri);
608
- // annotate fragment with info about referencing element
609
- booleanJsonSchemaElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
610
- if ((0, _apidomCore.isMemberElement)(parent)) {
611
- parent.value = booleanJsonSchemaElement; // eslint-disable-line no-param-reassign
612
- } else if (Array.isArray(parent)) {
613
- parent[key] = booleanJsonSchemaElement; // eslint-disable-line no-param-reassign
614
- }
615
- return !parent ? booleanJsonSchemaElement : false;
616
- }
584
+ // remove referencing schema from ancestors lineage
585
+ directAncestors.delete(referencingElement);
586
+ }
587
+ this.indirections.pop();
588
+ if ((0, _apidomNsOpenapi.isBooleanJsonSchemaElement)(referencedElement)) {
589
+ const booleanJsonSchemaElement = (0, _apidomCore.cloneDeep)(referencedElement);
590
+ // annotate referenced element with info about original referencing element
591
+ booleanJsonSchemaElement.setMetaProperty('ref-fields', {
592
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
593
+ });
594
+ // annotate referenced element with info about origin
595
+ booleanJsonSchemaElement.setMetaProperty('ref-origin', reference.uri);
596
+ // annotate fragment with info about referencing element
597
+ booleanJsonSchemaElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
598
+ link.replaceWith(booleanJsonSchemaElement, mutationReplacer);
599
+ return !parent ? booleanJsonSchemaElement : false;
600
+ }
617
601
 
618
- /**
619
- * Creating a new version of Schema Object by merging fields from referenced Schema Object with referencing one.
620
- */
621
- if ((0, _apidomNsOpenapi.isSchemaElement)(referencedElement)) {
622
- // Schema Object - merge keywords from referenced schema with referencing schema
623
- const mergedElement = new _apidomNsOpenapi.SchemaElement([...referencedElement.content], (0, _apidomCore.cloneDeep)(referencedElement.meta), (0, _apidomCore.cloneDeep)(referencedElement.attributes));
624
- // existing keywords from referencing schema overrides ones from referenced schema
625
- referencingElement.forEach((value, keyElement, item) => {
626
- mergedElement.remove((0, _apidomCore.toValue)(keyElement));
627
- mergedElement.content.push(item);
628
- });
629
- mergedElement.remove('$ref');
630
- // annotate referenced element with info about original referencing element
631
- mergedElement.setMetaProperty('ref-fields', {
632
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
633
- });
634
- // annotate fragment with info about origin
635
- mergedElement.setMetaProperty('ref-origin', reference.uri);
636
- // annotate fragment with info about referencing element
637
- mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
638
-
639
- // allowMetaPatches option processing
640
- if (this.allowMetaPatches) {
641
- // apply meta patch only when not already applied
642
- if (typeof mergedElement.get('$$ref') === 'undefined') {
643
- const baseURI = _empty.url.resolve(retrievalURI, $refBaseURI);
644
- mergedElement.set('$$ref', baseURI);
645
- }
602
+ /**
603
+ * Creating a new version of Schema Object by merging fields from referenced Schema Object with referencing one.
604
+ */
605
+ if ((0, _apidomNsOpenapi.isSchemaElement)(referencedElement)) {
606
+ // Schema Object - merge keywords from referenced schema with referencing schema
607
+ const mergedElement = new _apidomNsOpenapi.SchemaElement([...referencedElement.content], (0, _apidomCore.cloneDeep)(referencedElement.meta), (0, _apidomCore.cloneDeep)(referencedElement.attributes));
608
+ // existing keywords from referencing schema overrides ones from referenced schema
609
+ referencingElement.forEach((value, keyElement, item) => {
610
+ mergedElement.remove((0, _apidomCore.toValue)(keyElement));
611
+ mergedElement.content.push(item);
612
+ });
613
+ mergedElement.remove('$ref');
614
+ // annotate referenced element with info about original referencing element
615
+ mergedElement.setMetaProperty('ref-fields', {
616
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref)
617
+ });
618
+ // annotate fragment with info about origin
619
+ mergedElement.setMetaProperty('ref-origin', reference.uri);
620
+ // annotate fragment with info about referencing element
621
+ mergedElement.setMetaProperty('ref-referencing-element-id', (0, _apidomCore.cloneDeep)(identityManager.identify(referencingElement)));
622
+
623
+ // allowMetaPatches option processing
624
+ if (this.allowMetaPatches) {
625
+ // apply meta patch only when not already applied
626
+ if (typeof mergedElement.get('$$ref') === 'undefined') {
627
+ const baseURI = _empty.url.resolve(retrievalURI, $refBaseURI);
628
+ mergedElement.set('$$ref', baseURI);
646
629
  }
647
- referencedElement = mergedElement;
648
630
  }
631
+ referencedElement = mergedElement;
632
+ }
649
633
 
650
- /**
651
- * Transclude referencing element with merged referenced element.
652
- */
653
- if ((0, _apidomCore.isMemberElement)(parent)) {
654
- parent.value = referencedElement; // eslint-disable-line no-param-reassign
655
- } else if (Array.isArray(parent)) {
656
- parent[key] = referencedElement; // eslint-disable-line no-param-reassign
657
- }
634
+ /**
635
+ * Transclude referencing element with merged referenced element.
636
+ */
637
+ link.replaceWith(referencedElement, mutationReplacer);
658
638
 
659
- /**
660
- * We're at the root of the tree, so we're just replacing the entire tree.
661
- */
662
- return !parent ? referencedElement : undefined;
663
- } catch (error) {
664
- var _this$basePath6, _this$options$derefer9;
665
- const rootCause = (0, _getRootCause.default)(error);
666
- const wrappedError = new _SchemaRefError.default(`Could not resolve reference: ${rootCause.message}`, {
667
- baseDoc: this.reference.uri,
668
- $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
669
- fullPath: (_this$basePath6 = this.basePath) != null ? _this$basePath6 : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref'],
670
- cause: rootCause
671
- });
672
- (_this$options$derefer9 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer9 = _this$options$derefer9.errors) == null || _this$options$derefer9.push == null || _this$options$derefer9.push(wrappedError);
673
- return undefined;
674
- }
675
- },
676
- async LinkElement() {
677
639
  /**
678
- * OpenApi3_1DereferenceVisitor is doing lookup of Operation Objects
679
- * and assigns them to Link Object metadata. This is not needed in
680
- * swagger-client context, so we're disabling it here.
640
+ * We're at the root of the tree, so we're just replacing the entire tree.
681
641
  */
642
+ return !parent ? referencedElement : undefined;
643
+ } catch (error) {
644
+ var _this$basePath6, _this$options$derefer9;
645
+ const rootCause = (0, _getRootCause.default)(error);
646
+ const wrappedError = new _SchemaRefError.default(`Could not resolve reference: ${rootCause.message}`, {
647
+ baseDoc: this.reference.uri,
648
+ $ref: (0, _apidomCore.toValue)(referencingElement.$ref),
649
+ fullPath: (_this$basePath6 = this.basePath) != null ? _this$basePath6 : [...(0, _toPath.default)([...ancestors, parent, referencingElement]), '$ref'],
650
+ cause: rootCause
651
+ });
652
+ (_this$options$derefer9 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer9 = _this$options$derefer9.errors) == null || _this$options$derefer9.push == null || _this$options$derefer9.push(wrappedError);
653
+ return undefined;
654
+ }
655
+ }
656
+
657
+ // eslint-disable-next-line class-methods-use-this
658
+ async LinkElement() {
659
+ /**
660
+ * OpenApi3_1DereferenceVisitor is doing lookup of Operation Objects
661
+ * and assigns them to Link Object metadata. This is not needed in
662
+ * swagger-client context, so we're disabling it here.
663
+ */
664
+ return undefined;
665
+ }
666
+ async ExampleElement(exampleElement, key, parent, path, ancestors, link) {
667
+ try {
668
+ return await super.ExampleElement(exampleElement, key, parent, path, ancestors, link);
669
+ } catch (error) {
670
+ var _this$basePath7, _this$options$derefer10;
671
+ const rootCause = (0, _getRootCause.default)(error);
672
+ const wrappedError = wrapError(rootCause, {
673
+ baseDoc: this.reference.uri,
674
+ externalValue: (0, _apidomCore.toValue)(exampleElement.externalValue),
675
+ fullPath: (_this$basePath7 = this.basePath) != null ? _this$basePath7 : [...(0, _toPath.default)([...ancestors, parent, exampleElement]), 'externalValue']
676
+ });
677
+ (_this$options$derefer10 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer10 = _this$options$derefer10.errors) == null || _this$options$derefer10.push == null || _this$options$derefer10.push(wrappedError);
682
678
  return undefined;
683
- },
684
- async ExampleElement(exampleElement, key, parent, path, ancestors) {
685
- try {
686
- return await _openapi.OpenApi3_1DereferenceVisitor.compose.methods.ExampleElement.call(this, exampleElement, key, parent, path, ancestors);
687
- } catch (error) {
688
- var _this$basePath7, _this$options$derefer10;
689
- const rootCause = (0, _getRootCause.default)(error);
690
- const wrappedError = wrapError(rootCause, {
691
- baseDoc: this.reference.uri,
692
- externalValue: (0, _apidomCore.toValue)(exampleElement.externalValue),
693
- fullPath: (_this$basePath7 = this.basePath) != null ? _this$basePath7 : [...(0, _toPath.default)([...ancestors, parent, exampleElement]), 'externalValue']
694
- });
695
- (_this$options$derefer10 = this.options.dereference.dereferenceOpts) == null || (_this$options$derefer10 = _this$options$derefer10.errors) == null || _this$options$derefer10.push == null || _this$options$derefer10.push(wrappedError);
696
- return undefined;
697
- }
698
679
  }
699
680
  }
700
- });
701
- var _default = exports.default = OpenApi3_1SwaggerClientDereferenceVisitor;
681
+ }
682
+ var _default = exports.default = OpenAPI3_1SwaggerClientDereferenceVisitor;
702
683
  /* eslint-enable camelcase */