@speclynx/apidom-reference 3.2.0 → 4.0.0

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 (192) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/dist/apidom-reference.browser.js +162 -127
  3. package/dist/apidom-reference.browser.min.js +1 -1
  4. package/package.json +25 -25
  5. package/types/dereference/strategies/apidom/visitor.d.ts +1 -1
  6. package/types/dereference/strategies/arazzo-1/visitor.d.ts +1 -1
  7. package/types/dereference/strategies/asyncapi-2/visitor.d.ts +1 -1
  8. package/types/dereference/strategies/openapi-2/visitor.d.ts +1 -1
  9. package/types/dereference/strategies/openapi-3-0/visitor.d.ts +1 -1
  10. package/types/dereference/strategies/openapi-3-1/visitor.d.ts +1 -1
  11. package/src/File.cjs +0 -50
  12. package/src/File.mjs +0 -44
  13. package/src/Reference.cjs +0 -31
  14. package/src/Reference.mjs +0 -27
  15. package/src/ReferenceSet.cjs +0 -60
  16. package/src/ReferenceSet.mjs +0 -57
  17. package/src/bundle/index.cjs +0 -61
  18. package/src/bundle/index.mjs +0 -55
  19. package/src/bundle/strategies/BundleStrategy.cjs +0 -20
  20. package/src/bundle/strategies/BundleStrategy.mjs +0 -16
  21. package/src/bundle/strategies/openapi-3-1/index.cjs +0 -35
  22. package/src/bundle/strategies/openapi-3-1/index.mjs +0 -29
  23. package/src/configuration/empty.cjs +0 -9
  24. package/src/configuration/empty.mjs +0 -1
  25. package/src/configuration/saturated.cjs +0 -88
  26. package/src/configuration/saturated.mjs +0 -80
  27. package/src/dereference/index.cjs +0 -90
  28. package/src/dereference/index.mjs +0 -83
  29. package/src/dereference/strategies/DereferenceStrategy.cjs +0 -20
  30. package/src/dereference/strategies/DereferenceStrategy.mjs +0 -16
  31. package/src/dereference/strategies/apidom/index.cjs +0 -89
  32. package/src/dereference/strategies/apidom/index.mjs +0 -83
  33. package/src/dereference/strategies/apidom/selectors/element-id.cjs +0 -47
  34. package/src/dereference/strategies/apidom/selectors/element-id.mjs +0 -41
  35. package/src/dereference/strategies/apidom/visitor.cjs +0 -259
  36. package/src/dereference/strategies/apidom/visitor.mjs +0 -252
  37. package/src/dereference/strategies/arazzo-1/index.cjs +0 -109
  38. package/src/dereference/strategies/arazzo-1/index.mjs +0 -100
  39. package/src/dereference/strategies/arazzo-1/selectors/$anchor.cjs +0 -12
  40. package/src/dereference/strategies/arazzo-1/selectors/$anchor.mjs +0 -1
  41. package/src/dereference/strategies/arazzo-1/selectors/uri.cjs +0 -8
  42. package/src/dereference/strategies/arazzo-1/selectors/uri.mjs +0 -1
  43. package/src/dereference/strategies/arazzo-1/source-descriptions.cjs +0 -248
  44. package/src/dereference/strategies/arazzo-1/source-descriptions.mjs +0 -243
  45. package/src/dereference/strategies/arazzo-1/util.cjs +0 -37
  46. package/src/dereference/strategies/arazzo-1/util.mjs +0 -29
  47. package/src/dereference/strategies/arazzo-1/visitor.cjs +0 -501
  48. package/src/dereference/strategies/arazzo-1/visitor.mjs +0 -494
  49. package/src/dereference/strategies/asyncapi-2/index.cjs +0 -94
  50. package/src/dereference/strategies/asyncapi-2/index.mjs +0 -88
  51. package/src/dereference/strategies/asyncapi-2/visitor.cjs +0 -495
  52. package/src/dereference/strategies/asyncapi-2/visitor.mjs +0 -488
  53. package/src/dereference/strategies/openapi-2/index.cjs +0 -96
  54. package/src/dereference/strategies/openapi-2/index.mjs +0 -90
  55. package/src/dereference/strategies/openapi-2/visitor.cjs +0 -623
  56. package/src/dereference/strategies/openapi-2/visitor.mjs +0 -616
  57. package/src/dereference/strategies/openapi-3-0/index.cjs +0 -96
  58. package/src/dereference/strategies/openapi-3-0/index.mjs +0 -90
  59. package/src/dereference/strategies/openapi-3-0/visitor.cjs +0 -615
  60. package/src/dereference/strategies/openapi-3-0/visitor.mjs +0 -608
  61. package/src/dereference/strategies/openapi-3-1/index.cjs +0 -99
  62. package/src/dereference/strategies/openapi-3-1/index.mjs +0 -90
  63. package/src/dereference/strategies/openapi-3-1/selectors/$anchor.cjs +0 -67
  64. package/src/dereference/strategies/openapi-3-1/selectors/$anchor.mjs +0 -56
  65. package/src/dereference/strategies/openapi-3-1/selectors/uri.cjs +0 -50
  66. package/src/dereference/strategies/openapi-3-1/selectors/uri.mjs +0 -42
  67. package/src/dereference/strategies/openapi-3-1/util.cjs +0 -68
  68. package/src/dereference/strategies/openapi-3-1/util.mjs +0 -59
  69. package/src/dereference/strategies/openapi-3-1/visitor.cjs +0 -867
  70. package/src/dereference/strategies/openapi-3-1/visitor.mjs +0 -860
  71. package/src/dereference/util.cjs +0 -31
  72. package/src/dereference/util.mjs +0 -27
  73. package/src/errors/BundleError.cjs +0 -10
  74. package/src/errors/BundleError.mjs +0 -7
  75. package/src/errors/DereferenceError.cjs +0 -10
  76. package/src/errors/DereferenceError.mjs +0 -7
  77. package/src/errors/EvaluationElementIdError.cjs +0 -10
  78. package/src/errors/EvaluationElementIdError.mjs +0 -7
  79. package/src/errors/EvaluationJsonSchema$anchorError.cjs +0 -11
  80. package/src/errors/EvaluationJsonSchema$anchorError.mjs +0 -6
  81. package/src/errors/EvaluationJsonSchemaUriError.cjs +0 -11
  82. package/src/errors/EvaluationJsonSchemaUriError.mjs +0 -6
  83. package/src/errors/InvalidJsonSchema$anchorError.cjs +0 -15
  84. package/src/errors/InvalidJsonSchema$anchorError.mjs +0 -10
  85. package/src/errors/JsonSchema$anchorError.cjs +0 -10
  86. package/src/errors/JsonSchema$anchorError.mjs +0 -7
  87. package/src/errors/JsonSchemaUriError.cjs +0 -10
  88. package/src/errors/JsonSchemaUriError.mjs +0 -7
  89. package/src/errors/MaximumBundleDepthError.cjs +0 -11
  90. package/src/errors/MaximumBundleDepthError.mjs +0 -6
  91. package/src/errors/MaximumDereferenceDepthError.cjs +0 -11
  92. package/src/errors/MaximumDereferenceDepthError.mjs +0 -6
  93. package/src/errors/MaximumResolveDepthError.cjs +0 -11
  94. package/src/errors/MaximumResolveDepthError.mjs +0 -6
  95. package/src/errors/ParseError.cjs +0 -10
  96. package/src/errors/ParseError.mjs +0 -7
  97. package/src/errors/ParserError.cjs +0 -11
  98. package/src/errors/ParserError.mjs +0 -6
  99. package/src/errors/PluginError.cjs +0 -18
  100. package/src/errors/PluginError.mjs +0 -15
  101. package/src/errors/ResolveError.cjs +0 -10
  102. package/src/errors/ResolveError.mjs +0 -7
  103. package/src/errors/ResolverError.cjs +0 -11
  104. package/src/errors/ResolverError.mjs +0 -6
  105. package/src/errors/UnmatchedBundleStrategyError.cjs +0 -11
  106. package/src/errors/UnmatchedBundleStrategyError.mjs +0 -6
  107. package/src/errors/UnmatchedDereferenceStrategyError.cjs +0 -11
  108. package/src/errors/UnmatchedDereferenceStrategyError.mjs +0 -6
  109. package/src/errors/UnmatchedParserError.cjs +0 -11
  110. package/src/errors/UnmatchedParserError.mjs +0 -6
  111. package/src/errors/UnmatchedResolveStrategyError.cjs +0 -11
  112. package/src/errors/UnmatchedResolveStrategyError.mjs +0 -6
  113. package/src/errors/UnmatchedResolverError.cjs +0 -11
  114. package/src/errors/UnmatchedResolverError.mjs +0 -6
  115. package/src/errors/UnresolvableReferenceError.cjs +0 -11
  116. package/src/errors/UnresolvableReferenceError.mjs +0 -6
  117. package/src/index.cjs +0 -146
  118. package/src/index.mjs +0 -103
  119. package/src/options/index.cjs +0 -194
  120. package/src/options/index.mjs +0 -191
  121. package/src/options/util.cjs +0 -24
  122. package/src/options/util.mjs +0 -19
  123. package/src/parse/index.cjs +0 -69
  124. package/src/parse/index.mjs +0 -63
  125. package/src/parse/parsers/Parser.cjs +0 -62
  126. package/src/parse/parsers/Parser.mjs +0 -58
  127. package/src/parse/parsers/apidom-json/index.cjs +0 -70
  128. package/src/parse/parsers/apidom-json/index.mjs +0 -64
  129. package/src/parse/parsers/arazzo-json-1/index.cjs +0 -62
  130. package/src/parse/parsers/arazzo-json-1/index.mjs +0 -56
  131. package/src/parse/parsers/arazzo-json-1/source-descriptions.cjs +0 -221
  132. package/src/parse/parsers/arazzo-json-1/source-descriptions.mjs +0 -214
  133. package/src/parse/parsers/arazzo-yaml-1/index.cjs +0 -62
  134. package/src/parse/parsers/arazzo-yaml-1/index.mjs +0 -56
  135. package/src/parse/parsers/arazzo-yaml-1/source-descriptions.cjs +0 -12
  136. package/src/parse/parsers/arazzo-yaml-1/source-descriptions.mjs +0 -7
  137. package/src/parse/parsers/asyncapi-json-2/index.cjs +0 -54
  138. package/src/parse/parsers/asyncapi-json-2/index.mjs +0 -48
  139. package/src/parse/parsers/asyncapi-yaml-2/index.cjs +0 -54
  140. package/src/parse/parsers/asyncapi-yaml-2/index.mjs +0 -48
  141. package/src/parse/parsers/binary/index-browser.cjs +0 -56
  142. package/src/parse/parsers/binary/index-browser.mjs +0 -50
  143. package/src/parse/parsers/binary/index-node.cjs +0 -51
  144. package/src/parse/parsers/binary/index-node.mjs +0 -45
  145. package/src/parse/parsers/json/index.cjs +0 -53
  146. package/src/parse/parsers/json/index.mjs +0 -47
  147. package/src/parse/parsers/openapi-json-2/index.cjs +0 -54
  148. package/src/parse/parsers/openapi-json-2/index.mjs +0 -48
  149. package/src/parse/parsers/openapi-json-3-0/index.cjs +0 -54
  150. package/src/parse/parsers/openapi-json-3-0/index.mjs +0 -48
  151. package/src/parse/parsers/openapi-json-3-1/index.cjs +0 -54
  152. package/src/parse/parsers/openapi-json-3-1/index.mjs +0 -48
  153. package/src/parse/parsers/openapi-yaml-2/index.cjs +0 -54
  154. package/src/parse/parsers/openapi-yaml-2/index.mjs +0 -48
  155. package/src/parse/parsers/openapi-yaml-3-0/index.cjs +0 -54
  156. package/src/parse/parsers/openapi-yaml-3-0/index.mjs +0 -48
  157. package/src/parse/parsers/openapi-yaml-3-1/index.cjs +0 -54
  158. package/src/parse/parsers/openapi-yaml-3-1/index.mjs +0 -48
  159. package/src/parse/parsers/yaml-1-2/index.cjs +0 -56
  160. package/src/parse/parsers/yaml-1-2/index.mjs +0 -50
  161. package/src/resolve/index.cjs +0 -67
  162. package/src/resolve/index.mjs +0 -60
  163. package/src/resolve/resolvers/HTTPResolver.cjs +0 -45
  164. package/src/resolve/resolvers/HTTPResolver.mjs +0 -37
  165. package/src/resolve/resolvers/Resolver.cjs +0 -20
  166. package/src/resolve/resolvers/Resolver.mjs +0 -16
  167. package/src/resolve/resolvers/file/index-browser.cjs +0 -24
  168. package/src/resolve/resolvers/file/index-browser.mjs +0 -19
  169. package/src/resolve/resolvers/file/index-node.cjs +0 -49
  170. package/src/resolve/resolvers/file/index-node.mjs +0 -42
  171. package/src/resolve/resolvers/http-axios/cache/MemoryCache.cjs +0 -41
  172. package/src/resolve/resolvers/http-axios/cache/MemoryCache.mjs +0 -37
  173. package/src/resolve/resolvers/http-axios/index.cjs +0 -113
  174. package/src/resolve/resolvers/http-axios/index.mjs +0 -105
  175. package/src/resolve/strategies/ResolveStrategy.cjs +0 -20
  176. package/src/resolve/strategies/ResolveStrategy.mjs +0 -16
  177. package/src/resolve/strategies/apidom/index.cjs +0 -49
  178. package/src/resolve/strategies/apidom/index.mjs +0 -43
  179. package/src/resolve/strategies/asyncapi-2/index.cjs +0 -49
  180. package/src/resolve/strategies/asyncapi-2/index.mjs +0 -43
  181. package/src/resolve/strategies/openapi-2/index.cjs +0 -49
  182. package/src/resolve/strategies/openapi-2/index.mjs +0 -43
  183. package/src/resolve/strategies/openapi-3-0/index.cjs +0 -49
  184. package/src/resolve/strategies/openapi-3-0/index.mjs +0 -43
  185. package/src/resolve/strategies/openapi-3-1/index.cjs +0 -49
  186. package/src/resolve/strategies/openapi-3-1/index.mjs +0 -43
  187. package/src/resolve/util.cjs +0 -37
  188. package/src/resolve/util.mjs +0 -30
  189. package/src/util/plugins.cjs +0 -39
  190. package/src/util/plugins.mjs +0 -34
  191. package/src/util/url.cjs +0 -288
  192. package/src/util/url.mjs +0 -274
