@speclynx/apidom-reference 3.2.1 → 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 +12 -0
  2. package/dist/apidom-reference.browser.js +40 -36
  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 -266
  36. package/src/dereference/strategies/apidom/visitor.mjs +0 -259
  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 -507
  48. package/src/dereference/strategies/arazzo-1/visitor.mjs +0 -500
  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 -501
  52. package/src/dereference/strategies/asyncapi-2/visitor.mjs +0 -494
  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 -629
  56. package/src/dereference/strategies/openapi-2/visitor.mjs +0 -622
  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 -621
  60. package/src/dereference/strategies/openapi-3-0/visitor.mjs +0 -614
  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 -873
  70. package/src/dereference/strategies/openapi-3-1/visitor.mjs +0 -866
  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,100 +0,0 @@
1
- import { cloneDeep } from '@speclynx/apidom-datamodel';
2
- import { traverseAsync } from '@speclynx/apidom-traverse';
3
- import { isArazzoSpecification1Element, mediaTypes } from '@speclynx/apidom-ns-arazzo-1';
4
- import DereferenceStrategy from "../DereferenceStrategy.mjs";
5
- import Reference from "../../../Reference.mjs";
6
- import ReferenceSet from "../../../ReferenceSet.mjs";
7
- import Arazzo1DereferenceVisitor from "./visitor.mjs";
8
- import { dereferenceSourceDescriptions } from "./source-descriptions.mjs";
9
- /**
10
- * @public
11
- */
12
- /**
13
- * @public
14
- */
15
- class Arazzo1DereferenceStrategy extends DereferenceStrategy {
16
- constructor(options) {
17
- super({
18
- ...(options ?? {}),
19
- name: 'arazzo-1'
20
- });
21
- }
22
- canDereference(file) {
23
- // assert by media type
24
- if (file.mediaType !== 'text/plain') {
25
- return mediaTypes.includes(file.mediaType);
26
- }
27
-
28
- // assert by inspecting ApiDOM
29
- return isArazzoSpecification1Element(file.parseResult?.result);
30
- }
31
- async dereference(file, options) {
32
- const immutableRefSet = options.dereference.refSet ?? new ReferenceSet();
33
- const mutableRefSet = new ReferenceSet();
34
- let refSet = immutableRefSet;
35
- let reference;
36
- if (!immutableRefSet.has(file.uri)) {
37
- reference = new Reference({
38
- uri: file.uri,
39
- value: file.parseResult
40
- });
41
- immutableRefSet.add(reference);
42
- } else {
43
- // pre-computed refSet was provided as configuration option
44
- reference = immutableRefSet.find(ref => ref.uri === file.uri);
45
- }
46
-
47
- /**
48
- * Clone refSet due the dereferencing process being mutable.
49
- * We don't want to mutate the original refSet and the references.
50
- */
51
- if (options.dereference.immutable) {
52
- immutableRefSet.refs.map(ref => new Reference({
53
- ...ref,
54
- value: cloneDeep(ref.value)
55
- })).forEach(ref => mutableRefSet.add(ref));
56
- reference = mutableRefSet.find(ref => ref.uri === file.uri);
57
- refSet = mutableRefSet;
58
- }
59
- const visitor = new Arazzo1DereferenceVisitor({
60
- reference,
61
- options
62
- });
63
- const dereferencedElement = await traverseAsync(refSet.rootRef.value, visitor, {
64
- mutable: true
65
- });
66
-
67
- /**
68
- * Dereference source descriptions if option is enabled.
69
- */
70
- const shouldDereferenceSourceDescriptions = options?.dereference?.strategyOpts?.[this.name]?.sourceDescriptions ?? options?.dereference?.strategyOpts?.sourceDescriptions;
71
- if (shouldDereferenceSourceDescriptions) {
72
- const sourceDescriptions = await dereferenceSourceDescriptions(dereferencedElement, reference.uri, options, this.name);
73
- dereferencedElement.push(...sourceDescriptions);
74
- }
75
-
76
- /**
77
- * If immutable option is set, replay refs from the refSet.
78
- */
79
- if (options.dereference.immutable) {
80
- mutableRefSet.refs.filter(ref => ref.uri.startsWith('immutable://')).map(ref => new Reference({
81
- ...ref,
82
- uri: ref.uri.replace(/^immutable:\/\//, '')
83
- })).forEach(ref => immutableRefSet.add(ref));
84
- }
85
-
86
- /**
87
- * Release all memory if this refSet was not provided as a configuration option.
88
- * If provided as configuration option, then provider is responsible for cleanup.
89
- */
90
- if (options.dereference.refSet === null) {
91
- immutableRefSet.clean();
92
- }
93
- mutableRefSet.clean();
94
- return dereferencedElement;
95
- }
96
- }
97
- export { Arazzo1DereferenceVisitor };
98
- export { resolveSchema$refField, resolveSchema$idField, maybeRefractToJSONSchemaElement } from "./util.mjs";
99
- export { dereferenceSourceDescriptions } from "./source-descriptions.mjs";
100
- export default Arazzo1DereferenceStrategy;
@@ -1,12 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.uriToAnchor = exports.parse = exports.isAnchor = exports.evaluate = exports.JsonSchema$anchorError = exports.InvalidJsonSchema$anchorError = exports.EvaluationJsonSchema$anchorError = void 0;
5
- var _$anchor = require("../../openapi-3-1/selectors/$anchor.cjs");
6
- exports.isAnchor = _$anchor.isAnchor;
7
- exports.uriToAnchor = _$anchor.uriToAnchor;
8
- exports.parse = _$anchor.parse;
9
- exports.evaluate = _$anchor.evaluate;
10
- exports.EvaluationJsonSchema$anchorError = _$anchor.EvaluationJsonSchema$anchorError;
11
- exports.InvalidJsonSchema$anchorError = _$anchor.InvalidJsonSchema$anchorError;
12
- exports.JsonSchema$anchorError = _$anchor.JsonSchema$anchorError;
@@ -1 +0,0 @@
1
- export { isAnchor, uriToAnchor, parse, evaluate, EvaluationJsonSchema$anchorError, InvalidJsonSchema$anchorError, JsonSchema$anchorError } from "../../openapi-3-1/selectors/$anchor.mjs";
@@ -1,8 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.evaluate = exports.JsonSchemaUriError = exports.EvaluationJsonSchemaUriError = void 0;
5
- var _uri = require("../../openapi-3-1/selectors/uri.cjs");
6
- exports.evaluate = _uri.evaluate;
7
- exports.EvaluationJsonSchemaUriError = _uri.EvaluationJsonSchemaUriError;
8
- exports.JsonSchemaUriError = _uri.JsonSchemaUriError;
@@ -1 +0,0 @@
1
- export { evaluate, EvaluationJsonSchemaUriError, JsonSchemaUriError } from "../../openapi-3-1/selectors/uri.mjs";
@@ -1,248 +0,0 @@
1
- "use strict";
2
-
3
- var _interopRequireWildcard = require("@babel/runtime-corejs3/helpers/interopRequireWildcard").default;
4
- exports.__esModule = true;
5
- exports.dereferenceSourceDescriptions = dereferenceSourceDescriptions;
6
- var _apidomDatamodel = require("@speclynx/apidom-datamodel");
7
- var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
8
- var _apidomNsOpenapi = require("@speclynx/apidom-ns-openapi-2");
9
- var _apidomNsOpenapi2 = require("@speclynx/apidom-ns-openapi-3-0");
10
- var _apidomNsOpenapi3 = require("@speclynx/apidom-ns-openapi-3-1");
11
- var _apidomCore = require("@speclynx/apidom-core");
12
- var url = _interopRequireWildcard(require("../../../util/url.cjs"));
13
- var _util = require("../../../options/util.cjs");
14
- var _index = _interopRequireWildcard(require("../../index.cjs"));
15
- /**
16
- * Dereferences a single source description element.
17
- * Returns ParseResultElement on success, or with annotation if skipped.
18
- */
19
- async function dereferenceSourceDescription(sourceDescription, ctx) {
20
- const parseResult = new _apidomDatamodel.ParseResultElement();
21
- if (!(0, _apidomNsArazzo.isSourceDescriptionElement)(sourceDescription)) {
22
- const annotation = new _apidomDatamodel.AnnotationElement('Element is not a valid SourceDescriptionElement. Skipping');
23
- annotation.classes.push('warning');
24
- parseResult.push(annotation);
25
- return parseResult;
26
- }
27
-
28
- // set class and metadata from source description element
29
- parseResult.classes.push('source-description');
30
- if ((0, _apidomDatamodel.isStringElement)(sourceDescription.name)) parseResult.setMetaProperty('name', (0, _apidomCore.toValue)(sourceDescription.name));
31
- if ((0, _apidomDatamodel.isStringElement)(sourceDescription.type)) parseResult.setMetaProperty('type', (0, _apidomCore.toValue)(sourceDescription.type));
32
- const sourceDescriptionURI = (0, _apidomCore.toValue)(sourceDescription.url);
33
- if (typeof sourceDescriptionURI !== 'string') {
34
- const annotation = new _apidomDatamodel.AnnotationElement('Source description URL is missing or not a string. Skipping');
35
- annotation.classes.push('warning');
36
- parseResult.push(annotation);
37
- return parseResult;
38
- }
39
-
40
- // normalize URI for consistent cycle detection and refSet cache key matching
41
- const retrievalURI = url.sanitize(url.stripHash(url.resolve(ctx.baseURI, sourceDescriptionURI)));
42
- parseResult.setMetaProperty('retrievalURI', retrievalURI);
43
-
44
- // skip if already visited (cycle detection)
45
- if (ctx.visitedUrls.has(retrievalURI)) {
46
- const annotation = new _apidomDatamodel.AnnotationElement(`Source description "${retrievalURI}" has already been visited. Skipping to prevent cycle`);
47
- annotation.classes.push('warning');
48
- parseResult.push(annotation);
49
- return parseResult;
50
- }
51
- ctx.visitedUrls.add(retrievalURI);
52
-
53
- // check if source description was already parsed (e.g., during parse phase with sourceDescriptions: true)
54
- const existingParseResult = sourceDescription.meta.get('parseResult');
55
- try {
56
- let sourceDescriptionDereferenced;
57
- if ((0, _apidomDatamodel.isParseResultElement)(existingParseResult)) {
58
- // use existing parsed result - just dereference it (no re-fetch/re-parse)
59
- sourceDescriptionDereferenced = await (0, _index.dereferenceApiDOM)(existingParseResult, (0, _util.merge)(ctx.options, {
60
- parse: {
61
- mediaType: 'text/plain' // allow dereference strategy detection via ApiDOM inspection
62
- },
63
- resolve: {
64
- baseURI: retrievalURI
65
- },
66
- dereference: {
67
- strategyOpts: {
68
- // nested documents should dereference all their source descriptions
69
- // (parent's name filter doesn't apply to nested documents)
70
- // set at strategy-specific level to override any inherited filters
71
- [ctx.strategyName]: {
72
- sourceDescriptions: true,
73
- sourceDescriptionsDepth: ctx.currentDepth + 1,
74
- sourceDescriptionsVisitedUrls: ctx.visitedUrls
75
- }
76
- }
77
- }
78
- }));
79
- } else {
80
- // no existing parse result - fetch, parse, and dereference
81
- sourceDescriptionDereferenced = await (0, _index.default)(retrievalURI, (0, _util.merge)(ctx.options, {
82
- parse: {
83
- mediaType: 'text/plain' // allow parser plugin detection
84
- },
85
- dereference: {
86
- strategyOpts: {
87
- // nested documents should dereference all their source descriptions
88
- // (parent's name filter doesn't apply to nested documents)
89
- // set at strategy-specific level to override any inherited filters
90
- [ctx.strategyName]: {
91
- sourceDescriptions: true,
92
- sourceDescriptionsDepth: ctx.currentDepth + 1,
93
- sourceDescriptionsVisitedUrls: ctx.visitedUrls
94
- }
95
- }
96
- }
97
- }));
98
- }
99
-
100
- // merge dereferenced result into our parse result
101
- for (const item of sourceDescriptionDereferenced) {
102
- parseResult.push(item);
103
- }
104
- } catch (error) {
105
- // create error annotation instead of failing entire dereference
106
- const message = error instanceof Error ? error.message : String(error);
107
- const annotation = new _apidomDatamodel.AnnotationElement(`Error dereferencing source description "${retrievalURI}": ${message}`);
108
- annotation.classes.push('error');
109
- parseResult.push(annotation);
110
- return parseResult;
111
- }
112
-
113
- // only allow OpenAPI and Arazzo as source descriptions
114
- const {
115
- api: sourceDescriptionAPI
116
- } = parseResult;
117
- const isOpenApi = (0, _apidomNsOpenapi.isSwaggerElement)(sourceDescriptionAPI) || (0, _apidomNsOpenapi2.isOpenApi3_0Element)(sourceDescriptionAPI) || (0, _apidomNsOpenapi3.isOpenApi3_1Element)(sourceDescriptionAPI);
118
- const isArazzo = (0, _apidomNsArazzo.isArazzoSpecification1Element)(sourceDescriptionAPI);
119
- if (!isOpenApi && !isArazzo) {
120
- const annotation = new _apidomDatamodel.AnnotationElement(`Source description "${retrievalURI}" is not an OpenAPI or Arazzo document`);
121
- annotation.classes.push('warning');
122
- parseResult.push(annotation);
123
- return parseResult;
124
- }
125
-
126
- // validate declared type matches actual dereferenced type
127
- const declaredType = (0, _apidomCore.toValue)(sourceDescription.type);
128
- if (typeof declaredType === 'string') {
129
- if (declaredType === 'openapi' && !isOpenApi) {
130
- const annotation = new _apidomDatamodel.AnnotationElement(`Source description "${retrievalURI}" declared as "openapi" but dereferenced as Arazzo document`);
131
- annotation.classes.push('warning');
132
- parseResult.push(annotation);
133
- } else if (declaredType === 'arazzo' && !isArazzo) {
134
- const annotation = new _apidomDatamodel.AnnotationElement(`Source description "${retrievalURI}" declared as "arazzo" but dereferenced as OpenAPI document`);
135
- annotation.classes.push('warning');
136
- parseResult.push(annotation);
137
- }
138
- }
139
- return parseResult;
140
- }
141
-
142
- /**
143
- * Dereferences source descriptions from an Arazzo document.
144
- *
145
- * Each source description result is attached to its corresponding
146
- * SourceDescriptionElement's meta as 'parseResult' for easy access,
147
- * regardless of success or failure. On failure, the ParseResultElement
148
- * contains annotations explaining what went wrong.
149
- *
150
- * @param parseResult - ParseResult containing a parsed (optionally dereferenced) Arazzo specification
151
- * @param parseResultRetrievalURI - URI from which the parseResult was retrieved
152
- * @param options - Full ReferenceOptions. Pass `sourceDescriptions` as an array of names
153
- * in `dereference.strategyOpts` to filter which source descriptions to process.
154
- * @param strategyName - Strategy name for options lookup (defaults to 'arazzo-1')
155
- * @returns Array of ParseResultElements. Returns one ParseResultElement per source description
156
- * (each with class 'source-description' and metadata: name, type, retrievalURI).
157
- * May return early with a single-element array containing a warning annotation when:
158
- * - The API is not an Arazzo specification
159
- * - The sourceDescriptions field is missing or not an array
160
- * - Maximum dereference depth is exceeded (error annotation)
161
- * Returns an empty array when no source description names match the filter.
162
- *
163
- * @example
164
- * ```typescript
165
- * import { toValue } from '@speclynx/apidom-core';
166
- *
167
- * // Dereference all source descriptions
168
- * await dereferenceSourceDescriptions(parseResult, uri, options);
169
- *
170
- * // Filter by name
171
- * await dereferenceSourceDescriptions(parseResult, uri, mergeOptions(options, {
172
- * dereference: { strategyOpts: { sourceDescriptions: ['petStore'] } },
173
- * }));
174
- *
175
- * // Access dereferenced document from source description element
176
- * const sourceDesc = parseResult.api.sourceDescriptions.get(0);
177
- * const dereferencedDoc = sourceDesc.meta.get('parseResult');
178
- * const retrievalURI = toValue(dereferencedDoc.meta.get('retrievalURI'));
179
- * ```
180
- *
181
- * @public
182
- */
183
- async function dereferenceSourceDescriptions(parseResult, parseResultRetrievalURI, options, strategyName = 'arazzo-1') {
184
- const baseURI = url.sanitize(url.stripHash(parseResultRetrievalURI));
185
- const results = [];
186
-
187
- // get API from dereferenced parse result
188
- const {
189
- api
190
- } = parseResult;
191
-
192
- /**
193
- * Validate prerequisites for dereferencing source descriptions.
194
- * Return warning annotations if validation fails.
195
- */
196
- if (!(0, _apidomNsArazzo.isArazzoSpecification1Element)(api)) {
197
- const annotation = new _apidomDatamodel.AnnotationElement('Cannot dereference source descriptions: API is not an Arazzo specification');
198
- annotation.classes.push('warning');
199
- return [new _apidomDatamodel.ParseResultElement([annotation])];
200
- }
201
- if (!(0, _apidomDatamodel.isArrayElement)(api.sourceDescriptions)) {
202
- const annotation = new _apidomDatamodel.AnnotationElement('Cannot dereference source descriptions: sourceDescriptions field is missing or not an array');
203
- annotation.classes.push('warning');
204
- return [new _apidomDatamodel.ParseResultElement([annotation])];
205
- }
206
-
207
- // user config: strategy-specific options take precedence over global strategyOpts
208
- const maxDepth = options?.dereference?.strategyOpts?.[strategyName]?.sourceDescriptionsMaxDepth ?? options?.dereference?.strategyOpts?.sourceDescriptionsMaxDepth ?? +Infinity;
209
-
210
- // recursion state comes from strategy-specific options
211
- const sharedOpts = options?.dereference?.strategyOpts?.[strategyName] ?? {};
212
- const currentDepth = sharedOpts.sourceDescriptionsDepth ?? 0;
213
- const visitedUrls = sharedOpts.sourceDescriptionsVisitedUrls ?? new Set();
214
-
215
- // add current file to visited URLs to prevent cycles
216
- visitedUrls.add(baseURI);
217
- if (currentDepth >= maxDepth) {
218
- const annotation = new _apidomDatamodel.AnnotationElement(`Maximum dereference depth of ${maxDepth} has been exceeded by file "${baseURI}"`);
219
- annotation.classes.push('error');
220
- const parseResult = new _apidomDatamodel.ParseResultElement([annotation]);
221
- parseResult.classes.push('source-description');
222
- return [parseResult];
223
- }
224
- const ctx = {
225
- baseURI,
226
- options,
227
- strategyName,
228
- currentDepth,
229
- visitedUrls
230
- };
231
-
232
- // determine which source descriptions to dereference (array filters by name)
233
- const sourceDescriptionsOption = options?.dereference?.strategyOpts?.[strategyName]?.sourceDescriptions ?? options?.dereference?.strategyOpts?.sourceDescriptions;
234
- const sourceDescriptions = Array.isArray(sourceDescriptionsOption) ? api.sourceDescriptions.filter(sd => {
235
- if (!(0, _apidomNsArazzo.isSourceDescriptionElement)(sd)) return false;
236
- const name = (0, _apidomCore.toValue)(sd.name);
237
- return typeof name === 'string' && sourceDescriptionsOption.includes(name);
238
- }) : api.sourceDescriptions;
239
-
240
- // process sequentially to ensure proper cycle detection with shared visitedUrls
241
- for (const sourceDescription of sourceDescriptions) {
242
- const sourceDescriptionDereferenceResult = await dereferenceSourceDescription(sourceDescription, ctx);
243
- // always attach result (even on failure - contains annotations)
244
- sourceDescription.meta.set('parseResult', sourceDescriptionDereferenceResult);
245
- results.push(sourceDescriptionDereferenceResult);
246
- }
247
- return results;
248
- }
@@ -1,243 +0,0 @@
1
- import { ParseResultElement, AnnotationElement, isArrayElement, isStringElement, isParseResultElement } from '@speclynx/apidom-datamodel';
2
- import { isArazzoSpecification1Element, isSourceDescriptionElement } from '@speclynx/apidom-ns-arazzo-1';
3
- import { isSwaggerElement } from '@speclynx/apidom-ns-openapi-2';
4
- import { isOpenApi3_0Element } from '@speclynx/apidom-ns-openapi-3-0';
5
- import { isOpenApi3_1Element } from '@speclynx/apidom-ns-openapi-3-1';
6
- import { toValue } from '@speclynx/apidom-core';
7
- import * as url from "../../../util/url.mjs";
8
- import { merge as mergeOptions } from "../../../options/util.mjs";
9
- import dereference, { dereferenceApiDOM } from "../../index.mjs";
10
- /**
11
- * Dereferences a single source description element.
12
- * Returns ParseResultElement on success, or with annotation if skipped.
13
- */
14
- async function dereferenceSourceDescription(sourceDescription, ctx) {
15
- const parseResult = new ParseResultElement();
16
- if (!isSourceDescriptionElement(sourceDescription)) {
17
- const annotation = new AnnotationElement('Element is not a valid SourceDescriptionElement. Skipping');
18
- annotation.classes.push('warning');
19
- parseResult.push(annotation);
20
- return parseResult;
21
- }
22
-
23
- // set class and metadata from source description element
24
- parseResult.classes.push('source-description');
25
- if (isStringElement(sourceDescription.name)) parseResult.setMetaProperty('name', toValue(sourceDescription.name));
26
- if (isStringElement(sourceDescription.type)) parseResult.setMetaProperty('type', toValue(sourceDescription.type));
27
- const sourceDescriptionURI = toValue(sourceDescription.url);
28
- if (typeof sourceDescriptionURI !== 'string') {
29
- const annotation = new AnnotationElement('Source description URL is missing or not a string. Skipping');
30
- annotation.classes.push('warning');
31
- parseResult.push(annotation);
32
- return parseResult;
33
- }
34
-
35
- // normalize URI for consistent cycle detection and refSet cache key matching
36
- const retrievalURI = url.sanitize(url.stripHash(url.resolve(ctx.baseURI, sourceDescriptionURI)));
37
- parseResult.setMetaProperty('retrievalURI', retrievalURI);
38
-
39
- // skip if already visited (cycle detection)
40
- if (ctx.visitedUrls.has(retrievalURI)) {
41
- const annotation = new AnnotationElement(`Source description "${retrievalURI}" has already been visited. Skipping to prevent cycle`);
42
- annotation.classes.push('warning');
43
- parseResult.push(annotation);
44
- return parseResult;
45
- }
46
- ctx.visitedUrls.add(retrievalURI);
47
-
48
- // check if source description was already parsed (e.g., during parse phase with sourceDescriptions: true)
49
- const existingParseResult = sourceDescription.meta.get('parseResult');
50
- try {
51
- let sourceDescriptionDereferenced;
52
- if (isParseResultElement(existingParseResult)) {
53
- // use existing parsed result - just dereference it (no re-fetch/re-parse)
54
- sourceDescriptionDereferenced = await dereferenceApiDOM(existingParseResult, mergeOptions(ctx.options, {
55
- parse: {
56
- mediaType: 'text/plain' // allow dereference strategy detection via ApiDOM inspection
57
- },
58
- resolve: {
59
- baseURI: retrievalURI
60
- },
61
- dereference: {
62
- strategyOpts: {
63
- // nested documents should dereference all their source descriptions
64
- // (parent's name filter doesn't apply to nested documents)
65
- // set at strategy-specific level to override any inherited filters
66
- [ctx.strategyName]: {
67
- sourceDescriptions: true,
68
- sourceDescriptionsDepth: ctx.currentDepth + 1,
69
- sourceDescriptionsVisitedUrls: ctx.visitedUrls
70
- }
71
- }
72
- }
73
- }));
74
- } else {
75
- // no existing parse result - fetch, parse, and dereference
76
- sourceDescriptionDereferenced = await dereference(retrievalURI, mergeOptions(ctx.options, {
77
- parse: {
78
- mediaType: 'text/plain' // allow parser plugin detection
79
- },
80
- dereference: {
81
- strategyOpts: {
82
- // nested documents should dereference all their source descriptions
83
- // (parent's name filter doesn't apply to nested documents)
84
- // set at strategy-specific level to override any inherited filters
85
- [ctx.strategyName]: {
86
- sourceDescriptions: true,
87
- sourceDescriptionsDepth: ctx.currentDepth + 1,
88
- sourceDescriptionsVisitedUrls: ctx.visitedUrls
89
- }
90
- }
91
- }
92
- }));
93
- }
94
-
95
- // merge dereferenced result into our parse result
96
- for (const item of sourceDescriptionDereferenced) {
97
- parseResult.push(item);
98
- }
99
- } catch (error) {
100
- // create error annotation instead of failing entire dereference
101
- const message = error instanceof Error ? error.message : String(error);
102
- const annotation = new AnnotationElement(`Error dereferencing source description "${retrievalURI}": ${message}`);
103
- annotation.classes.push('error');
104
- parseResult.push(annotation);
105
- return parseResult;
106
- }
107
-
108
- // only allow OpenAPI and Arazzo as source descriptions
109
- const {
110
- api: sourceDescriptionAPI
111
- } = parseResult;
112
- const isOpenApi = isSwaggerElement(sourceDescriptionAPI) || isOpenApi3_0Element(sourceDescriptionAPI) || isOpenApi3_1Element(sourceDescriptionAPI);
113
- const isArazzo = isArazzoSpecification1Element(sourceDescriptionAPI);
114
- if (!isOpenApi && !isArazzo) {
115
- const annotation = new AnnotationElement(`Source description "${retrievalURI}" is not an OpenAPI or Arazzo document`);
116
- annotation.classes.push('warning');
117
- parseResult.push(annotation);
118
- return parseResult;
119
- }
120
-
121
- // validate declared type matches actual dereferenced type
122
- const declaredType = toValue(sourceDescription.type);
123
- if (typeof declaredType === 'string') {
124
- if (declaredType === 'openapi' && !isOpenApi) {
125
- const annotation = new AnnotationElement(`Source description "${retrievalURI}" declared as "openapi" but dereferenced as Arazzo document`);
126
- annotation.classes.push('warning');
127
- parseResult.push(annotation);
128
- } else if (declaredType === 'arazzo' && !isArazzo) {
129
- const annotation = new AnnotationElement(`Source description "${retrievalURI}" declared as "arazzo" but dereferenced as OpenAPI document`);
130
- annotation.classes.push('warning');
131
- parseResult.push(annotation);
132
- }
133
- }
134
- return parseResult;
135
- }
136
-
137
- /**
138
- * Dereferences source descriptions from an Arazzo document.
139
- *
140
- * Each source description result is attached to its corresponding
141
- * SourceDescriptionElement's meta as 'parseResult' for easy access,
142
- * regardless of success or failure. On failure, the ParseResultElement
143
- * contains annotations explaining what went wrong.
144
- *
145
- * @param parseResult - ParseResult containing a parsed (optionally dereferenced) Arazzo specification
146
- * @param parseResultRetrievalURI - URI from which the parseResult was retrieved
147
- * @param options - Full ReferenceOptions. Pass `sourceDescriptions` as an array of names
148
- * in `dereference.strategyOpts` to filter which source descriptions to process.
149
- * @param strategyName - Strategy name for options lookup (defaults to 'arazzo-1')
150
- * @returns Array of ParseResultElements. Returns one ParseResultElement per source description
151
- * (each with class 'source-description' and metadata: name, type, retrievalURI).
152
- * May return early with a single-element array containing a warning annotation when:
153
- * - The API is not an Arazzo specification
154
- * - The sourceDescriptions field is missing or not an array
155
- * - Maximum dereference depth is exceeded (error annotation)
156
- * Returns an empty array when no source description names match the filter.
157
- *
158
- * @example
159
- * ```typescript
160
- * import { toValue } from '@speclynx/apidom-core';
161
- *
162
- * // Dereference all source descriptions
163
- * await dereferenceSourceDescriptions(parseResult, uri, options);
164
- *
165
- * // Filter by name
166
- * await dereferenceSourceDescriptions(parseResult, uri, mergeOptions(options, {
167
- * dereference: { strategyOpts: { sourceDescriptions: ['petStore'] } },
168
- * }));
169
- *
170
- * // Access dereferenced document from source description element
171
- * const sourceDesc = parseResult.api.sourceDescriptions.get(0);
172
- * const dereferencedDoc = sourceDesc.meta.get('parseResult');
173
- * const retrievalURI = toValue(dereferencedDoc.meta.get('retrievalURI'));
174
- * ```
175
- *
176
- * @public
177
- */
178
- export async function dereferenceSourceDescriptions(parseResult, parseResultRetrievalURI, options, strategyName = 'arazzo-1') {
179
- const baseURI = url.sanitize(url.stripHash(parseResultRetrievalURI));
180
- const results = [];
181
-
182
- // get API from dereferenced parse result
183
- const {
184
- api
185
- } = parseResult;
186
-
187
- /**
188
- * Validate prerequisites for dereferencing source descriptions.
189
- * Return warning annotations if validation fails.
190
- */
191
- if (!isArazzoSpecification1Element(api)) {
192
- const annotation = new AnnotationElement('Cannot dereference source descriptions: API is not an Arazzo specification');
193
- annotation.classes.push('warning');
194
- return [new ParseResultElement([annotation])];
195
- }
196
- if (!isArrayElement(api.sourceDescriptions)) {
197
- const annotation = new AnnotationElement('Cannot dereference source descriptions: sourceDescriptions field is missing or not an array');
198
- annotation.classes.push('warning');
199
- return [new ParseResultElement([annotation])];
200
- }
201
-
202
- // user config: strategy-specific options take precedence over global strategyOpts
203
- const maxDepth = options?.dereference?.strategyOpts?.[strategyName]?.sourceDescriptionsMaxDepth ?? options?.dereference?.strategyOpts?.sourceDescriptionsMaxDepth ?? +Infinity;
204
-
205
- // recursion state comes from strategy-specific options
206
- const sharedOpts = options?.dereference?.strategyOpts?.[strategyName] ?? {};
207
- const currentDepth = sharedOpts.sourceDescriptionsDepth ?? 0;
208
- const visitedUrls = sharedOpts.sourceDescriptionsVisitedUrls ?? new Set();
209
-
210
- // add current file to visited URLs to prevent cycles
211
- visitedUrls.add(baseURI);
212
- if (currentDepth >= maxDepth) {
213
- const annotation = new AnnotationElement(`Maximum dereference depth of ${maxDepth} has been exceeded by file "${baseURI}"`);
214
- annotation.classes.push('error');
215
- const parseResult = new ParseResultElement([annotation]);
216
- parseResult.classes.push('source-description');
217
- return [parseResult];
218
- }
219
- const ctx = {
220
- baseURI,
221
- options,
222
- strategyName,
223
- currentDepth,
224
- visitedUrls
225
- };
226
-
227
- // determine which source descriptions to dereference (array filters by name)
228
- const sourceDescriptionsOption = options?.dereference?.strategyOpts?.[strategyName]?.sourceDescriptions ?? options?.dereference?.strategyOpts?.sourceDescriptions;
229
- const sourceDescriptions = Array.isArray(sourceDescriptionsOption) ? api.sourceDescriptions.filter(sd => {
230
- if (!isSourceDescriptionElement(sd)) return false;
231
- const name = toValue(sd.name);
232
- return typeof name === 'string' && sourceDescriptionsOption.includes(name);
233
- }) : api.sourceDescriptions;
234
-
235
- // process sequentially to ensure proper cycle detection with shared visitedUrls
236
- for (const sourceDescription of sourceDescriptions) {
237
- const sourceDescriptionDereferenceResult = await dereferenceSourceDescription(sourceDescription, ctx);
238
- // always attach result (even on failure - contains annotations)
239
- sourceDescription.meta.set('parseResult', sourceDescriptionDereferenceResult);
240
- results.push(sourceDescriptionDereferenceResult);
241
- }
242
- return results;
243
- }
@@ -1,37 +0,0 @@
1
- "use strict";
2
-
3
- exports.__esModule = true;
4
- exports.resolveSchema$refField = exports.resolveSchema$idField = exports.refractToJSONSchemaElement = exports.maybeRefractToJSONSchemaElement = void 0;
5
- var _apidomDatamodel = require("@speclynx/apidom-datamodel");
6
- var _apidomNsArazzo = require("@speclynx/apidom-ns-arazzo-1");
7
- var _util = require("../openapi-3-1/util.cjs");
8
- exports.resolveSchema$refField = _util.resolveSchema$refField;
9
- exports.resolveSchema$idField = _util.resolveSchema$idField;
10
- /**
11
- * Cached version of JSONSchemaElement.refract.
12
- */
13
- const refractToJSONSchemaElement = element => {
14
- if (refractToJSONSchemaElement.cache.has(element)) {
15
- return refractToJSONSchemaElement.cache.get(element);
16
- }
17
- const refracted = (0, _apidomNsArazzo.refractJSONSchema)(element);
18
- refractToJSONSchemaElement.cache.set(element, refracted);
19
- return refracted;
20
- };
21
- exports.refractToJSONSchemaElement = refractToJSONSchemaElement;
22
- refractToJSONSchemaElement.cache = new WeakMap();
23
-
24
- /**
25
- * @public
26
- */
27
- const maybeRefractToJSONSchemaElement = element => {
28
- /**
29
- * Conditional version of refractToJSONSchemaElement, that acts as an identity
30
- * function for all non-primitive Element instances.
31
- */
32
- if ((0, _apidomDatamodel.isPrimitiveElement)(element)) {
33
- return refractToJSONSchemaElement(element);
34
- }
35
- return element;
36
- };
37
- exports.maybeRefractToJSONSchemaElement = maybeRefractToJSONSchemaElement;