@@ -1,259 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
5
- exports.__esModule = true;
6
- exports.default = void 0;
7
- var _ramda = require("ramda");
8
- var _apidomError = require("@speclynx/apidom-error");
9
- var _apidomDatamodel = require("@speclynx/apidom-datamodel");
10
- var _apidomCore = require("@speclynx/apidom-core");
11
- var _apidomTraverse = require("@speclynx/apidom-traverse");
12
- var _apidomJsonPointer = require("@speclynx/apidom-json-pointer");
13
- var _MaximumResolveDepthError = _interopRequireDefault(require("../../../errors/MaximumResolveDepthError.cjs"));
14
- var _UnresolvableReferenceError = _interopRequireDefault(require("../../../errors/UnresolvableReferenceError.cjs"));
15
- var url = _interopRequireWildcard(require("../../../util/url.cjs"));
16
- var _index = _interopRequireDefault(require("../../../parse/index.cjs"));
17
- var _Reference = _interopRequireDefault(require("../../../Reference.cjs"));
18
- var _elementId = require("./selectors/element-id.cjs");
19
- /**
20
- * The following rules apply:
21
- *
22
- * 1. When referencing an element in the local document, the id of the element MAY be used
23
- * 2. When referencing remote elements, an absolute URL or relative URL MAY be used
24
- * 3. When a URL fragment exists in the URL given, it references the element with the matching id in the given document. The URL fragment MAY need to be URL decoded before making a match.
25
- * 4. When a URL fragment does not exist, the URL references the root element
26
- * 5. When path is used, it references the given property of the referenced element
27
- * 6. When path is used in an element that includes the data of the pointer (such as with ref), the referenced path MAY need to be converted to a refract structure in order to be valid
28
- *
29
- * WARNING: this implementation only supports referencing elements in the local document. Points 2-4 are not supported.
30
- * @public
31
- */
32
-
33
- /**
34
- * @public
35
- */
36
- class ApiDOMDereferenceVisitor {
37
- reference;
38
- options;
39
- constructor({
40
- reference,
41
- options
42
- }) {
43
- this.reference = reference;
44
- this.options = options;
45
- }
46
- toBaseURI(uri) {
47
- return url.resolve(this.reference.uri, url.sanitize(url.stripHash(uri)));
48
- }
49
- async toReference(uri) {
50
- // detect maximum depth of resolution
51
- if (this.reference.depth >= this.options.resolve.maxDepth) {
52
- throw new _MaximumResolveDepthError.default(`Maximum resolution depth of ${this.options.resolve.maxDepth} has been exceeded by file "${this.reference.uri}"`, {
53
- maxDepth: this.options.resolve.maxDepth,
54
- uri: this.reference.uri
55
- });
56
- }
57
- const baseURI = this.toBaseURI(uri);
58
- const {
59
- refSet
60
- } = this.reference;
61
-
62
- // we've already processed this Reference in past
63
- if (refSet.has(baseURI)) {
64
- return refSet.find((0, _ramda.propEq)(baseURI, 'uri'));
65
- }
66
- const parseResult = await (0, _index.default)(url.unsanitize(baseURI), {
67
- ...this.options,
68
- parse: {
69
- ...this.options.parse,
70
- mediaType: 'text/plain'
71
- }
72
- });
73
-
74
- // register new mutable reference with a refSet
75
- const mutableReference = new _Reference.default({
76
- uri: baseURI,
77
- value: (0, _apidomDatamodel.cloneDeep)(parseResult),
78
- depth: this.reference.depth + 1
79
- });
80
- refSet.add(mutableReference);
81
- if (this.options.dereference.immutable) {
82
- // register new immutable reference with a refSet
83
- const immutableReference = new _Reference.default({
84
- uri: `immutable://${baseURI}`,
85
- value: parseResult,
86
- depth: this.reference.depth + 1
87
- });
88
- refSet.add(immutableReference);
89
- }
90
- return mutableReference;
91
- }
92
-
93
- /**
94
- * Handles an error according to the continueOnError option.
95
- *
96
- * For new errors: wraps in UnresolvableReferenceError with structured context.
97
- * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
98
- *
99
- * Inner/intermediate visitors always throw to let the trace accumulate.
100
- * Only the entry document visitor respects continueOnError (callback/swallow/throw).
101
- */
102
- handleError(message, error, referencingElement, refFieldName, refFieldValue, visitorPath) {
103
- const {
104
- continueOnError
105
- } = this.options.dereference;
106
- const isEntryDocument = url.stripHash(this.reference.refSet?.rootRef?.uri ?? '') === this.reference.uri;
107
- const uri = this.reference.uri;
108
- const type = referencingElement.element;
109
- let location;
110
- (0, _apidomTraverse.traverse)(this.reference.value.result, {
111
- enter(p) {
112
- if (p.node === referencingElement) {
113
- location = p.formatPath();
114
- p.stop();
115
- }
116
- }
117
- });
118
- location ??= visitorPath.formatPath();
119
- const codeFrame = (0, _apidomCore.toYAML)(referencingElement);
120
- const hop = {
121
- uri,
122
- type,
123
- refFieldName,
124
- refFieldValue,
125
- location,
126
- codeFrame
127
- };
128
- let unresolvedError;
129
- if (error instanceof _UnresolvableReferenceError.default) {
130
- const refBaseURI = this.toBaseURI(refFieldValue);
131
- const fragment = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference(refFieldValue);
132
- if (fragment) {
133
- if (refBaseURI === error.uri && error.location) {
134
- error.location = fragment + error.location;
135
- }
136
- for (const h of error.trace) {
137
- if (h.uri === refBaseURI && h.location) h.location = fragment + h.location;
138
- }
139
- }
140
- // @ts-ignore
141
- error.trace = [hop, ...error.trace];
142
- unresolvedError = error;
143
- } else {
144
- unresolvedError = new _UnresolvableReferenceError.default(message, {
145
- cause: error,
146
- type,
147
- uri,
148
- location,
149
- codeFrame,
150
- refFieldName,
151
- refFieldValue,
152
- trace: []
153
- });
154
- }
155
- if (!isEntryDocument || continueOnError === false) throw unresolvedError;
156
- if (typeof continueOnError === 'function') continueOnError(unresolvedError);
157
- }
158
- async RefElement(path) {
159
- const refElement = path.node;
160
- const {
161
- parent,
162
- key
163
- } = path;
164
- const ancestors = path.getAncestorNodes();
165
- const refURI = (0, _apidomCore.toValue)(refElement);
166
- const refNormalizedURI = refURI.includes('#') ? refURI : `#${refURI}`;
167
- const retrievalURI = this.toBaseURI(refNormalizedURI);
168
- const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
169
- const isExternalReference = !isInternalReference;
170
-
171
- // ignore resolving internal RefElements
172
- if (!this.options.resolve.internal && isInternalReference) {
173
- // skip traversing this ref element
174
- path.skip();
175
- return;
176
- }
177
- // ignore resolving external RefElements
178
- if (!this.options.resolve.external && isExternalReference) {
179
- // skip traversing this ref element
180
- path.skip();
181
- return;
182
- }
183
- try {
184
- const reference = await this.toReference(refNormalizedURI);
185
- const refBaseURI = url.resolve(retrievalURI, refNormalizedURI);
186
- const elementID = _apidomJsonPointer.URIFragmentIdentifier.fromURIReference(refBaseURI);
187
- let referencedElement = (0, _elementId.evaluate)(elementID, reference.value.result);
188
- if (!(0, _apidomDatamodel.isElement)(referencedElement)) {
189
- throw new _apidomError.ApiDOMStructuredError(`Referenced element with id="${elementID}" was not found`, {
190
- elementID
191
- });
192
- }
193
- if (refElement === referencedElement) {
194
- throw new _apidomError.ApiDOMStructuredError(`RefElement with id="${elementID}" cannot reference itself`, {
195
- elementID
196
- });
197
- }
198
- if ((0, _apidomDatamodel.isRefElement)(referencedElement)) {
199
- throw new _apidomError.ApiDOMStructuredError(`RefElement with id="${elementID}" cannot reference another RefElement`, {
200
- elementID
201
- });
202
- }
203
- if (isExternalReference) {
204
- // dive deep into the fragment
205
- const visitor = new ApiDOMDereferenceVisitor({
206
- reference,
207
- options: this.options
208
- });
209
- referencedElement = await (0, _apidomTraverse.traverseAsync)(referencedElement, visitor, {
210
- mutable: true
211
- });
212
- }
213
-
214
- /**
215
- * When path is used, it references the given property of the referenced element.
216
- * Valid paths are: 'element', 'content', 'meta', 'attributes'.
217
- */
218
- const referencedElementPath = (0, _apidomCore.toValue)(refElement.path);
219
- if (referencedElementPath !== 'element' && (0, _apidomDatamodel.isElement)(referencedElement)) {
220
- referencedElement = (0, _apidomDatamodel.refract)(referencedElement[referencedElementPath]);
221
- }
222
-
223
- /**
224
- * Transclusion of a Ref Element SHALL be defined in the if/else block below.
225
- */
226
- // ancestors[0] is the grandparent (nearest ancestor from getAncestorNodes())
227
- const grandparent = ancestors[0];
228
- if ((0, _apidomDatamodel.isObjectElement)(referencedElement) && (0, _apidomDatamodel.isObjectElement)(grandparent) && Array.isArray(parent) && typeof key === 'number') {
229
- /**
230
- * If the Ref Element is held by an Object Element and references an Object Element,
231
- * its content entries SHALL be inserted in place of the Ref Element.
232
- */
233
- parent.splice(key, 1, ...referencedElement.content);
234
- } else if ((0, _apidomDatamodel.isArrayElement)(referencedElement) && Array.isArray(parent) && typeof key === 'number') {
235
- /**
236
- * If the Ref Element is held by an Array Element and references an Array Element,
237
- * its content entries SHALL be inserted in place of the Ref Element.
238
- */
239
- parent.splice(key, 1, ...referencedElement.content);
240
- } else if ((0, _apidomDatamodel.isMemberElement)(parent)) {
241
- /**
242
- * The Ref Element is substituted by the Element it references.
243
- */
244
- parent.value = referencedElement;
245
- } else if (Array.isArray(parent)) {
246
- /**
247
- * The Ref Element is substituted by the Element it references.
248
- */
249
- parent[key] = referencedElement;
250
- }
251
- if (!parent) {
252
- path.replaceWith(referencedElement);
253
- }
254
- } catch (error) {
255
- this.handleError(`Error while dereferencing Ref Element. Cannot resolve ref "${refURI}": ${error.message}`, error, refElement, null, refURI, path);
256
- }
257
- }
258
- }
259
- var _default = exports.default = ApiDOMDereferenceVisitor;
@@ -1,252 +0,0 @@
1
- import { propEq } from 'ramda';
2
- import { ApiDOMStructuredError } from '@speclynx/apidom-error';
3
- import { isElement, isMemberElement, isArrayElement, isObjectElement, isRefElement, refract, cloneDeep } from '@speclynx/apidom-datamodel';
4
- import { toValue, toYAML } from '@speclynx/apidom-core';
5
- import { traverse, traverseAsync } from '@speclynx/apidom-traverse';
6
- import { URIFragmentIdentifier } from '@speclynx/apidom-json-pointer';
7
- import MaximumResolveDepthError from "../../../errors/MaximumResolveDepthError.mjs";
8
- import UnresolvableReferenceError from "../../../errors/UnresolvableReferenceError.mjs";
9
- import * as url from "../../../util/url.mjs";
10
- import parse from "../../../parse/index.mjs";
11
- import Reference from "../../../Reference.mjs";
12
- import { evaluate } from "./selectors/element-id.mjs";
13
- /**
14
- * The following rules apply:
15
- *
16
- * 1. When referencing an element in the local document, the id of the element MAY be used
17
- * 2. When referencing remote elements, an absolute URL or relative URL MAY be used
18
- * 3. When a URL fragment exists in the URL given, it references the element with the matching id in the given document. The URL fragment MAY need to be URL decoded before making a match.
19
- * 4. When a URL fragment does not exist, the URL references the root element
20
- * 5. When path is used, it references the given property of the referenced element
21
- * 6. When path is used in an element that includes the data of the pointer (such as with ref), the referenced path MAY need to be converted to a refract structure in order to be valid
22
- *
23
- * WARNING: this implementation only supports referencing elements in the local document. Points 2-4 are not supported.
24
- * @public
25
- */
26
- /**
27
- * @public
28
- */
29
- class ApiDOMDereferenceVisitor {
30
- reference;
31
- options;
32
- constructor({
33
- reference,
34
- options
35
- }) {
36
- this.reference = reference;
37
- this.options = options;
38
- }
39
- toBaseURI(uri) {
40
- return url.resolve(this.reference.uri, url.sanitize(url.stripHash(uri)));
41
- }
42
- async toReference(uri) {
43
- // detect maximum depth of resolution
44
- if (this.reference.depth >= this.options.resolve.maxDepth) {
45
- throw new MaximumResolveDepthError(`Maximum resolution depth of ${this.options.resolve.maxDepth} has been exceeded by file "${this.reference.uri}"`, {
46
- maxDepth: this.options.resolve.maxDepth,
47
- uri: this.reference.uri
48
- });
49
- }
50
- const baseURI = this.toBaseURI(uri);
51
- const {
52
- refSet
53
- } = this.reference;
54
-
55
- // we've already processed this Reference in past
56
- if (refSet.has(baseURI)) {
57
- return refSet.find(propEq(baseURI, 'uri'));
58
- }
59
- const parseResult = await parse(url.unsanitize(baseURI), {
60
- ...this.options,
61
- parse: {
62
- ...this.options.parse,
63
- mediaType: 'text/plain'
64
- }
65
- });
66
-
67
- // register new mutable reference with a refSet
68
- const mutableReference = new Reference({
69
- uri: baseURI,
70
- value: cloneDeep(parseResult),
71
- depth: this.reference.depth + 1
72
- });
73
- refSet.add(mutableReference);
74
- if (this.options.dereference.immutable) {
75
- // register new immutable reference with a refSet
76
- const immutableReference = new Reference({
77
- uri: `immutable://${baseURI}`,
78
- value: parseResult,
79
- depth: this.reference.depth + 1
80
- });
81
- refSet.add(immutableReference);
82
- }
83
- return mutableReference;
84
- }
85
-
86
- /**
87
- * Handles an error according to the continueOnError option.
88
- *
89
- * For new errors: wraps in UnresolvableReferenceError with structured context.
90
- * For errors already wrapped by a nested visitor: prepends the current hop to the trace.
91
- *
92
- * Inner/intermediate visitors always throw to let the trace accumulate.
93
- * Only the entry document visitor respects continueOnError (callback/swallow/throw).
94
- */
95
- handleError(message, error, referencingElement, refFieldName, refFieldValue, visitorPath) {
96
- const {
97
- continueOnError
98
- } = this.options.dereference;
99
- const isEntryDocument = url.stripHash(this.reference.refSet?.rootRef?.uri ?? '') === this.reference.uri;
100
- const uri = this.reference.uri;
101
- const type = referencingElement.element;
102
- let location;
103
- traverse(this.reference.value.result, {
104
- enter(p) {
105
- if (p.node === referencingElement) {
106
- location = p.formatPath();
107
- p.stop();
108
- }
109
- }
110
- });
111
- location ??= visitorPath.formatPath();
112
- const codeFrame = toYAML(referencingElement);
113
- const hop = {
114
- uri,
115
- type,
116
- refFieldName,
117
- refFieldValue,
118
- location,
119
- codeFrame
120
- };
121
- let unresolvedError;
122
- if (error instanceof UnresolvableReferenceError) {
123
- const refBaseURI = this.toBaseURI(refFieldValue);
124
- const fragment = URIFragmentIdentifier.fromURIReference(refFieldValue);
125
- if (fragment) {
126
- if (refBaseURI === error.uri && error.location) {
127
- error.location = fragment + error.location;
128
- }
129
- for (const h of error.trace) {
130
- if (h.uri === refBaseURI && h.location) h.location = fragment + h.location;
131
- }
132
- }
133
- // @ts-ignore
134
- error.trace = [hop, ...error.trace];
135
- unresolvedError = error;
136
- } else {
137
- unresolvedError = new UnresolvableReferenceError(message, {
138
- cause: error,
139
- type,
140
- uri,
141
- location,
142
- codeFrame,
143
- refFieldName,
144
- refFieldValue,
145
- trace: []
146
- });
147
- }
148
- if (!isEntryDocument || continueOnError === false) throw unresolvedError;
149
- if (typeof continueOnError === 'function') continueOnError(unresolvedError);
150
- }
151
- async RefElement(path) {
152
- const refElement = path.node;
153
- const {
154
- parent,
155
- key
156
- } = path;
157
- const ancestors = path.getAncestorNodes();
158
- const refURI = toValue(refElement);
159
- const refNormalizedURI = refURI.includes('#') ? refURI : `#${refURI}`;
160
- const retrievalURI = this.toBaseURI(refNormalizedURI);
161
- const isInternalReference = url.stripHash(this.reference.uri) === retrievalURI;
162
- const isExternalReference = !isInternalReference;
163
-
164
- // ignore resolving internal RefElements
165
- if (!this.options.resolve.internal && isInternalReference) {
166
- // skip traversing this ref element
167
- path.skip();
168
- return;
169
- }
170
- // ignore resolving external RefElements
171
- if (!this.options.resolve.external && isExternalReference) {
172
- // skip traversing this ref element
173
- path.skip();
174
- return;
175
- }
176
- try {
177
- const reference = await this.toReference(refNormalizedURI);
178
- const refBaseURI = url.resolve(retrievalURI, refNormalizedURI);
179
- const elementID = URIFragmentIdentifier.fromURIReference(refBaseURI);
180
- let referencedElement = evaluate(elementID, reference.value.result);
181
- if (!isElement(referencedElement)) {
182
- throw new ApiDOMStructuredError(`Referenced element with id="${elementID}" was not found`, {
183
- elementID
184
- });
185
- }
186
- if (refElement === referencedElement) {
187
- throw new ApiDOMStructuredError(`RefElement with id="${elementID}" cannot reference itself`, {
188
- elementID
189
- });
190
- }
191
- if (isRefElement(referencedElement)) {
192
- throw new ApiDOMStructuredError(`RefElement with id="${elementID}" cannot reference another RefElement`, {
193
- elementID
194
- });
195
- }
196
- if (isExternalReference) {
197
- // dive deep into the fragment
198
- const visitor = new ApiDOMDereferenceVisitor({
199
- reference,
200
- options: this.options
201
- });
202
- referencedElement = await traverseAsync(referencedElement, visitor, {
203
- mutable: true
204
- });
205
- }
206
-
207
- /**
208
- * When path is used, it references the given property of the referenced element.
209
- * Valid paths are: 'element', 'content', 'meta', 'attributes'.
210
- */
211
- const referencedElementPath = toValue(refElement.path);
212
- if (referencedElementPath !== 'element' && isElement(referencedElement)) {
213
- referencedElement = refract(referencedElement[referencedElementPath]);
214
- }
215
-
216
- /**
217
- * Transclusion of a Ref Element SHALL be defined in the if/else block below.
218
- */
219
- // ancestors[0] is the grandparent (nearest ancestor from getAncestorNodes())
220
- const grandparent = ancestors[0];
221
- if (isObjectElement(referencedElement) && isObjectElement(grandparent) && Array.isArray(parent) && typeof key === 'number') {
222
- /**
223
- * If the Ref Element is held by an Object Element and references an Object Element,
224
- * its content entries SHALL be inserted in place of the Ref Element.
225
- */
226
- parent.splice(key, 1, ...referencedElement.content);
227
- } else if (isArrayElement(referencedElement) && Array.isArray(parent) && typeof key === 'number') {
228
- /**
229
- * If the Ref Element is held by an Array Element and references an Array Element,
230
- * its content entries SHALL be inserted in place of the Ref Element.
231
- */
232
- parent.splice(key, 1, ...referencedElement.content);
233
- } else if (isMemberElement(parent)) {
234
- /**
235
- * The Ref Element is substituted by the Element it references.
236
- */
237
- parent.value = referencedElement;
238
- } else if (Array.isArray(parent)) {
239
- /**
240
- * The Ref Element is substituted by the Element it references.
241
- */
242
- parent[key] = referencedElement;
243
- }
244
- if (!parent) {
245
- path.replaceWith(referencedElement);
246
- }
247
- } catch (error) {
248
- this.handleError(`Error while dereferencing Ref Element. Cannot resolve ref "${refURI}": ${error.message}`, error, refElement, null, refURI, path);
249
- }
250
- }
251
- }
252
- export default ApiDOMDereferenceVisitor;
@@ -1,109 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
- exports.__esModule = true;
5
- exports.resolveSchema$refField = exports.resolveSchema$idField = exports.maybeRefractToJSONSchemaElement = exports.default = void 0;
6
- var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
- var _apidomTraverse = require("@speclynx/apidom-traverse");
8
- var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
9
- var _DereferenceStrategy = _interopRequireDefault(require("../DereferenceStrategy.cjs"));
10
- var _Reference = _interopRequireDefault(require("../../../Reference.cjs"));
11
- var _ReferenceSet = _interopRequireDefault(require("../../../ReferenceSet.cjs"));
12
- var _visitor = _interopRequireDefault(require("./visitor.cjs"));
13
- exports.Arazzo1DereferenceVisitor = _visitor.default;
14
- var _sourceDescriptions = require("./source-descriptions.cjs");
15
- exports.dereferenceSourceDescriptions = _sourceDescriptions.dereferenceSourceDescriptions;
16
- var _util = require("./util.cjs");
17
- exports.resolveSchema$refField = _util.resolveSchema$refField;
18
- exports.resolveSchema$idField = _util.resolveSchema$idField;
19
- exports.maybeRefractToJSONSchemaElement = _util.maybeRefractToJSONSchemaElement;
20
- /**
21
- * @public
22
- */
23
-
24
- /**
25
- * @public
26
- */
27
- class Arazzo1DereferenceStrategy extends _DereferenceStrategy.default {
28
- constructor(options) {
29
- super({
30
- ...(options ?? {}),
31
- name: 'arazzo-1'
32
- });
33
- }
34
- canDereference(file) {
35
- // assert by media type
36
- if (file.mediaType !== 'text/plain') {
37
- return _apidomNsArazzo.mediaTypes.includes(file.mediaType);
38
- }
39
-
40
- // assert by inspecting ApiDOM
41
- return (0, _apidomNsArazzo.isArazzoSpecification1Element)(file.parseResult?.result);
42
- }
43
- async dereference(file, options) {
44
- const immutableRefSet = options.dereference.refSet ?? new _ReferenceSet.default();
45
- const mutableRefSet = new _ReferenceSet.default();
46
- let refSet = immutableRefSet;
47
- let reference;
48
- if (!immutableRefSet.has(file.uri)) {
49
- reference = new _Reference.default({
50
- uri: file.uri,
51
- value: file.parseResult
52
- });
53
- immutableRefSet.add(reference);
54
- } else {
55
- // pre-computed refSet was provided as configuration option
56
- reference = immutableRefSet.find(ref => ref.uri === file.uri);
57
- }
58
-
59
- /**
60
- * Clone refSet due the dereferencing process being mutable.
61
- * We don't want to mutate the original refSet and the references.
62
- */
63
- if (options.dereference.immutable) {
64
- immutableRefSet.refs.map(ref => new _Reference.default({
65
- ...ref,
66
- value: (0, _apidomDatamodel.cloneDeep)(ref.value)
67
- })).forEach(ref => mutableRefSet.add(ref));
68
- reference = mutableRefSet.find(ref => ref.uri === file.uri);
69
- refSet = mutableRefSet;
70
- }
71
- const visitor = new _visitor.default({
72
- reference,
73
- options
74
- });
75
- const dereferencedElement = await (0, _apidomTraverse.traverseAsync)(refSet.rootRef.value, visitor, {
76
- mutable: true
77
- });
78
-
79
- /**
80
- * Dereference source descriptions if option is enabled.
81
- */
82
- const shouldDereferenceSourceDescriptions = options?.dereference?.strategyOpts?.[this.name]?.sourceDescriptions ?? options?.dereference?.strategyOpts?.sourceDescriptions;
83
- if (shouldDereferenceSourceDescriptions) {
84
- const sourceDescriptions = await (0, _sourceDescriptions.dereferenceSourceDescriptions)(dereferencedElement, reference.uri, options, this.name);
85
- dereferencedElement.push(...sourceDescriptions);
86
- }
87
-
88
- /**
89
- * If immutable option is set, replay refs from the refSet.
90
- */
91
- if (options.dereference.immutable) {
92
- mutableRefSet.refs.filter(ref => ref.uri.startsWith('immutable://')).map(ref => new _Reference.default({
93
- ...ref,
94
- uri: ref.uri.replace(/^immutable:\/\//, '')
95
- })).forEach(ref => immutableRefSet.add(ref));
96
- }
97
-
98
- /**
99
- * Release all memory if this refSet was not provided as a configuration option.
100
- * If provided as configuration option, then provider is responsible for cleanup.
101
- */
102
- if (options.dereference.refSet === null) {
103
- immutableRefSet.clean();
104
- }
105
- mutableRefSet.clean();
106
- return dereferencedElement;
107
- }
108
- }
109
- var _default = exports.default = Arazzo1DereferenceStrategy;