@speclynx/apidom-reference 1.12.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 (263) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/LICENSE +202 -0
  3. package/LICENSES/AFL-3.0.txt +182 -0
  4. package/LICENSES/Apache-2.0.txt +202 -0
  5. package/LICENSES/BSD-3-Clause.txt +26 -0
  6. package/LICENSES/MIT.txt +9 -0
  7. package/NOTICE +65 -0
  8. package/README.md +2107 -0
  9. package/dist/167.apidom-reference.browser.js +10 -0
  10. package/dist/167.apidom-reference.browser.min.js +1 -0
  11. package/dist/451.apidom-reference.browser.js +10 -0
  12. package/dist/451.apidom-reference.browser.min.js +1 -0
  13. package/dist/9786785aaddf11f37840fad896531940.wasm +0 -0
  14. package/dist/apidom-reference.browser.js +85376 -0
  15. package/dist/apidom-reference.browser.min.js +1 -0
  16. package/package.json +304 -0
  17. package/src/File.cjs +50 -0
  18. package/src/File.mjs +44 -0
  19. package/src/Reference.cjs +31 -0
  20. package/src/Reference.mjs +27 -0
  21. package/src/ReferenceSet.cjs +60 -0
  22. package/src/ReferenceSet.mjs +57 -0
  23. package/src/bundle/index.cjs +61 -0
  24. package/src/bundle/index.mjs +55 -0
  25. package/src/bundle/strategies/BundleStrategy.cjs +20 -0
  26. package/src/bundle/strategies/BundleStrategy.mjs +16 -0
  27. package/src/bundle/strategies/openapi-3-1/index.cjs +35 -0
  28. package/src/bundle/strategies/openapi-3-1/index.mjs +29 -0
  29. package/src/configuration/empty.cjs +9 -0
  30. package/src/configuration/empty.mjs +1 -0
  31. package/src/configuration/saturated.cjs +95 -0
  32. package/src/configuration/saturated.mjs +87 -0
  33. package/src/dereference/index.cjs +86 -0
  34. package/src/dereference/index.mjs +79 -0
  35. package/src/dereference/strategies/DereferenceStrategy.cjs +20 -0
  36. package/src/dereference/strategies/DereferenceStrategy.mjs +16 -0
  37. package/src/dereference/strategies/apidom/index.cjs +89 -0
  38. package/src/dereference/strategies/apidom/index.mjs +84 -0
  39. package/src/dereference/strategies/apidom/selectors/element-id.cjs +36 -0
  40. package/src/dereference/strategies/apidom/selectors/element-id.mjs +30 -0
  41. package/src/dereference/strategies/apidom/visitor.cjs +165 -0
  42. package/src/dereference/strategies/apidom/visitor.mjs +159 -0
  43. package/src/dereference/strategies/asyncapi-2/index.cjs +100 -0
  44. package/src/dereference/strategies/asyncapi-2/index.mjs +94 -0
  45. package/src/dereference/strategies/asyncapi-2/visitor.cjs +412 -0
  46. package/src/dereference/strategies/asyncapi-2/visitor.mjs +406 -0
  47. package/src/dereference/strategies/openapi-2/index.cjs +102 -0
  48. package/src/dereference/strategies/openapi-2/index.mjs +96 -0
  49. package/src/dereference/strategies/openapi-2/visitor.cjs +530 -0
  50. package/src/dereference/strategies/openapi-2/visitor.mjs +524 -0
  51. package/src/dereference/strategies/openapi-3-0/index.cjs +102 -0
  52. package/src/dereference/strategies/openapi-3-0/index.mjs +96 -0
  53. package/src/dereference/strategies/openapi-3-0/visitor.cjs +519 -0
  54. package/src/dereference/strategies/openapi-3-0/visitor.mjs +513 -0
  55. package/src/dereference/strategies/openapi-3-1/index.cjs +105 -0
  56. package/src/dereference/strategies/openapi-3-1/index.mjs +96 -0
  57. package/src/dereference/strategies/openapi-3-1/selectors/$anchor.cjs +66 -0
  58. package/src/dereference/strategies/openapi-3-1/selectors/$anchor.mjs +55 -0
  59. package/src/dereference/strategies/openapi-3-1/selectors/uri.cjs +50 -0
  60. package/src/dereference/strategies/openapi-3-1/selectors/uri.mjs +42 -0
  61. package/src/dereference/strategies/openapi-3-1/util.cjs +67 -0
  62. package/src/dereference/strategies/openapi-3-1/util.mjs +58 -0
  63. package/src/dereference/strategies/openapi-3-1/visitor.cjs +776 -0
  64. package/src/dereference/strategies/openapi-3-1/visitor.mjs +770 -0
  65. package/src/dereference/util.cjs +31 -0
  66. package/src/dereference/util.mjs +27 -0
  67. package/src/errors/BundleError.cjs +10 -0
  68. package/src/errors/BundleError.mjs +7 -0
  69. package/src/errors/DereferenceError.cjs +10 -0
  70. package/src/errors/DereferenceError.mjs +7 -0
  71. package/src/errors/EvaluationElementIdError.cjs +10 -0
  72. package/src/errors/EvaluationElementIdError.mjs +7 -0
  73. package/src/errors/EvaluationJsonSchema$anchorError.cjs +11 -0
  74. package/src/errors/EvaluationJsonSchema$anchorError.mjs +6 -0
  75. package/src/errors/EvaluationJsonSchemaUriError.cjs +11 -0
  76. package/src/errors/EvaluationJsonSchemaUriError.mjs +6 -0
  77. package/src/errors/InvalidJsonSchema$anchorError.cjs +15 -0
  78. package/src/errors/InvalidJsonSchema$anchorError.mjs +10 -0
  79. package/src/errors/JsonSchema$anchorError.cjs +10 -0
  80. package/src/errors/JsonSchema$anchorError.mjs +7 -0
  81. package/src/errors/JsonSchemaUriError.cjs +10 -0
  82. package/src/errors/JsonSchemaUriError.mjs +7 -0
  83. package/src/errors/MaximumBundleDepthError.cjs +11 -0
  84. package/src/errors/MaximumBundleDepthError.mjs +6 -0
  85. package/src/errors/MaximumDereferenceDepthError.cjs +11 -0
  86. package/src/errors/MaximumDereferenceDepthError.mjs +6 -0
  87. package/src/errors/MaximumResolveDepthError.cjs +11 -0
  88. package/src/errors/MaximumResolveDepthError.mjs +6 -0
  89. package/src/errors/ParseError.cjs +10 -0
  90. package/src/errors/ParseError.mjs +7 -0
  91. package/src/errors/ParserError.cjs +11 -0
  92. package/src/errors/ParserError.mjs +6 -0
  93. package/src/errors/PluginError.cjs +18 -0
  94. package/src/errors/PluginError.mjs +15 -0
  95. package/src/errors/ResolveError.cjs +10 -0
  96. package/src/errors/ResolveError.mjs +7 -0
  97. package/src/errors/ResolverError.cjs +11 -0
  98. package/src/errors/ResolverError.mjs +6 -0
  99. package/src/errors/UnmatchedBundleStrategyError.cjs +11 -0
  100. package/src/errors/UnmatchedBundleStrategyError.mjs +6 -0
  101. package/src/errors/UnmatchedDereferenceStrategyError.cjs +11 -0
  102. package/src/errors/UnmatchedDereferenceStrategyError.mjs +6 -0
  103. package/src/errors/UnmatchedResolveStrategyError.cjs +11 -0
  104. package/src/errors/UnmatchedResolveStrategyError.mjs +6 -0
  105. package/src/errors/UnmatchedResolverError.cjs +11 -0
  106. package/src/errors/UnmatchedResolverError.mjs +6 -0
  107. package/src/index.cjs +142 -0
  108. package/src/index.mjs +101 -0
  109. package/src/options/index.cjs +185 -0
  110. package/src/options/index.mjs +182 -0
  111. package/src/options/util.cjs +24 -0
  112. package/src/options/util.mjs +19 -0
  113. package/src/parse/index.cjs +69 -0
  114. package/src/parse/index.mjs +63 -0
  115. package/src/parse/parsers/Parser.cjs +48 -0
  116. package/src/parse/parsers/Parser.mjs +44 -0
  117. package/src/parse/parsers/api-design-systems-json/index.cjs +55 -0
  118. package/src/parse/parsers/api-design-systems-json/index.mjs +49 -0
  119. package/src/parse/parsers/api-design-systems-yaml/index.cjs +54 -0
  120. package/src/parse/parsers/api-design-systems-yaml/index.mjs +48 -0
  121. package/src/parse/parsers/apidom-json/index.cjs +70 -0
  122. package/src/parse/parsers/apidom-json/index.mjs +64 -0
  123. package/src/parse/parsers/arazzo-json-1/index.cjs +55 -0
  124. package/src/parse/parsers/arazzo-json-1/index.mjs +49 -0
  125. package/src/parse/parsers/arazzo-yaml-1/index.cjs +54 -0
  126. package/src/parse/parsers/arazzo-yaml-1/index.mjs +48 -0
  127. package/src/parse/parsers/asyncapi-json-2/index.cjs +55 -0
  128. package/src/parse/parsers/asyncapi-json-2/index.mjs +49 -0
  129. package/src/parse/parsers/asyncapi-yaml-2/index.cjs +54 -0
  130. package/src/parse/parsers/asyncapi-yaml-2/index.mjs +48 -0
  131. package/src/parse/parsers/binary/index-browser.cjs +56 -0
  132. package/src/parse/parsers/binary/index-browser.mjs +50 -0
  133. package/src/parse/parsers/binary/index-node.cjs +51 -0
  134. package/src/parse/parsers/binary/index-node.mjs +45 -0
  135. package/src/parse/parsers/json/index.cjs +54 -0
  136. package/src/parse/parsers/json/index.mjs +48 -0
  137. package/src/parse/parsers/openapi-json-2/index.cjs +55 -0
  138. package/src/parse/parsers/openapi-json-2/index.mjs +49 -0
  139. package/src/parse/parsers/openapi-json-3-0/index.cjs +55 -0
  140. package/src/parse/parsers/openapi-json-3-0/index.mjs +49 -0
  141. package/src/parse/parsers/openapi-json-3-1/index.cjs +55 -0
  142. package/src/parse/parsers/openapi-json-3-1/index.mjs +49 -0
  143. package/src/parse/parsers/openapi-yaml-2/index.cjs +54 -0
  144. package/src/parse/parsers/openapi-yaml-2/index.mjs +48 -0
  145. package/src/parse/parsers/openapi-yaml-3-0/index.cjs +54 -0
  146. package/src/parse/parsers/openapi-yaml-3-0/index.mjs +48 -0
  147. package/src/parse/parsers/openapi-yaml-3-1/index.cjs +54 -0
  148. package/src/parse/parsers/openapi-yaml-3-1/index.mjs +48 -0
  149. package/src/parse/parsers/yaml-1-2/index.cjs +54 -0
  150. package/src/parse/parsers/yaml-1-2/index.mjs +48 -0
  151. package/src/resolve/index.cjs +67 -0
  152. package/src/resolve/index.mjs +60 -0
  153. package/src/resolve/resolvers/HTTPResolver.cjs +38 -0
  154. package/src/resolve/resolvers/HTTPResolver.mjs +31 -0
  155. package/src/resolve/resolvers/Resolver.cjs +20 -0
  156. package/src/resolve/resolvers/Resolver.mjs +16 -0
  157. package/src/resolve/resolvers/file/index-browser.cjs +24 -0
  158. package/src/resolve/resolvers/file/index-browser.mjs +19 -0
  159. package/src/resolve/resolvers/file/index-node.cjs +49 -0
  160. package/src/resolve/resolvers/file/index-node.mjs +42 -0
  161. package/src/resolve/resolvers/http-axios/index.cjs +80 -0
  162. package/src/resolve/resolvers/http-axios/index.mjs +73 -0
  163. package/src/resolve/strategies/ResolveStrategy.cjs +20 -0
  164. package/src/resolve/strategies/ResolveStrategy.mjs +16 -0
  165. package/src/resolve/strategies/apidom/index.cjs +49 -0
  166. package/src/resolve/strategies/apidom/index.mjs +43 -0
  167. package/src/resolve/strategies/asyncapi-2/index.cjs +49 -0
  168. package/src/resolve/strategies/asyncapi-2/index.mjs +43 -0
  169. package/src/resolve/strategies/openapi-2/index.cjs +49 -0
  170. package/src/resolve/strategies/openapi-2/index.mjs +43 -0
  171. package/src/resolve/strategies/openapi-3-0/index.cjs +49 -0
  172. package/src/resolve/strategies/openapi-3-0/index.mjs +43 -0
  173. package/src/resolve/strategies/openapi-3-1/index.cjs +49 -0
  174. package/src/resolve/strategies/openapi-3-1/index.mjs +43 -0
  175. package/src/resolve/util.cjs +37 -0
  176. package/src/resolve/util.mjs +30 -0
  177. package/src/util/plugins.cjs +44 -0
  178. package/src/util/plugins.mjs +37 -0
  179. package/src/util/url.cjs +288 -0
  180. package/src/util/url.mjs +274 -0
  181. package/types/File.d.ts +24 -0
  182. package/types/Reference.d.ts +23 -0
  183. package/types/ReferenceSet.d.ts +25 -0
  184. package/types/apidom-reference.d.ts +584 -0
  185. package/types/bundle/index.d.ts +7 -0
  186. package/types/bundle/strategies/BundleStrategy.d.ts +19 -0
  187. package/types/bundle/strategies/openapi-3-1/index.d.ts +26 -0
  188. package/types/configuration/empty.d.ts +1 -0
  189. package/types/configuration/saturated.d.ts +1 -0
  190. package/types/dereference/index.d.ts +11 -0
  191. package/types/dereference/strategies/DereferenceStrategy.d.ts +19 -0
  192. package/types/dereference/strategies/apidom/index.d.ts +30 -0
  193. package/types/dereference/strategies/apidom/selectors/element-id.d.ts +11 -0
  194. package/types/dereference/strategies/apidom/visitor.d.ts +32 -0
  195. package/types/dereference/strategies/asyncapi-2/index.d.ts +31 -0
  196. package/types/dereference/strategies/asyncapi-2/visitor.d.ts +43 -0
  197. package/types/dereference/strategies/openapi-2/index.d.ts +32 -0
  198. package/types/dereference/strategies/openapi-2/visitor.d.ts +47 -0
  199. package/types/dereference/strategies/openapi-3-0/index.d.ts +31 -0
  200. package/types/dereference/strategies/openapi-3-0/visitor.d.ts +49 -0
  201. package/types/dereference/strategies/openapi-3-1/index.d.ts +32 -0
  202. package/types/dereference/strategies/openapi-3-1/selectors/$anchor.d.ts +22 -0
  203. package/types/dereference/strategies/openapi-3-1/selectors/uri.d.ts +12 -0
  204. package/types/dereference/strategies/openapi-3-1/util.d.ts +21 -0
  205. package/types/dereference/strategies/openapi-3-1/visitor.d.ts +52 -0
  206. package/types/dereference/util.d.ts +9 -0
  207. package/types/errors/BundleError.d.ts +7 -0
  208. package/types/errors/DereferenceError.d.ts +7 -0
  209. package/types/errors/EvaluationElementIdError.d.ts +7 -0
  210. package/types/errors/EvaluationJsonSchema$anchorError.d.ts +7 -0
  211. package/types/errors/EvaluationJsonSchemaUriError.d.ts +7 -0
  212. package/types/errors/InvalidJsonSchema$anchorError.d.ts +8 -0
  213. package/types/errors/JsonSchema$anchorError.d.ts +7 -0
  214. package/types/errors/JsonSchemaUriError.d.ts +7 -0
  215. package/types/errors/MaximumBundleDepthError.d.ts +7 -0
  216. package/types/errors/MaximumDereferenceDepthError.d.ts +7 -0
  217. package/types/errors/MaximumResolveDepthError.d.ts +7 -0
  218. package/types/errors/ParseError.d.ts +7 -0
  219. package/types/errors/ParserError.d.ts +7 -0
  220. package/types/errors/PluginError.d.ts +12 -0
  221. package/types/errors/ResolveError.d.ts +7 -0
  222. package/types/errors/ResolverError.d.ts +7 -0
  223. package/types/errors/UnmatchedBundleStrategyError.d.ts +7 -0
  224. package/types/errors/UnmatchedDereferenceStrategyError.d.ts +7 -0
  225. package/types/errors/UnmatchedResolveStrategyError.d.ts +7 -0
  226. package/types/errors/UnmatchedResolverError.d.ts +7 -0
  227. package/types/index.d.ts +75 -0
  228. package/types/options/index.d.ts +62 -0
  229. package/types/options/util.d.ts +5 -0
  230. package/types/parse/index.d.ts +7 -0
  231. package/types/parse/parsers/Parser.d.ts +38 -0
  232. package/types/parse/parsers/api-design-systems-json/index.d.ts +21 -0
  233. package/types/parse/parsers/api-design-systems-yaml/index.d.ts +20 -0
  234. package/types/parse/parsers/apidom-json/index.d.ts +24 -0
  235. package/types/parse/parsers/arazzo-json-1/index.d.ts +21 -0
  236. package/types/parse/parsers/arazzo-yaml-1/index.d.ts +20 -0
  237. package/types/parse/parsers/asyncapi-json-2/index.d.ts +21 -0
  238. package/types/parse/parsers/asyncapi-yaml-2/index.d.ts +20 -0
  239. package/types/parse/parsers/binary/index-browser.d.ts +21 -0
  240. package/types/parse/parsers/binary/index-node.d.ts +21 -0
  241. package/types/parse/parsers/json/index.d.ts +20 -0
  242. package/types/parse/parsers/openapi-json-2/index.d.ts +21 -0
  243. package/types/parse/parsers/openapi-json-3-0/index.d.ts +21 -0
  244. package/types/parse/parsers/openapi-json-3-1/index.d.ts +21 -0
  245. package/types/parse/parsers/openapi-yaml-2/index.d.ts +20 -0
  246. package/types/parse/parsers/openapi-yaml-3-0/index.d.ts +20 -0
  247. package/types/parse/parsers/openapi-yaml-3-1/index.d.ts +20 -0
  248. package/types/parse/parsers/yaml-1-2/index.d.ts +20 -0
  249. package/types/resolve/index.d.ts +12 -0
  250. package/types/resolve/resolvers/HTTPResolver.d.ts +22 -0
  251. package/types/resolve/resolvers/Resolver.d.ts +17 -0
  252. package/types/resolve/resolvers/file/index-browser.d.ts +12 -0
  253. package/types/resolve/resolvers/file/index-node.d.ts +20 -0
  254. package/types/resolve/resolvers/http-axios/index.d.ts +30 -0
  255. package/types/resolve/strategies/ResolveStrategy.d.ts +19 -0
  256. package/types/resolve/strategies/apidom/index.d.ts +27 -0
  257. package/types/resolve/strategies/asyncapi-2/index.d.ts +27 -0
  258. package/types/resolve/strategies/openapi-2/index.d.ts +27 -0
  259. package/types/resolve/strategies/openapi-3-0/index.d.ts +27 -0
  260. package/types/resolve/strategies/openapi-3-1/index.d.ts +27 -0
  261. package/types/resolve/util.d.ts +6 -0
  262. package/types/util/plugins.d.ts +14 -0
  263. package/types/util/url.d.ts +106 -0
package/README.md ADDED
@@ -0,0 +1,2107 @@
1
+ # @speclynx/apidom-reference
2
+
3
+ `@speclynx/apidom-reference` package contains advanced algorithms for semantic ApiDOM manipulations.
4
+ This package is divided into three (3) main components:
5
+
6
+ - **[Parse component](#parse-component)**
7
+ - **[Resolve component](#resolve-component)**
8
+ - **[Dereference component](#dereference-component)**
9
+ - **[Bundle component](#bundle-component)**
10
+
11
+ ## Installation
12
+
13
+ You can install `@speclynx/apidom-reference` via [npm CLI](https://docs.npmjs.com/cli) by running the following command:
14
+
15
+ ```sh
16
+ $ npm install @speclynx/apidom-reference
17
+ ```
18
+
19
+ ## Configurations
20
+
21
+ This package has two main exports suitable for different use-cases. **Empty** configuration and **saturated** configuration.
22
+
23
+ ### Empty configuration
24
+
25
+ ```js
26
+ import { parse } from '@speclynx/apidom-reference/configuration/empty';
27
+ import OpenAPIJSON3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-1';
28
+
29
+ await parse('/home/user/oas.json', {
30
+ parse: {
31
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
32
+ parsers: [new OpenAPIJSON3_1Parser({ allowEmpty: true, sourceMap: false })]
33
+ }
34
+ });
35
+ ```
36
+
37
+ When using this approach, `options` object is not configured with parsers, resolvers or strategies.
38
+ This is suitable for creating **web bundles** and gives you total control of the contents of your bundles.
39
+
40
+ ### Saturated configuration
41
+
42
+ ```js
43
+ import { parse } from '@speclynx/apidom-reference';
44
+ ```
45
+ or
46
+ ```js
47
+ import { parse } from '@speclynx/apidom-reference/configuration/saturaged';
48
+ ```
49
+
50
+ Both of above imports are equivalent. This approach is suitable for **Node.js** environments.
51
+ `options` object is pre-configured with all the parsers, resolvers and strategies.
52
+
53
+ ## Parse component
54
+
55
+ Parse component consists of implementation of default [parser plugins](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers).
56
+ Defaults parser plugin is a specialized wrapper that wraps one of the ApiDOM parser adapter into specialized API.
57
+ Standard ApiDOM parser adapter can only parse strings. Parser plugins are capable of parsing local filesystem URIs and network URLs.
58
+
59
+ **Parsing a file localed on local filesystem:**
60
+
61
+ ```js
62
+ import { parse } from '@speclynx/apidom-reference';
63
+
64
+ await parse('/home/user/oas.json', {
65
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' }
66
+ });
67
+ ```
68
+
69
+ **Parsing an HTTP(S) URL located on internet:**
70
+
71
+ ```js
72
+ import { parse } from '@speclynx/apidom-reference';
73
+
74
+ await parse('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
75
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' }
76
+ })
77
+ ```
78
+
79
+ Notice how we explicitly pass a `mediaType` parse option. This option is actually **not required**,
80
+ but if not provided, the Parse component will try to identify appropriate parser plugin by file contents, and it's extension (`.json`).
81
+
82
+ What actually happens if you don't provide `mediaType` parse option?
83
+
84
+ ```js
85
+ import { parse } from '@speclynx/apidom-reference';
86
+
87
+ await parse('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json');
88
+ ```
89
+
90
+ The result of this operation is going to be generic ApiDOM structure. By analyzing the name of the file
91
+ we can identify the extension of the file as `.json`. At this point we only know
92
+ that this file is probably going to contain JSON string, though we have no idea what data (AsyncApi/OpenApi)
93
+ is encoded within that JSON string.
94
+
95
+ In the future, we will introduce smart algorithms for looking in the contents of a file and detecting the
96
+ `mediaType` automatically. Of course not explicitly providing `mediaType` has performance implications (running detection)
97
+ so providing it is always a better option.
98
+
99
+ ### Parser plugins
100
+
101
+ Parse component comes with number of default parser plugins.
102
+
103
+ #### [apidom-json](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/apidom-json)
104
+
105
+ Parses dehydrated ApiDOM structure and hydrates it.
106
+ This parser plugin is uniquely identified by `apidom-json` name.
107
+
108
+ Supported media types are:
109
+
110
+ ```js
111
+ [
112
+ 'application/vnd.apidom',
113
+ 'application/vnd.apidom+json',
114
+ ]
115
+ ```
116
+
117
+ #### [openapi-json-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/openapi-json-2)
118
+
119
+ Wraps [@speclynx/apidom-parser-adapter-openapi-json-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-openapi-json-2) package
120
+ and is uniquely identified by `openapi-json-2` name.
121
+
122
+ Supported media types are:
123
+
124
+ ```js
125
+ [
126
+ 'application/vnd.oai.openapi;version=2.0',
127
+ 'application/vnd.oai.openapi+json;version=2.0',
128
+ ]
129
+ ```
130
+
131
+ #### [openapi-json-3-0](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/openapi-json-3-0)
132
+
133
+ Wraps [@speclynx/apidom-parser-adapter-openapi-json-3-0](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-openapi-json-3-0) package
134
+ and is uniquely identified by `openapi-json-3-0` name.
135
+
136
+ Supported media types are:
137
+
138
+ ```js
139
+ [
140
+ 'application/vnd.oai.openapi;version=3.0.0',
141
+ 'application/vnd.oai.openapi+json;version=3.0.0',
142
+ 'application/vnd.oai.openapi;version=3.0.1',
143
+ 'application/vnd.oai.openapi+json;version=3.0.1',
144
+ 'application/vnd.oai.openapi;version=3.0.2',
145
+ 'application/vnd.oai.openapi+json;version=3.0.2',
146
+ 'application/vnd.oai.openapi;version=3.0.3',
147
+ 'application/vnd.oai.openapi+json;version=3.0.3',
148
+ 'application/vnd.oai.openapi;version=3.0.4',
149
+ 'application/vnd.oai.openapi+json;version=3.0.4',
150
+ ]
151
+ ```
152
+
153
+ #### [openapi-yaml-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/openapi-yaml-2)
154
+
155
+ Wraps [@speclynx/apidom-parser-adapter-openapi-yaml-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-openapi-yaml-2) package
156
+ and is uniquely identified by `openapi-yaml-2` name.
157
+
158
+ Supported media types are:
159
+
160
+ ```js
161
+ [
162
+ 'application/vnd.oai.openapi;version=2.0',
163
+ 'application/vnd.oai.openapi+yaml;version=2.0',
164
+ ]
165
+ ```
166
+
167
+ #### [openapi-yaml-3-0](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/openapi-yaml-3-0)
168
+
169
+ Wraps [@speclynx/apidom-parser-adapter-openapi-yaml-3-0](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-openapi-yaml-3-0) package
170
+ and is uniquely identified by `openapi-yaml-3-0` name.
171
+
172
+ Supported media types are:
173
+
174
+ ```js
175
+ [
176
+ 'application/vnd.oai.openapi;version=3.0.0',
177
+ 'application/vnd.oai.openapi+yaml;version=3.0.0',
178
+ 'application/vnd.oai.openapi;version=3.0.1',
179
+ 'application/vnd.oai.openapi+yaml;version=3.0.1',
180
+ 'application/vnd.oai.openapi;version=3.0.2',
181
+ 'application/vnd.oai.openapi+yaml;version=3.0.2',
182
+ 'application/vnd.oai.openapi;version=3.0.3',
183
+ 'application/vnd.oai.openapi+yaml;version=3.0.3',
184
+ 'application/vnd.oai.openapi;version=3.0.4',
185
+ 'application/vnd.oai.openapi+yaml;version=3.0.4',
186
+ ]
187
+ ```
188
+
189
+ #### [openapi-json-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/openapi-json-3-1)
190
+
191
+ Wraps [@speclynx/apidom-parser-adapter-openapi-json-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-openapi-json-3-1) package
192
+ and is uniquely identified by `openapi-json-3-1` name.
193
+
194
+ Supported media types are:
195
+
196
+ ```js
197
+ [
198
+ 'application/vnd.oai.openapi;version=3.1.0',
199
+ 'application/vnd.oai.openapi+json;version=3.1.0',
200
+ 'application/vnd.oai.openapi;version=3.1.1',
201
+ 'application/vnd.oai.openapi+json;version=3.1.1',
202
+ 'application/vnd.oai.openapi;version=3.1.2',
203
+ 'application/vnd.oai.openapi+json;version=3.1.2',
204
+ ]
205
+ ```
206
+
207
+ #### [openapi-yaml-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/openapi-yaml-3-1)
208
+
209
+ Wraps [@speclynx/apidom-parser-adapter-openapi-yaml-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-openapi-yaml-3-1) package
210
+ and is uniquely identified by `openapi-yaml-3-1` name.
211
+
212
+ Supported media types are:
213
+
214
+ ```js
215
+ [
216
+ 'application/vnd.oai.openapi;version=3.1.0',
217
+ 'application/vnd.oai.openapi+yaml;version=3.1.0',
218
+ 'application/vnd.oai.openapi;version=3.1.1',
219
+ 'application/vnd.oai.openapi+yaml;version=3.1.1',
220
+ 'application/vnd.oai.openapi;version=3.1.2',
221
+ 'application/vnd.oai.openapi+yaml;version=3.1.2'
222
+ ]
223
+ ```
224
+
225
+ #### [asyncapi-json-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/asyncapi-json-2)
226
+
227
+ Wraps [@speclynx/apidom-parser-adapter-asyncapi-json-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-asyncapi-json-2) package
228
+ and is uniquely identified by `asyncapi-json-2` name.
229
+
230
+ Supported media types are:
231
+
232
+ ```js
233
+ [
234
+ 'application/vnd.aai.asyncapi;version=2.0.0',
235
+ 'application/vnd.aai.asyncapi;version=2.1.0',
236
+ 'application/vnd.aai.asyncapi;version=2.2.0',
237
+ 'application/vnd.aai.asyncapi;version=2.3.0',
238
+ 'application/vnd.aai.asyncapi;version=2.4.0',
239
+ 'application/vnd.aai.asyncapi;version=2.5.0',
240
+ 'application/vnd.aai.asyncapi;version=2.6.0',
241
+ 'application/vnd.aai.asyncapi+json;version=2.0.0',
242
+ 'application/vnd.aai.asyncapi+json;version=2.1.0',
243
+ 'application/vnd.aai.asyncapi+json;version=2.2.0',
244
+ 'application/vnd.aai.asyncapi+json;version=2.3.0',
245
+ 'application/vnd.aai.asyncapi+json;version=2.4.0',
246
+ 'application/vnd.aai.asyncapi+json;version=2.5.0',
247
+ 'application/vnd.aai.asyncapi+json;version=2.6.0',
248
+ ]
249
+ ```
250
+
251
+ #### [asyncapi-yaml-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/asyncapi-yaml-2)
252
+
253
+ Wraps [@speclynx/apidom-parser-adapter-asyncapi-yaml-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-asyncapi-yaml-2) package
254
+ and is uniquely identified by `asyncapi-yaml-2` name.
255
+
256
+
257
+ Supported media types are:
258
+
259
+ ```js
260
+ [
261
+ 'application/vnd.aai.asyncapi;version=2.0.0',
262
+ 'application/vnd.aai.asyncapi;version=2.1.0',
263
+ 'application/vnd.aai.asyncapi;version=2.2.0',
264
+ 'application/vnd.aai.asyncapi;version=2.3.0',
265
+ 'application/vnd.aai.asyncapi;version=2.3.0',
266
+ 'application/vnd.aai.asyncapi;version=2.4.0',
267
+ 'application/vnd.aai.asyncapi;version=2.5.0',
268
+ 'application/vnd.aai.asyncapi;version=2.6.0',
269
+ 'application/vnd.aai.asyncapi+yaml;version=2.0.0',
270
+ 'application/vnd.aai.asyncapi+yaml;version=2.1.0',
271
+ 'application/vnd.aai.asyncapi+yaml;version=2.2.0',
272
+ 'application/vnd.aai.asyncapi+yaml;version=2.3.0',
273
+ 'application/vnd.aai.asyncapi+yaml;version=2.4.0',
274
+ 'application/vnd.aai.asyncapi+yaml;version=2.5.0',
275
+ 'application/vnd.aai.asyncapi+yaml;version=2.6.0',
276
+ ]
277
+ ```
278
+
279
+ #### [arazzo-json-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/arazzo-json-1)
280
+
281
+ Wraps [@speclynx/apidom-parser-adapter-arazzo-json-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-arazzo-json-1) package
282
+ and is uniquely identified by `arazzo-json-1` name.
283
+
284
+ Supported media types are:
285
+
286
+ ```js
287
+ [
288
+ 'application/vnd.oai.workflows;version=1.0.0',
289
+ 'application/vnd.oai.workflows+json;version=1.0.0',
290
+ 'application/vnd.oai.workflows;version=1.0.1',
291
+ 'application/vnd.oai.workflows+json;version=1.0.1',
292
+ ]
293
+ ```
294
+
295
+ #### [arazzo-yaml-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/arazzo-yaml-1)
296
+
297
+ Wraps [@speclynx/apidom-parser-adapter-arazzo-yaml-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-arazzo-yaml-1) package
298
+ and is uniquely identified by `arazzo-yaml-1` name.
299
+
300
+ Supported media types are:
301
+
302
+ ```js
303
+ [
304
+ 'application/vnd.oai.workflows;version=1.0.0',
305
+ 'application/vnd.oai.workflows+yaml;version=1.0.0',
306
+ 'application/vnd.oai.workflows;version=1.0.1',
307
+ 'application/vnd.oai.workflows+yaml;version=1.0.1',
308
+ ]
309
+ ```
310
+
311
+ #### [api-design-systems-json](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/api-design-systems-json)
312
+
313
+ Wraps [@speclynx/apidom-parser-adapter-api-design-systsems-json](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-api-design-systems-json) package
314
+ and is uniquely identified by `api-design-systems-json` name.
315
+
316
+ Supported media types are:
317
+
318
+ ```js
319
+ [
320
+ 'application/vnd.aai.apidesignsystems;version=2021-05-07',
321
+ 'application/vnd.aai.apidesignsystems+json;version=2021-05-07'
322
+ ]
323
+ ```
324
+
325
+ #### [api-design-systems-yaml](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/api-design-systems-yaml)
326
+
327
+ Wraps [@speclynx/apidom-parser-adapter-api-design-systems-yaml](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-api-design-systems-yaml) package
328
+ and is uniquely identified by `api-design-systems-yaml` name.
329
+
330
+
331
+ Supported media types are:
332
+
333
+ ```js
334
+ [
335
+ 'application/vnd.aai.apidesignsystems;version=2021-05-07',
336
+ 'application/vnd.aai.apidesignsystems+yaml;version=2021-05-07'
337
+ ]
338
+ ```
339
+
340
+ #### [json](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/json)
341
+
342
+ Wraps [@speclynx/apidom-parser-adapter-json](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-json) package
343
+ and is uniquely identified by `json` name.
344
+
345
+
346
+ Supported media types are:
347
+
348
+ ```js
349
+ [
350
+ 'application/json'
351
+ ]
352
+ ```
353
+
354
+ #### [yaml-1-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/yaml-1-2)
355
+
356
+ Wraps [@speclynx/apidom-parser-adapter-yaml-1-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-parser-adapter-yaml-1-2) package
357
+ and is uniquely identified by `yaml-1-2` name.
358
+
359
+
360
+ Supported media types are:
361
+
362
+ ```js
363
+ [
364
+ 'text/yaml',
365
+ 'application/yaml'
366
+ ]
367
+ ```
368
+
369
+ #### [binary](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/parse/parsers/binary)
370
+
371
+ Can parse any binary or non-binary file and return it's content as `base64` encoded string.
372
+ This parser is uniquely identified by `binary` name.
373
+
374
+
375
+ **All** media types are supported.
376
+
377
+ #### Parser plugins execution order
378
+
379
+ It's important to understand that default parser plugins are run in specific order. The order is determined
380
+ by the [options.parse.parsers](https://github.com/speclynx/apidom/blob/ba888d711a4292e8ed0b72e343c4902a4bf0d45a/packages/apidom-reference/src/configuration/saturated.ts#L22) option.
381
+ Every plugin is pulled from `options.parse.parsers` option, and it's `canParse` method is called to determine
382
+ whether the plugin can parse the URI. If `canParse` returns `true`, `parse` method of plugin is called
383
+ and result from parsing is returned. No subsequent parser plugins are run. If `canParse` returns
384
+ `false`, next parser plugin is pulled and this process is repeated until one of the parser plugins `canParse` method
385
+ returns `true` or until entire list of parser plugins is exhausted (throws error).
386
+
387
+ ```js
388
+ [
389
+ new OpenAPIJSON2Parser({ allowEmpty: true, sourceMap: false }),
390
+ new OpenAPIYAML2Parser({ allowEmpty: true, sourceMap: false }),
391
+ new OpenAPIJSON3_0Parser({ allowEmpty: true, sourceMap: false }),
392
+ new OpenAPIYAML3_0Parser({ allowEmpty: true, sourceMap: false }),
393
+ new OpenAPIJSON3_1Parser({ allowEmpty: true, sourceMap: false }),
394
+ new OpenAPIYAML3_1Parser({ allowEmpty: true, sourceMap: false }),
395
+ new AsyncAPIJSON2Parser({ allowEmpty: true, sourceMap: false }),
396
+ new AsyncAPIYAML2Parser({ allowEmpty: true, sourceMap: false }),
397
+ new ArazzoJSON1Parser({ allowEmpty: true, sourceMap: false }),
398
+ new ArazzoYAML1Parser({ allowEmpty: true, sourceMap: false }),
399
+ new APIDesignSystemsJSONParser({ allowEmpty: true, sourceMap: false }),
400
+ new APIDesignSystemsYAMLParser({ allowEmpty: true, sourceMap: false }),
401
+ new APIDOMJSONParser({ allowEmpty: true, sourceMap: false }),
402
+ new JSONParser({ allowEmpty: true, sourceMap: false }),
403
+ new YAMLParser({ allowEmpty: true, sourceMap: false }),
404
+ new BinaryParser({ allowEmpty: true }),
405
+ ]
406
+ ```
407
+ Most specific parser plugins are listed first, most generic are listed last.
408
+
409
+ It's possible to **change** the parser plugins **order globally** by mutating global `parse` options:
410
+
411
+ ```js
412
+ import { options } from '@speclynx/apidom-reference';
413
+ import OpenAPIJSON2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-2';
414
+ import OpenAPIYAML2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-2';
415
+ import OpenAPIJSON3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-0';
416
+ import OpenAPIYAML3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-0'
417
+ import OpenAPIJSON3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-1';
418
+ import OpenAPIYAML3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-1'
419
+ import AsyncAPIJSON2Parser from '@speclynx/apidom-reference/parse/parsers/asyncapi-json-2';
420
+ import AsyncAPIYAML2Parser from '@speclynx/apidom-reference/parse/parsers/asyncapi-yaml-2';
421
+ import ArazzoJSON1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
422
+ import ArazzoYAML1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1';
423
+ import APIDOMJSONParser from '@speclynx/apidom-reference/parse/parsers/apidom-json';
424
+ import APIDesignSystemsJSONParser from '@speclynx/apidom-reference/parse/parsers/api-design-systems-json';
425
+ import APIDesignSystemsYAMLParser from '@speclynx/apidom-reference/parse/parsers/api-design-systems-json';
426
+ import JSONParser from '@speclynx/apidom-reference/parse/parsers/json';
427
+ import YAMLParser from '@speclynx/apidom-reference/parse/parsers/yaml';
428
+ import BinaryParser from '@speclynx/apidom-reference/parse/parsers/binary';
429
+
430
+
431
+ options.parse.parsers = [
432
+ new OpenAPIJSON2Parser({ allowEmpty: true, sourceMap: false }),
433
+ new OpenAPIYAML2Parser({ allowEmpty: true, sourceMap: false }),
434
+ new OpenAPIJSON3_0Parser({ allowEmpty: true, sourceMap: false }),
435
+ new OpenAPIYAML3_0Parser({ allowEmpty: true, sourceMap: false }),
436
+ new OpenAPIJSON3_1Parser({ allowEmpty: true, sourceMap: false }),
437
+ new OpenAPIYAML3_1Parser({ allowEmpty: true, sourceMap: false }),
438
+ new AsyncAPIJSON2Parser({ allowEmpty: true, sourceMap: false }),
439
+ new AsyncAPIYAML2Parser({ allowEmpty: true, sourceMap: false }),
440
+ new ArazzoJSON1Parser({ allowEmpty: true, sourceMap: false }),
441
+ new ArazzoYAML1Parser({ allowEmpty: true, sourceMap: false }),
442
+ new APIDesignSystemsJSONParser({ allowEmpty: true, sourceMap: false }),
443
+ new APIDesignSystemsYAMLParser({ allowEmpty: true, sourceMap: false }),
444
+ new APIDOMJSONParser({ allowEmpty: true, sourceMap: false }),
445
+ new YAMLParser({ allowEmpty: true, sourceMap: false }),
446
+ new JSONParser({ allowEmpty: true, sourceMap: false }),
447
+ new BinaryParser({ allowEmpty: true }),
448
+ ]
449
+ ```
450
+
451
+ To **change** the parser plugins **order** on ad-hoc basis:
452
+
453
+ ```js
454
+ import { parse } from '@speclynx/apidom-reference';
455
+ import OpenAPIJSON2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-2';
456
+ import OpenAPIYAML2Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-2';
457
+ import OpenAPIJSON3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-0';
458
+ import OpenAPIYAML3_0Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-0'
459
+ import OpenAPIJSON3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-json-3-1';
460
+ import OpenAPIYAML3_1Parser from '@speclynx/apidom-reference/parse/parsers/openapi-yaml-3-1'
461
+ import AsyncAPIJSON2Parser from '@speclynx/apidom-reference/parse/parsers/asyncapi-json-2';
462
+ import AsyncAPIYAML2Parser from '@speclynx/apidom-reference/parse/parsers/asyncapi-yaml-2';
463
+ import ArazzoJSON1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-json-1';
464
+ import ArazzoYAML1Parser from '@speclynx/apidom-reference/parse/parsers/arazzo-yaml-1';
465
+ import APIDOMJSONParser from '@speclynx/apidom-reference/parse/parsers/apidom-json';
466
+ import APIDesignSystemsJSONParser from '@speclynx/apidom-reference/parse/parsers/api-design-systems-json';
467
+ import APIDesignSystemsYAMLParser from '@speclynx/apidom-reference/parse/parsers/api-design-systems-json';
468
+ import JSONParser from '@speclynx/apidom-reference/parse/parsers/json';
469
+ import YAMLParser from '@speclynx/apidom-reference/parse/parsers/yaml';
470
+ import BinaryParser from '@speclynx/apidom-reference/parse/parsers/binary';
471
+
472
+ await parse('/home/user/oas.json', {
473
+ parse: {
474
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
475
+ parsers: [
476
+ new OpenAPIJSON2Parser({ allowEmpty: true, sourceMap: false }),
477
+ new OpenAPIYAML2Parser({ allowEmpty: true, sourceMap: false }),
478
+ new OpenAPIJSON3_0Parser({ allowEmpty: true, sourceMap: false }),
479
+ new OpenAPIYAML3_0Parser({ allowEmpty: true, sourceMap: false }),
480
+ new OpenAPIJSON3_1Parser({ allowEmpty: true, sourceMap: false }),
481
+ new OpenAPIYAML3_1Parser({ allowEmpty: true, sourceMap: false }),
482
+ new AsyncAPIJSON2Parser({ allowEmpty: true, sourceMap: false }),
483
+ new AsyncAPIYAML2Parser({ allowEmpty: true, sourceMap: false }),
484
+ new ArazzoJSON1Parser({ allowEmpty: true, sourceMap: false }),
485
+ new ArazzoYAML1Parser({ allowEmpty: true, sourceMap: false }),
486
+ new APIDesignSystemsJSONParser({ allowEmpty: true, sourceMap: false }),
487
+ new APIDesignSystemsYAMLParser({ allowEmpty: true, sourceMap: false }),
488
+ new APIDOMJSONParser({ allowEmpty: true, sourceMap: false }),
489
+ new JSONParser({ allowEmpty: true, sourceMap: false }),
490
+ new YAMLParser({ allowEmpty: true, sourceMap: false }),
491
+ new BinaryParser({ allowEmpty: true }),
492
+ ],
493
+ },
494
+ });
495
+ ```
496
+
497
+ #### Parser plugin options
498
+
499
+ Parser plugins accept additional options like `allowEmpty` or `sourceMap`. It's possible to **change** parser plugin
500
+ **options globally** by mutating global `parse` options:
501
+
502
+ ```js
503
+ import { options, parse } from '@speclynx/apidom-reference';
504
+
505
+ options.parser.parserOpts = {
506
+ allowEmpty: false,
507
+ sourceMap: true,
508
+ };
509
+
510
+ await parse('/home/user/oas.json', {
511
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' }
512
+ });
513
+ ```
514
+
515
+ To **change** the parser plugins **options** on ad-hoc basis:
516
+
517
+ ```js
518
+ import { parse } from '@speclynx/apidom-reference';
519
+
520
+ await parse('/home/user/oas.json', {
521
+ parse: {
522
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
523
+ parserOpts: { allowEmpty: false, sourceMap: true },
524
+ },
525
+ });
526
+ ```
527
+
528
+ ### Creating new parser plugin
529
+
530
+ Parse component can be extended by additional parser plugins. Every parser plugin is an object that
531
+ must conform to the following interface/shape:
532
+
533
+ ```typescript
534
+ interface ParserPlugin {
535
+ // uniquely identifies this parser plugin
536
+ readonly name: string;
537
+ allowEmpty: boolean;
538
+ sourceMap: boolean;
539
+ fileExtensions: string[];
540
+ mediaTypes: string[];
541
+
542
+ // this method is called to determine whether the parser plugin can parse the file
543
+ canParse(file: File): boolean | Promise<boolean>;
544
+
545
+ // this method actually parses the file
546
+ parse(file: File): ParseResultElement | Promise<ParseResultElement>;
547
+ }
548
+ ```
549
+
550
+ New parser plugin is then provided as an option to a `parse` function:
551
+
552
+ ```ts
553
+ import { parse, options, File, Parser, ParserOptions } from '@speclynx/apidom-reference';
554
+
555
+ interface MyCustomParserPluginOptions extends Omit<ParserOptions, 'name'> {}
556
+
557
+ class MyCustomParserPlugin extends Parser {
558
+ constructor(options?: MyCustomParserPluginOptions) {
559
+ super({ ...(options ?? {}), name: 'my-custom-parser' });
560
+ }
561
+
562
+ async canParse(file: File, options: typeof options) {
563
+ return true;
564
+ }
565
+
566
+ async parse(file: File, options: typeof options) {
567
+ // implementation of parsing
568
+ }
569
+ }
570
+
571
+ await parse('/home/user/oas.json', {
572
+ parse: {
573
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
574
+ parsers: [...options.parse.parsers, new MyCustomParserPlugin()],
575
+ }
576
+ });
577
+ ```
578
+
579
+ In this particular example we're adding our custom parser plugin as the last plugin
580
+ to the available default parser plugin list, so there's a good chance that one of the
581
+ default parser plugins detects that it can parse the `/home/user/oas.json` file,
582
+ parses it and returns.
583
+
584
+ If you want to force execution of your custom plugin, add it as a first parser plugin:
585
+
586
+ ```ts
587
+ import { parse, options, File, Parser, ParserOptions } from '@speclynx/apidom-reference';
588
+
589
+ interface MyCustomParserPluginOptions extends Omit<ParserOptions, 'name'> {}
590
+
591
+ class MyCustomParserPlugin extends Parser {
592
+ constructor(options?: MyCustomParserPluginOptions) {
593
+ super({ ...(options ?? {}), name: 'my-custom-parser' });
594
+ }
595
+
596
+ async canParse(file: File, options: typeof options) {
597
+ return true;
598
+ }
599
+
600
+ async parse(file: File, options: typeof options) {
601
+ // implementation of parsing
602
+ }
603
+ }
604
+
605
+
606
+ await parse('/home/user/oas.json', {
607
+ parse: {
608
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
609
+ parsers: [new MyCustomParserPlugin(), ...options.parse.parsers],
610
+ }
611
+ });
612
+ ```
613
+
614
+ To override the default parser plugins entirely, set `myCustomParserPlugin` plugin to be the only one available:
615
+
616
+ ```ts
617
+ import { parse, options, File, Parser, ParserOptions } from '@speclynx/apidom-reference';
618
+
619
+ interface MyCustomParserPluginOptions extends Omit<ParserOptions, 'name'> {}
620
+
621
+ class MyCustomParserPlugin extends Parser {
622
+ constructor(options?: MyCustomParserPluginOptions) {
623
+ super({ ...(options ?? {}), name: 'my-custom-parser' });
624
+ }
625
+
626
+ async canParse(file: File, options: typeof options) {
627
+ return true;
628
+ }
629
+
630
+ async parse(file: File, options: typeof options) {
631
+ // implementation of parsing
632
+ }
633
+ }
634
+
635
+ await parse('/home/user/oas.json', {
636
+ parse: {
637
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
638
+ parsers: [new MyCustomParserPlugin()],
639
+ }
640
+ });
641
+ ```
642
+
643
+ ### Manipulating parser plugins
644
+
645
+ Parser plugins can be added, removed, replaced or reordered.
646
+
647
+ Here are two examples of removing one of the parser plugins called `asyncapi-json-2`.
648
+ We're using the fact that every parser plugin is uniquely identifiable by its name.
649
+
650
+ **Removing** parser plugin **globally** for all subsequence `parse` calls is achieved by mutating global options:
651
+
652
+ ```js
653
+ import { parse, options, mergeOptions } from '@speclynx/apidom-reference';
654
+
655
+ options.parse.parsers = options.parse.parsers.filter(parserPlugin => parserPlugin !== 'asyncapi-json-2')
656
+
657
+ // here you can be sure `asyncapi-json-2` plugin was disabled
658
+ await parse('/home/user/oas.json', {
659
+ parse: {
660
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
661
+ }
662
+ });
663
+ ```
664
+
665
+ **Removing** default parser plugin on **ad-hoc** basis:
666
+
667
+ ```js
668
+ import { parse, options } from '@speclynx/apidom-reference';
669
+
670
+ await parse('/home/user/oas.json', {
671
+ parse: {
672
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
673
+ parsers: options.parse.parsers.filter(parserPlugin => parserPlugin.name !== 'asyncapi-json-2'),
674
+ }
675
+ });
676
+ ```
677
+ As you can see, these are all primitive JavaScript Array manipulation techniques.
678
+ These techniques can be applied to replacing (use [Array.prototype.map()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)) or reordering parser plugins as well.
679
+
680
+
681
+ ## Resolve component
682
+
683
+ `Resolve component` consists of two (2) sub-components: **File resolution** and **External Resolution**.
684
+ `Resolve component` is used by [Parse component](#parse-component) under the hood. `Resolve component` provides a resolved
685
+ file contents for a Parse component to parse.
686
+
687
+ ### File resolution
688
+
689
+ Contains implementation of default [resolver plugins](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/resolvers).
690
+ Defaults resolver plugin is an object which knows how to obtain contents of a file represented by URI or URL.
691
+
692
+ #### Resolver plugins
693
+
694
+ File resolution comes with two (2) default resolver plugins.
695
+
696
+ ##### [FileResolver](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/resolve/resolvers/file)
697
+
698
+ This resolver plugin is responsible for resolving a local file.
699
+ It detects if the provided URI represents a filesystem path and if so,
700
+ reads the file and provides its content.
701
+
702
+ **WARNING**: use this plugin with caution, as it can read files from a local file system.
703
+ By default, this plugin will reject to read any files from the local file system, unless
704
+ explicitly provided by **fileAllowList** option.
705
+
706
+ ###### Providing file allow list
707
+
708
+ File allow list can be provided **globally** as an option to `FileResolver` in form
709
+ of array of *glob patterns* or *regular expressions*.
710
+
711
+ ```js
712
+ import { options } from '@speclynx/apidom-reference';
713
+ import FileResolver from '@speclynx/apidom-reference/resolve/resolvers/file';
714
+ import HTTPResolverAxios from '@speclynx/apidom-reference/resolve/resolvers/http-axios';
715
+
716
+ options.resolve.resolvers = [
717
+ new FileResolver({
718
+ fileAllowList: [
719
+ '*.json',
720
+ /\.json$/,
721
+ ]
722
+ }),
723
+ new HTTPResolverAxios({ timeout: 5000, redirects: 5, withCredentials: false }),
724
+ ]
725
+ ```
726
+
727
+ File allow list can also be provided on ad-hoc basis:
728
+
729
+ ```js
730
+ import { resolve } from '@speclynx/apidom-reference';
731
+
732
+ await resolve('/home/user/oas.json', {
733
+ resolve: {
734
+ resolverOpts: {
735
+ fileAllowList: [
736
+ '*.json',
737
+ /\.json$/,
738
+ ]
739
+ },
740
+ },
741
+ });
742
+ ```
743
+
744
+ ##### [HTTPResolverAxios](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/resolve/resolvers/http-axios)
745
+
746
+ This resolver plugin is responsible for resolving a remote file represented by HTTP(s) URL.
747
+ It detects if the provided URI represents an HTTP(s) URL and if so,
748
+ fetches the file and provides its content.
749
+
750
+ ###### [Axios Request Config](https://axios-http.com/docs/req_config) support
751
+
752
+ HttpResolverAxios plugin supports all the options available in [Axios Request Config](https://axios-http.com/docs/req_config).
753
+ Config options can be provided in following way:
754
+
755
+ ```js
756
+ import { resolve } from '@speclynx/apidom-reference';
757
+
758
+ await resolve('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
759
+ resolve: {
760
+ resolverOpts: {
761
+ axiosConfig: {
762
+ timeout: 10000,
763
+ withCredentials: false,
764
+ responseType: 'json',
765
+ },
766
+ },
767
+ },
768
+ });
769
+ ```
770
+
771
+ ###### [Axios Interceptors](https://axios-http.com/docs/interceptors) support
772
+
773
+ HttpResolverAxios plugin supports [Axios Interceptors](https://axios-http.com/docs/interceptors).
774
+ Interceptors can be provided in following way:
775
+
776
+ ```js
777
+ import { resolve } from '@speclynx/apidom-reference';
778
+
779
+ const requestInterceptor = (config) => config;
780
+ const responseInterceptor = (response) => response;
781
+
782
+ await resolve('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
783
+ resolve: {
784
+ resolverOpts: {
785
+ axiosConfig: {
786
+ interceptors: {
787
+ request: requestInterceptor,
788
+ response: responseInterceptor,
789
+ },
790
+ },
791
+ },
792
+ },
793
+ });
794
+ ```
795
+
796
+ Multiple request and response interceptors can be provided in following way:
797
+
798
+ ```js
799
+ import { resolve } from '@speclynx/apidom-reference';
800
+
801
+ const requestInterceptor1 = (config) => config;
802
+ const requestInterceptor2 = (config) => config;
803
+ const responseInterceptor1 = (response) => response;
804
+ const responseInterceptor2 = async (error) => Promise.reject(error);
805
+
806
+ await resolve('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
807
+ resolve: {
808
+ resolverOpts: {
809
+ axiosConfig: {
810
+ interceptors: {
811
+ request: [requestInterceptor1, requestInterceptor2],
812
+ response: [responseInterceptor1, responseInterceptor2],
813
+ },
814
+ },
815
+ },
816
+ },
817
+ });
818
+ ```
819
+
820
+ **File resolution on local filesystem path**:
821
+
822
+ ```js
823
+ import { readFile } from '@speclynx/apidom-reference';
824
+
825
+ await readFile('/home/user/oas.json'); // Promise<Buffer>
826
+ ```
827
+
828
+ **File resolution on HTTP(s) URL:**
829
+
830
+ ```js
831
+ import { readFile } from '@speclynx/apidom-reference';
832
+
833
+ await readFile('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json'); // Promise<Buffer>
834
+ ```
835
+ File resolution always returns a [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) containing a [Buffer](https://nodejs.org/api/buffer.html).
836
+ It is responsibility of the API consumer to transform `Buffer` into `String` or any other type.
837
+
838
+ ```js
839
+ import { readFile } from '@speclynx/apidom-reference';
840
+
841
+ const buffer = await readFile('/home/user/oas.json');
842
+ const string = buffer.toString('utf-8');
843
+ ```
844
+
845
+ ##### Resolver plugins execution order
846
+
847
+ It's important to understand that default resolver plugins are run in specific order. The order is determined
848
+ by the [options.resolve.resolvers]https://github.com/speclynx/apidom/blob/ba888d711a4292e8ed0b72e343c4902a4bf0d45a/packages/apidom-reference/src/configuration/saturated.ts#L36) option.
849
+ Every plugin is pulled from `options.resolve.resolvers` option, and it's `canRead` method is called to determine
850
+ whether the plugin can resolve the URI. If `canRead` returns `true`, `read` method of plugin is called
851
+ and result from reading the file is returned. No subsequent resolver plugins are run.
852
+ If `canRead` returns `false`, next resolver plugin is pulled and this process is repeated until one
853
+ of the resolver plugins `canRead` method returns `true` or until entire list of resolver plugins is exhausted (throws error).
854
+
855
+ ```js
856
+ [
857
+ new FileResolver(),
858
+ new HTTPResolverAxios({ timeout: 5000, redirects: 5, withCredentials: false }),
859
+ ]
860
+ ```
861
+
862
+ It's possible to **change** resolver plugins **order globally** by mutating global `resolve` option:
863
+
864
+ ```js
865
+ import { options } from '@speclynx/apidom-reference';
866
+ import FileResolver from '@speclynx/apidom-reference/resolve/resolvers/file';
867
+ import HTTPResolverAxios from '@speclynx/apidom-reference/resolve/resolvers/http-axios';
868
+
869
+ options.resolve.resolvers = [
870
+ new HTTPResolverAxios({ timeout: 5000, redirects: 5, withCredentials: false }),
871
+ new FileResolver(),
872
+ ]
873
+ ```
874
+
875
+ To **change** resolver plugins **order** on ad-hoc basis:
876
+
877
+ ```js
878
+ import { readFile } from '@speclynx/apidom-reference';
879
+ import FileResolver from '@speclynx/apidom-reference/resolve/resolvers/file';
880
+ import HTTPResolverAxios from '@speclynx/apidom-reference/resolve/resolvers/http-axios';
881
+
882
+ await readFile('/home/user/oas.json', {
883
+ resolve: {
884
+ resolvers: [
885
+ new HTTPResolverAxios({ timeout: 5000, redirects: 5, withCredentials: false }),
886
+ new FileResolver(),
887
+ ],
888
+ },
889
+ });
890
+ ```
891
+
892
+ ##### Resolver plugin options
893
+
894
+ Some resolver plugins accept additional options. It's possible to **change** resolver plugin
895
+ **options globally** by mutating global `resolve` options:
896
+
897
+ ```js
898
+ import { options, readFile } from '@speclynx/apidom-reference';
899
+
900
+ options.resolve.resolverOpts = {
901
+ axiosConfig: {
902
+ timeout: 10000,
903
+ },
904
+ };
905
+
906
+ await readFile('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json');
907
+ ```
908
+
909
+ To **change** the resolver plugins **options** on ad-hoc basis:
910
+
911
+ ```js
912
+ import { readFile } from '@speclynx/apidom-reference';
913
+
914
+ await readFile('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
915
+ resolve: {
916
+ resolverOpts: {
917
+ axiosConfig: {
918
+ timeout: 10000,
919
+ },
920
+ },
921
+ },
922
+ });
923
+ ```
924
+
925
+ Both of above examples will be using [HttpResolverAxios](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/resolve/resolvers/http-axios) plugin
926
+ (as we're trying to resolve HTTP(s) URL) and the `timeout` of resolution will increase from **default 3 seconds**
927
+ to 10 seconds.
928
+
929
+ ##### Resolver strategy plugin options
930
+
931
+ Some resolver strategy plugins accept additional options. It's possible to **change** strategy plugin
932
+ **options globally** by mutating global `resolve` options:
933
+
934
+ ```js
935
+ import { options, resolve } from '@speclynx/apidom-reference';
936
+
937
+ options.resolve.strategyOpts = {
938
+ apidom: { clone: true },
939
+ };
940
+
941
+ await resolve('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json');
942
+ ```
943
+
944
+ To **change** the resolver strategy plugins **options** on ad-hoc basis:
945
+
946
+ ```js
947
+ import { resolve } from '@speclynx/apidom-reference';
948
+
949
+ await resolve('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
950
+ resolve: {
951
+ strategyOpts: {
952
+ apidom: { clone: true },
953
+ },
954
+ },
955
+ });
956
+ ```
957
+
958
+ ##### Creating new resolver plugin
959
+
960
+ Resolve component can be extended by additional resolver plugins. Every resolver plugin is an object that
961
+ must conform to the following interface/shape:
962
+
963
+ ```typescript
964
+ interface ResolverPlugin {
965
+ // uniquely identifies this plugin
966
+ readonly name: string;
967
+
968
+ // this method is called to determine whether the resolver plugin can resolve the file
969
+ canRead(file: File, options: ReferenceOptions): boolean;
970
+ // this method actually resolves the file
971
+ read(file: File, options: ReferenceOptions): Promise<Buffer>;
972
+ }
973
+ ```
974
+
975
+ New resolver plugin is then provided as an option to a `readFile` function:
976
+
977
+ ```ts
978
+ import { readFile, options, File, Resolver, ResolverOptions } from '@speclynx/apidom-reference';
979
+
980
+ interface MyCustomResolverOptions extends Omit<ResolverOptions, 'name'> {}
981
+
982
+ class MyCustomResolverPlugin extends Resolver {
983
+ constructor(options?: MyCustomResolverOptions) {
984
+ super({ ...(options ?? {}), name: 'my-custom-resolver' });
985
+ }
986
+
987
+ async canRead(file: File, options: typeof options) {
988
+ return true;
989
+ }
990
+
991
+ async read(file: File, options: typeof options) {
992
+ // implementation of file resolution
993
+ }
994
+ }
995
+
996
+ await readFile('/home/user/oas.json', {
997
+ resolve: {
998
+ resolvers: [...options.resolve.resolvers, new MyCustomResolverPlugin()],
999
+ }
1000
+ });
1001
+ ```
1002
+
1003
+ In this particular example we're adding our custom resolver plugin as the last plugin
1004
+ to the available default resolver plugin list, so there's a good chance that one of the
1005
+ default resolver plugins detects that it can resolve the `/home/user/oas.json` file,
1006
+ resolves it and returns its content.
1007
+
1008
+ If you want to force execution of your custom plugin, add it as a first resolver plugin:
1009
+
1010
+ ```ts
1011
+ import { readFile, options, File, Resolver, ResolverOptions } from '@speclynx/apidom-reference';
1012
+
1013
+ interface MyCustomResolverOptions extends Omit<ResolverOptions, 'name'> {}
1014
+
1015
+ class MyCustomResolverPlugin extends Resolver {
1016
+ constructor(options?: MyCustomResolverOptions) {
1017
+ super({ ...(options ?? {}), name: 'my-custom-resolver' });
1018
+ }
1019
+
1020
+ async canRead(file: File, options: typeof options) {
1021
+ return true;
1022
+ }
1023
+
1024
+ async read(file: File, options: typeof options) {
1025
+ // implementation of file resolution
1026
+ }
1027
+ }
1028
+
1029
+ await readFile('/home/user/oas.json', {
1030
+ resolve: {
1031
+ resolvers: [new MyCustomResolverPlugin(), ...options.resolve.resolvers],
1032
+ }
1033
+ });
1034
+ ```
1035
+
1036
+ To override the default resolver plugins entirely, set `myCustomResolverPlugin` plugin to be the only one available:
1037
+
1038
+ ```ts
1039
+ import { readFile, options, File, Resolver, ResolverOptions } from '@speclynx/apidom-reference';
1040
+
1041
+ interface MyCustomResolverOptions extends Omit<ResolverOptions, 'name'> {}
1042
+
1043
+ class MyCustomResolverPlugin extends Resolver {
1044
+ constructor(options?: MyCustomResolverOptions) {
1045
+ super({ ...(options ?? {}), name: 'my-custom-resolver' });
1046
+ }
1047
+
1048
+ async canRead(file: File, options: typeof options) {
1049
+ return true;
1050
+ }
1051
+
1052
+ async read(file: File, options: typeof options) {
1053
+ // implementation of file resolution
1054
+ }
1055
+ }
1056
+
1057
+ await readFile('/home/user/oas.json', {
1058
+ resolve: {
1059
+ resolvers: [new MyCustomResolverPlugin()],
1060
+ }
1061
+ });
1062
+ ```
1063
+ New resolver plugins can be based on two predefined stamps: [Resolver](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/resolve/resolvers/Resolver.ts) and [HTTPResolver](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/resolve/resolvers/HttpResolver.ts).
1064
+
1065
+ ##### Manipulating resolver plugins
1066
+
1067
+ Resolver plugins can be added, removed, replaced or reordered. We've already covered these techniques in [Manipulating parser plugins section](#manipulating-parser-plugins).
1068
+
1069
+ ### External resolution
1070
+
1071
+ External resolution is a process of resolving all external dependencies of a particular
1072
+ document using a specific [external resolution strategy](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies). External resolution strategy is determined by
1073
+ asserting on `mediaType` option. [File Resolution](#file-resolution) (file content is read/fetched)
1074
+ and [Parse component](#parse-component) (file content is parsed) are used under the hood.
1075
+
1076
+ **Externally resolving a file localed on a local filesystem:**
1077
+
1078
+ ```js
1079
+ import { resolve } from '@speclynx/apidom-reference';
1080
+
1081
+ await resolve('/home/user/oas.json', {
1082
+ parse: { mediType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1083
+ }); // Promise<ReferenceSet>
1084
+ ```
1085
+
1086
+ **Externally resolving an HTTP(S) URL located on an internet:**
1087
+
1088
+ ```js
1089
+ import { resolve } from '@speclynx/apidom-reference';
1090
+
1091
+ await resolve('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
1092
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1093
+ resolve: {
1094
+ resolverOpts: {
1095
+ axiosConfig: {
1096
+ timeout: 10
1097
+ },
1098
+ },
1099
+ },
1100
+ }); // Promise<ReferenceSet>
1101
+ ```
1102
+
1103
+ **Externally resolving an ApiDOM fragment:**
1104
+
1105
+ When externally resolving an ApiDOM fragment, [baseURI](https://github.com/speclynx/apidom/blob/91763fa4ad876375a413e7049c28c2031c7bbe83/apidom/packages/apidom-reference/src/options/index.ts#L47)
1106
+ resolve option needs to be provided to have a starting point for external dependency resolution.
1107
+ `mediaType` parse option is unnecessary as we can directly assert the type of ApiDOM fragment.
1108
+
1109
+ ```js
1110
+ import { OpenApi3_1Element } from '@speclynx/apidom-ns-openapi-3-1';
1111
+ import { resolveApiDOM } from '@speclynx/apidom-reference';
1112
+
1113
+ const apidom = OpenApi3_1Element.refract({
1114
+ openapi: '3.1.2',
1115
+ components: {
1116
+ parameters: {
1117
+ externalRef: {
1118
+ $ref: './ex.json#/externalParameter', // file is located at /home/user/ex.json
1119
+ }
1120
+ }
1121
+ }
1122
+ });
1123
+
1124
+ const refSet = await resolveApiDOM(apidom, {
1125
+ resolve: { baseURI: '/home/user/' },
1126
+ });
1127
+
1128
+ for (const ref of refSet) {
1129
+ console.log(ref.uri);
1130
+ }
1131
+ // /home/user
1132
+ // /home/user/ex.json
1133
+ ```
1134
+
1135
+ [ReferenceSet](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/ReferenceSet.ts) is a [Set](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set)
1136
+ like structure containing list of [Reference](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/Reference.ts) objects.
1137
+ Every Reference object represents single external dependency.
1138
+
1139
+ #### [External resolution strategies](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies)
1140
+
1141
+ External resolution strategy determines how a document is externally resolved. Depending on document `mediaType`
1142
+ every strategy differs significantly. Resolve component comes with two (2) default external resolution strategies.
1143
+
1144
+ ##### [apidom](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/apidom)
1145
+
1146
+ External resolution strategy for understanding and resolving remote elements referenced with [Ref Element](https://apielements.org/en/latest/element-definitions.html?highlight=referencing#ref-element).
1147
+
1148
+ Supported media types:
1149
+
1150
+ ```js
1151
+ [
1152
+ 'application/vnd.apidom',
1153
+ 'application/vnd.apidom+json'
1154
+ ]
1155
+ ```
1156
+
1157
+ ##### [asyncapi-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/asyncapi-2)
1158
+
1159
+ External resolution strategy for understanding and resolving external dependencies of [AsyncApi 2.x.y](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md) definitions.
1160
+
1161
+ Supported media types:
1162
+
1163
+ ```js
1164
+ [
1165
+ 'application/vnd.aai.asyncapi;version=2.0.0',
1166
+ 'application/vnd.aai.asyncapi+json;version=2.0.0',
1167
+ 'application/vnd.aai.asyncapi+yaml;version=2.0.0',
1168
+ 'application/vnd.aai.asyncapi;version=2.1.0',
1169
+ 'application/vnd.aai.asyncapi+json;version=2.1.0',
1170
+ 'application/vnd.aai.asyncapi+yaml;version=2.1.0',
1171
+ 'application/vnd.aai.asyncapi;version=2.2.0',
1172
+ 'application/vnd.aai.asyncapi+json;version=2.2.0',
1173
+ 'application/vnd.aai.asyncapi+yaml;version=2.2.0',
1174
+ 'application/vnd.aai.asyncapi;version=2.3.0',
1175
+ 'application/vnd.aai.asyncapi+json;version=2.3.0',
1176
+ 'application/vnd.aai.asyncapi+yaml;version=2.3.0',
1177
+ 'application/vnd.aai.asyncapi;version=2.4.0',
1178
+ 'application/vnd.aai.asyncapi+json;version=2.4.0',
1179
+ 'application/vnd.aai.asyncapi+yaml;version=2.4.0',
1180
+ 'application/vnd.aai.asyncapi;version=2.5.0',
1181
+ 'application/vnd.aai.asyncapi+json;version=2.5.0',
1182
+ 'application/vnd.aai.asyncapi+yaml;version=2.5.0',
1183
+ 'application/vnd.aai.asyncapi;version=2.6.0',
1184
+ 'application/vnd.aai.asyncapi+json;version=2.6.0',
1185
+ 'application/vnd.aai.asyncapi+yaml;version=2.6.0',
1186
+ ]
1187
+ ```
1188
+
1189
+ ##### [openapi-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/openapi-2)
1190
+
1191
+ External resolution strategy for understanding and resolving external dependencies of [OpenApi 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) definitions.
1192
+
1193
+ Supported media types:
1194
+
1195
+ ```js
1196
+ [
1197
+ 'application/vnd.oai.openapi;version=2.0',
1198
+ 'application/vnd.oai.openapi+json;version=2.0',
1199
+ 'application/vnd.oai.openapi+yaml;version=2.0',
1200
+ ]
1201
+ ```
1202
+
1203
+ ##### [openapi-3-0](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/openapi-3-0)
1204
+
1205
+ External resolution strategy for understanding and resolving external dependencies of [OpenApi 3.0.x](https://spec.openapis.org/oas/v3.0.4.html) definitions.
1206
+
1207
+ Supported media types:
1208
+
1209
+ ```js
1210
+ [
1211
+ 'application/vnd.oai.openapi;version=3.0.0',
1212
+ 'application/vnd.oai.openapi+json;version=3.0.0',
1213
+ 'application/vnd.oai.openapi+yaml;version=3.0.0',
1214
+ 'application/vnd.oai.openapi;version=3.0.1',
1215
+ 'application/vnd.oai.openapi+json;version=3.0.1',
1216
+ 'application/vnd.oai.openapi+yaml;version=3.0.1',
1217
+ 'application/vnd.oai.openapi;version=3.0.2',
1218
+ 'application/vnd.oai.openapi+json;version=3.0.2',
1219
+ 'application/vnd.oai.openapi+yaml;version=3.0.2',
1220
+ 'application/vnd.oai.openapi;version=3.0.3',
1221
+ 'application/vnd.oai.openapi+json;version=3.0.3',
1222
+ 'application/vnd.oai.openapi+yaml;version=3.0.3',
1223
+ 'application/vnd.oai.openapi;version=3.0.4',
1224
+ 'application/vnd.oai.openapi+json;version=3.0.4',
1225
+ 'application/vnd.oai.openapi+yaml;version=3.0.4',
1226
+ ]
1227
+ ```
1228
+
1229
+ ##### [openapi-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/resolve/strategies/openapi-3-1)
1230
+
1231
+ External resolution strategy for understanding and resolving external dependencies of [OpenApi 3.1.x](https://spec.openapis.org/oas/v3.1.2.html) definitions.
1232
+
1233
+ Supported media types:
1234
+
1235
+ ```js
1236
+ [
1237
+ 'application/vnd.oai.openapi;version=3.1.0',
1238
+ 'application/vnd.oai.openapi+json;version=3.1.0',
1239
+ 'application/vnd.oai.openapi+yaml;version=3.1.0',
1240
+ 'application/vnd.oai.openapi;version=3.1.1',
1241
+ 'application/vnd.oai.openapi+json;version=3.1.1',
1242
+ 'application/vnd.oai.openapi+yaml;version=3.1.1',
1243
+ 'application/vnd.oai.openapi;version=3.1.2',
1244
+ 'application/vnd.oai.openapi+json;version=3.1.2',
1245
+ 'application/vnd.oai.openapi+yaml;version=3.1.2'
1246
+ ]
1247
+ ```
1248
+
1249
+ ##### External resolution strategies execution order
1250
+
1251
+ It's important to understand that default external resolution strategies are run in specific order. The order is determined
1252
+ by the [options.resolve.strategies](https://github.com/speclynx/apidom/blob/ba888d711a4292e8ed0b72e343c4902a4bf0d45a/packages/apidom-reference/src/configuration/saturated.ts#L41) option.
1253
+ Every strategy is pulled from `options.resolve.strategies` option and its `canResolve` method is called to determine
1254
+ whether the strategy can externally resolve the URI. If `canResolve` returns `true`, `resolve` method of strategy is called
1255
+ and result from external resolution is returned. No subsequent strategies are run. If `canResolve` returns
1256
+ `false`, next strategy is pulled and this process is repeated until one of the strategy's `canResolve` method
1257
+ returns `true` or until entire list of strategies is exhausted (throws error).
1258
+
1259
+ ```js
1260
+ [
1261
+ new OpenAPI2ResolveStrategy(),
1262
+ new OpenAPI3_0ResolveStrategy(),
1263
+ new OpenAPI3_1ResolveStrategy(),
1264
+ new AsyncAPI2ResolveStrategy(),
1265
+ ]
1266
+ ```
1267
+ Most specific strategies are listed first, most generic are listed last.
1268
+
1269
+ It's possible to **change** strategies **order globally** by mutating global `resolve` option:
1270
+
1271
+ ```js
1272
+ import { options } from '@speclynx/apidom-reference';
1273
+ import AsyncAPI2ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/asyncapi-2';
1274
+ import OpenAPI2ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/openapi-2';
1275
+ import OpenAPI3_0ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/openapi-3-0';
1276
+ import OpenAPI3_1ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/openapi-3-1';
1277
+
1278
+ options.resolve.strategies = [
1279
+ new OpenAPI2ResolveStrategy(),
1280
+ new OpenAPI3_0ResolveStrategy(),
1281
+ new OpenAPI3_1ResolveStrategy(),
1282
+ new AsyncAPI2ResolveStrategy(),
1283
+ ];
1284
+ ```
1285
+
1286
+ To **change** the strategies **order** on ad-hoc basis:
1287
+
1288
+ ```js
1289
+ import { resolve } from '@speclynx/apidom-reference';
1290
+ import AsyncAPI2ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/asyncapi-2';
1291
+ import OpenAPI2ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/openapi-2';
1292
+ import OpenAPI3_0ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/openapi-3-0';
1293
+ import OpenAPI3_1ResolveStrategy from '@speclynx/apidom-reference/resolve/strategies/openapi-3-1';
1294
+
1295
+
1296
+ await resolve('/home/user/oas.json', {
1297
+ parse: {
1298
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
1299
+ },
1300
+ resolve: {
1301
+ strategies: [
1302
+ new AsyncAPI2ResolveStrategy(),
1303
+ new OpenAPI2ResolveStrategy(),
1304
+ new OpenAPI3_0ResolveStrategy(),
1305
+ new OpenAPI3_1ResolveStrategy(),
1306
+ ]
1307
+ }
1308
+ });
1309
+ ```
1310
+ ##### Creating new external resolution strategy
1311
+
1312
+ Resolve component can be extended by additional strategies. Every strategy is an object that
1313
+ must conform to the following interface/shape:
1314
+
1315
+ ```typescript
1316
+ interface ResolveStrategy {
1317
+ // uniquely identifies this plugin
1318
+ readonly name: string;
1319
+
1320
+ // this method is called to determine whether the strategy can externally resolve the file
1321
+ canResolve(file: File, options: ReferenceOptions): boolean;
1322
+ // this method actually externally resolves the file
1323
+ resolve(file: File, options: ReferenceOptions): Promise<ReferenceSet>;
1324
+ }
1325
+ ```
1326
+
1327
+ New strategy is then provided as an option to a `resolve` function:
1328
+
1329
+ ```ts
1330
+ import { resolve, options, File, ResolveStrategy, ResolveStrategyOptions } from '@speclynx/apidom-reference';
1331
+
1332
+ interface MyCustomResolverStrategyOptions extends Omit<ResolveStrategyOptions, 'name'> {}
1333
+
1334
+ class MyCustomResolverStrategy extends ResolveStrategy {
1335
+ constructor(options?: MyCustomResolverStrategyOptions) {
1336
+ super({ ...(options ?? {}), name: 'my-custom-resolver-strategy' });
1337
+ }
1338
+
1339
+ canResolve(file: File, options: typeof options) {
1340
+ return true;
1341
+ }
1342
+
1343
+ async resolve(file: File, options: typeof options) {
1344
+ // implementation of external resolution
1345
+ }
1346
+ }
1347
+
1348
+ await resolve('/home/user/oas.json', {
1349
+ parse: {
1350
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
1351
+ },
1352
+ resolve: {
1353
+ strategies: [...options.resolve.strategies, new MyCustomResolverStrategy()],
1354
+ }
1355
+ });
1356
+ ```
1357
+
1358
+ In this particular example we're adding our custom strategy as the last strategy
1359
+ to the available default external resolution strategy list, so there's a good chance that one of the
1360
+ default strategies detects that it can externally resolve the `/home/user/oas.json` file,
1361
+ resolves it and returns `ReferenceSet` object.
1362
+
1363
+ If you want to force execution of your strategy, add it as a first one:
1364
+
1365
+ ```ts
1366
+ import { resolve, options, File, ResolveStrategy, ResolveStrategyOptions } from '@speclynx/apidom-reference';
1367
+
1368
+ interface MyCustomResolverStrategyOptions extends Omit<ResolveStrategyOptions, 'name'> {}
1369
+
1370
+ class MyCustomResolverStrategy extends ResolveStrategy {
1371
+ constructor(options?: MyCustomResolverStrategyOptions) {
1372
+ super({ ...(options ?? {}), name: 'my-custom-resolver-strategy' });
1373
+ }
1374
+
1375
+ canResolve(file: File, options: typeof options) {
1376
+ return true;
1377
+ }
1378
+
1379
+ async resolve(file: File, options: typeof options) {
1380
+ // implementation of external resolution
1381
+ }
1382
+ }
1383
+
1384
+ await resolve('/home/user/oas.json', {
1385
+ parse: {
1386
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
1387
+ },
1388
+ resolve: {
1389
+ strategies: [new MyCustomResolverStrategy(), ...options.resolve.strategies],
1390
+ }
1391
+ });
1392
+ ```
1393
+
1394
+ To override the default strategies entirely, set `MyCustomResolverStrategy` strategy to be the only one available:
1395
+
1396
+ ```ts
1397
+ import { resolve, options, File, ResolveStrategy, ResolveStrategyOptions } from '@speclynx/apidom-reference';
1398
+
1399
+ interface MyCustomResolverStrategyOptions extends Omit<ResolveStrategyOptions, 'name'> {}
1400
+
1401
+ class MyCustomResolverStrategy extends ResolveStrategy {
1402
+ constructor(options?: MyCustomResolverStrategyOptions) {
1403
+ super({ ...(options ?? {}), name: 'my-custom-resolver-strategy' });
1404
+ }
1405
+
1406
+ canResolve(file: File, options: typeof options) {
1407
+ return true;
1408
+ }
1409
+
1410
+ async resolve(file: File, options: typeof options) {
1411
+ // implementation of external resolution
1412
+ }
1413
+ }
1414
+
1415
+ await resolve('/home/user/oas.json', {
1416
+ parse: {
1417
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
1418
+ },
1419
+ resolve: {
1420
+ strategies: [new MyCustomResolverPlugin()],
1421
+ }
1422
+ });
1423
+ ```
1424
+ New strategies can be based on a predefined stamp called [ResolveStrategy](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/resolve/strategies/ResolveStrategy.ts).
1425
+
1426
+ ##### Manipulating external resolution strategies
1427
+
1428
+ External resolution strategies can be added, removed, replaced or reordered. We've already covered these techniques in [Manipulating parser plugins section](#manipulating-parser-plugins).
1429
+
1430
+ ## Dereference component
1431
+
1432
+ Dereferencing is a process of transcluding referencing element (internal or external) with a referenced element
1433
+ using a specific [dereference strategy](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies). Simply put, dereferencing is a process of reference removal.
1434
+ Dereferencing strategy is determined by asserting on `mediaType` option. [File Resolution](#file-resolution) (file content is read/fetched)
1435
+ and [Parse component](#parse-component) (file content is parsed) are used under the hood.
1436
+
1437
+ **Dereferencing a file localed on a local filesystem:**
1438
+
1439
+ ```js
1440
+ import { dereference } from '@speclynx/apidom-reference';
1441
+
1442
+ await dereference('/home/user/oas.json', {
1443
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1444
+ }); // Promise<ParseResultElement>
1445
+ ```
1446
+
1447
+ **Dereferencing an HTTP(S) URL located on an internet:**
1448
+
1449
+ ```js
1450
+ import { dereference } from '@speclynx/apidom-reference';
1451
+
1452
+ await dereference('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
1453
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1454
+ resolve: {
1455
+ resolverOpts: {
1456
+ axiosConfig: {
1457
+ timeout: 10
1458
+ },
1459
+ },
1460
+ },
1461
+ }); // Promise<ParseResultElement>
1462
+ ```
1463
+
1464
+ **Dereferencing an ApiDOM fragment:**
1465
+
1466
+ When dereferencing an ApiDOM fragment, [baseURI](https://github.com/speclynx/apidom/blob/91763fa4ad876375a413e7049c28c2031c7bbe83/apidom/packages/apidom-reference/src/options/index.ts#L47)
1467
+ resolve option needs to be provided to have a starting point for external dependency resolution.
1468
+ `mediaType` parse option is unnecessary as we can directly assert the type of ApiDOM fragment.
1469
+
1470
+ **ex.json**
1471
+
1472
+ ```json
1473
+ {
1474
+ "externalParameter": {
1475
+ "name": "param1",
1476
+ "in": "query"
1477
+ }
1478
+ }
1479
+ ```
1480
+
1481
+ ```js
1482
+ import { OpenApi3_1Element } from '@speclynx/apidom-ns-openapi-3-1';
1483
+ import { dereferenceApiDOM } from '@speclynx/apidom-reference';
1484
+
1485
+ const apidom = OpenApi3_1Element.refract({
1486
+ openapi: '3.1.2',
1487
+ components: {
1488
+ parameters: {
1489
+ externalRef: {
1490
+ $ref: './ex.json#/externalParameter', // file is located at /home/user/ex.json
1491
+ }
1492
+ }
1493
+ }
1494
+ });
1495
+
1496
+ const dereferenced = await dereferenceApiDOM(apidom, {
1497
+ resolve: { baseURI: '/home/user/' },
1498
+ });
1499
+ /**
1500
+ * OpenApi3_1Element {
1501
+ * openapi: '3.1.2',
1502
+ * components: {
1503
+ * parameters: {
1504
+ * externalRef: {
1505
+ * name: param1,
1506
+ * in: query
1507
+ * }
1508
+ * }
1509
+ * }
1510
+ * }
1511
+ */
1512
+ ```
1513
+
1514
+ #### [Dereference strategies](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies)
1515
+
1516
+ Dereference strategy determines how a document is internally or externally dereferenced. Depending on document `mediaType` option,
1517
+ every strategy differs significantly. `Dereference component` comes with four (4) default dereference strategies.
1518
+
1519
+ #### [apidom](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies/apidom)
1520
+
1521
+ Dereference strategy for dereferencing ApiDOM using [Ref Element](https://apielements.org/en/latest/element-definitions.html?highlight=referencing#ref-element).
1522
+ Ref Element MAY be used to reference elements in remote documents or elements in the local document.
1523
+ The ref element transcludes the contents of the element into the document in which it is referenced.
1524
+
1525
+ Supported media types:
1526
+
1527
+ ```js
1528
+ [
1529
+ 'application/vnd.apidom',
1530
+ 'application/vnd.apidom+json',
1531
+ ]
1532
+ ```
1533
+
1534
+ ##### [asyncapi-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies/asyncapi-2)
1535
+
1536
+ Dereference strategy for dereferencing [AsyncApi 2.x.y](https://github.com/asyncapi/spec/blob/master/spec/asyncapi.md) definitions.
1537
+
1538
+ Supported media types:
1539
+
1540
+ ```js
1541
+ [
1542
+ 'application/vnd.aai.asyncapi;version=2.0.0',
1543
+ 'application/vnd.aai.asyncapi+json;version=2.0.0',
1544
+ 'application/vnd.aai.asyncapi+yaml;version=2.0.0',
1545
+ 'application/vnd.aai.asyncapi;version=2.1.0',
1546
+ 'application/vnd.aai.asyncapi+json;version=2.1.0',
1547
+ 'application/vnd.aai.asyncapi+yaml;version=2.1.0',
1548
+ 'application/vnd.aai.asyncapi;version=2.2.0',
1549
+ 'application/vnd.aai.asyncapi+json;version=2.2.0',
1550
+ 'application/vnd.aai.asyncapi+yaml;version=2.2.0',
1551
+ 'application/vnd.aai.asyncapi;version=2.3.0',
1552
+ 'application/vnd.aai.asyncapi+json;version=2.3.0',
1553
+ 'application/vnd.aai.asyncapi+yaml;version=2.3.0',
1554
+ 'application/vnd.aai.asyncapi;version=2.4.0',
1555
+ 'application/vnd.aai.asyncapi+json;version=2.4.0',
1556
+ 'application/vnd.aai.asyncapi+yaml;version=2.4.0',
1557
+ 'application/vnd.aai.asyncapi;version=2.5.0',
1558
+ 'application/vnd.aai.asyncapi+json;version=2.5.0',
1559
+ 'application/vnd.aai.asyncapi+yaml;version=2.5.0',
1560
+ 'application/vnd.aai.asyncapi;version=2.6.0',
1561
+ 'application/vnd.aai.asyncapi+json;version=2.6.0',
1562
+ 'application/vnd.aai.asyncapi+yaml;version=2.6.0',
1563
+ ]
1564
+ ```
1565
+
1566
+ ##### [openapi-2](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies/openapi-2)
1567
+
1568
+ Dereference strategy for dereferencing [OpenApi 2.0](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/2.0.md) definitions.
1569
+
1570
+ Supported media types:
1571
+
1572
+ ```js
1573
+ [
1574
+ 'application/vnd.oai.openapi;version=2.0',
1575
+ 'application/vnd.oai.openapi+json;version=2.0',
1576
+ 'application/vnd.oai.openapi+yaml;version=2.0',
1577
+ ]
1578
+ ```
1579
+
1580
+ ##### [openapi-3-0](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies/openapi-3-0)
1581
+
1582
+ Dereference strategy for dereferencing [OpenApi 3.0.x](https://spec.openapis.org/oas/v3.0.4.html) definitions.
1583
+
1584
+ Supported media types:
1585
+
1586
+ ```js
1587
+ [
1588
+ 'application/vnd.oai.openapi;version=3.0.0',
1589
+ 'application/vnd.oai.openapi+json;version=3.0.0',
1590
+ 'application/vnd.oai.openapi+yaml;version=3.0.0',
1591
+ 'application/vnd.oai.openapi;version=3.0.1',
1592
+ 'application/vnd.oai.openapi+json;version=3.0.1',
1593
+ 'application/vnd.oai.openapi+yaml;version=3.0.1',
1594
+ 'application/vnd.oai.openapi;version=3.0.2',
1595
+ 'application/vnd.oai.openapi+json;version=3.0.2',
1596
+ 'application/vnd.oai.openapi+yaml;version=3.0.2',
1597
+ 'application/vnd.oai.openapi;version=3.0.3',
1598
+ 'application/vnd.oai.openapi+json;version=3.0.3',
1599
+ 'application/vnd.oai.openapi+yaml;version=3.0.3',
1600
+ 'application/vnd.oai.openapi;version=3.0.4',
1601
+ 'application/vnd.oai.openapi+json;version=3.0.4',
1602
+ 'application/vnd.oai.openapi+yaml;version=3.0.4',
1603
+ ]
1604
+ ```
1605
+
1606
+ ##### [openapi-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/dereference/strategies/openapi-3-1)
1607
+
1608
+ Dereference strategy for dereferencing [OpenApi 3.1.x](https://spec.openapis.org/oas/v3.1.2.html) definitions.
1609
+
1610
+ Supported media types:
1611
+
1612
+ ```js
1613
+ [
1614
+ 'application/vnd.oai.openapi;version=3.1.0',
1615
+ 'application/vnd.oai.openapi+json;version=3.1.0',
1616
+ 'application/vnd.oai.openapi+yaml;version=3.1.0',
1617
+ 'application/vnd.oai.openapi;version=3.1.1',
1618
+ 'application/vnd.oai.openapi+json;version=3.1.1',
1619
+ 'application/vnd.oai.openapi+yaml;version=3.1.1',
1620
+ 'application/vnd.oai.openapi;version=3.1.2',
1621
+ 'application/vnd.oai.openapi+json;version=3.1.2',
1622
+ 'application/vnd.oai.openapi+yaml;version=3.1.2'
1623
+ ]
1624
+ ```
1625
+
1626
+ ##### Dereference strategies execution order
1627
+
1628
+ It's important to understand that default dereference strategies are run in specific order. The order is determined
1629
+ by the [options.dereference.strategies](https://github.com/speclynx/apidom/blob/b3a391481360004d3d4a56c1467cece557442ec8/apidom/packages/apidom-reference/src/options/index.ts#L88) option.
1630
+ Every strategy is pulled from `options.dereference.strategies` option and it's `canDereference` method is called to determine
1631
+ whether the strategy can dereference the URI. If `canDereference` returns `true`, `dereference` method of strategy is called
1632
+ and result from dereferencing is returned. No subsequent strategies are run. If `canDereference` returns
1633
+ `false`, next strategy is pulled and this process is repeated until one of the strategy's `canDereference` method
1634
+ returns `true` or until entire list of strategies is exhausted (throws error).
1635
+
1636
+ ```js
1637
+ [
1638
+ new OpenAPI2DereferenceStrategy(),
1639
+ new OpenAPI3_0DereferenceStrategy(),
1640
+ new OpenAPI3_1DereferenceStrategy(),
1641
+ new AsyncAPI2DereferenceStrategy(),
1642
+ new ApiDOMDereferenceStrategy(),
1643
+ ]
1644
+ ```
1645
+ Most specific strategies are listed first, most generic are listed last.
1646
+
1647
+ It's possible to **change** strategies **order globally** by mutating global `dereference` option:
1648
+
1649
+ ```js
1650
+ import { options } from '@speclynx/apidom-reference';
1651
+ import AsyncAPI2DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/asyncapi-2';
1652
+ import OpenAPI2DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/openapi-2';
1653
+ import OpenAPI3_0DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/openapi-3-0';
1654
+ import OpenAPI3_1DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/openapi-3-1';
1655
+ import ApiDOMDereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/apidom';
1656
+
1657
+ options.dereference.strategies = [
1658
+ new OpenAPI2DereferenceStrategy(),
1659
+ new OpenAPI3_0DereferenceStrategy(),
1660
+ new OpenAPI3_1DereferenceStrategy(),
1661
+ new AsyncAPI2DereferenceStrategy(),
1662
+ new ApiDOMDereferenceStrategy(),
1663
+ ];
1664
+ ```
1665
+
1666
+ To **change** the strategies **order** on ad-hoc basis:
1667
+
1668
+ ```js
1669
+ import { dereference } from '@speclynx/apidom-reference';
1670
+ import AsyncAPI2DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/asyncapi-2';
1671
+ import OpenAPI2DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/openapi-2';
1672
+ import OpenAPI3_0DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/openapi-3-0';
1673
+ import OpenAPI3_1DereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/openapi-3-1';
1674
+ import ApiDOMDereferenceStrategy from '@speclynx/apidom-reference/dereference/strategies/apidom';
1675
+
1676
+
1677
+ await dereference('/home/user/oas.json', {
1678
+ parse: {
1679
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
1680
+ },
1681
+ dereference: {
1682
+ strategies: [
1683
+ new AsyncAPI2DereferenceStrategy(),
1684
+ new OpenAPI2DereferenceStrategy(),
1685
+ new OpenAPI3_0DereferenceStrategy(),
1686
+ new OpenAPI3_1DereferenceStrategy(),
1687
+ new ApiDOMDereferenceStrategy(),
1688
+ ]
1689
+ }
1690
+ });
1691
+ ```
1692
+
1693
+ ##### Dereference strategy plugin options
1694
+
1695
+ Some dereference strategy plugins accept additional options. It's possible to **change** strategy plugin
1696
+ **options globally** by mutating global `dereference` options:
1697
+
1698
+ ```js
1699
+ import { options, dereference } from '@speclynx/apidom-reference';
1700
+
1701
+ options.dereference.strategyOpts = {
1702
+ apidom: { clone: true },
1703
+ };
1704
+
1705
+ await dereference('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json');
1706
+ ```
1707
+
1708
+ To **change** the dereference strategy plugins **options** on ad-hoc basis:
1709
+
1710
+ ```js
1711
+ import { dereference } from '@speclynx/apidom-reference';
1712
+
1713
+ await dereference('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
1714
+ dereference: {
1715
+ strategyOpts: {
1716
+ apidom: { clone: true },
1717
+ },
1718
+ },
1719
+ });
1720
+ ```
1721
+
1722
+ ##### Creating new dereference strategy
1723
+
1724
+ Dereference component can be extended by additional strategies. Every strategy is an object that
1725
+ must conform to the following interface/shape:
1726
+
1727
+ ```ts
1728
+ interface DereferenceStrategy {
1729
+ // uniquely identifies this plugin
1730
+ readonly name: string,
1731
+
1732
+ // this method is called to determine whether the strategy can dereference the file
1733
+ canDereference(file: File, options: ReferenceOptions): boolean;
1734
+ // this method actually dereferences the file
1735
+ dereference(file: File, options: ReferenceOptions): Promise<Element>;
1736
+ }
1737
+ ```
1738
+
1739
+ New strategy is then provided as an option to the `dereference` function:
1740
+
1741
+ ```ts
1742
+ import { dereference, options, File, DereferenceStrategy, DereferenceStrategyOptions } from '@speclynx/apidom-reference';
1743
+
1744
+ export interface MyCustomDereferenceStrategyOptions
1745
+ extends Omit<DereferenceStrategyOptions, 'name'> {}
1746
+
1747
+ class MyCustomDereferenceStrategy extends DereferenceStrategy {
1748
+ constructor(options?: MyCustomDereferenceStrategyOptions) {
1749
+ super({ ...(options ?? {}), name: 'my-custom-dereference' });
1750
+ }
1751
+
1752
+ canDereference(file: File, options: typeof options) {
1753
+ return true;
1754
+ }
1755
+
1756
+ async dereference(file: File, options: typeof options) {
1757
+ // implementation of dereferenceing
1758
+ }
1759
+ }
1760
+
1761
+ await dereference('/home/user/oas.json', {
1762
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1763
+ dereference: {
1764
+ strategies: [...options.dereference.strategies, new MyCustomDereferenceStrategy()],
1765
+ }
1766
+ });
1767
+ ```
1768
+
1769
+ In this particular example we're adding our custom strategy as the last strategy
1770
+ to the available default dereference strategy list, so there's a good chance that one of the
1771
+ default strategies detects that it can dereference the `/home/user/oas.json` file,
1772
+ dereferences it and returns a dereferenced element.
1773
+
1774
+ If you want to force execution of your strategy, add it as a first one:
1775
+
1776
+ ```ts
1777
+ import { dereference, options, File, DereferenceStrategy, DereferenceStrategyOptions } from '@speclynx/apidom-reference';
1778
+
1779
+ export interface MyCustomDereferenceStrategyOptions
1780
+ extends Omit<DereferenceStrategyOptions, 'name'> {}
1781
+
1782
+ class MyCustomDereferenceStrategy extends DereferenceStrategy {
1783
+ constructor(options?: MyCustomDereferenceStrategyOptions) {
1784
+ super({ ...(options ?? {}), name: 'my-custom-dereference' });
1785
+ }
1786
+
1787
+ canDereference(file: File, options: typeof options) {
1788
+ return true;
1789
+ }
1790
+
1791
+ async dereference(file: File, options: typeof options) {
1792
+ // implementation of dereferenceing
1793
+ }
1794
+ }
1795
+
1796
+ await dereference('/home/user/oas.json', {
1797
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1798
+ dereference: {
1799
+ strategies: [new MyCustomDereferenceStrategy(), ...options.dereference.strategies],
1800
+ }
1801
+ });
1802
+ ```
1803
+
1804
+ To override the default strategies entirely, set `MyCustomDereferenceStrategy` strategy to be the only one available:
1805
+
1806
+ ```ts
1807
+ import { dereference, options, File, DereferenceStrategy, DereferenceStrategyOptions } from '@speclynx/apidom-reference';
1808
+
1809
+ export interface MyCustomDereferenceStrategyOptions
1810
+ extends Omit<DereferenceStrategyOptions, 'name'> {}
1811
+
1812
+ class MyCustomDereferenceStrategy extends DereferenceStrategy {
1813
+ constructor(options?: MyCustomDereferenceStrategyOptions) {
1814
+ super({ ...(options ?? {}), name: 'my-custom-dereference' });
1815
+ }
1816
+
1817
+ canDereference(file: File, options: typeof options) {
1818
+ return true;
1819
+ }
1820
+
1821
+ async dereference(file: File, options: typeof options) {
1822
+ // implementation of dereferenceing
1823
+ }
1824
+ }
1825
+
1826
+
1827
+ await dereference('/home/user/oas.json', {
1828
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1829
+ dereference: {
1830
+ strategies: [new MyCustomDereferenceStrategy()],
1831
+ }
1832
+ });
1833
+ ```
1834
+
1835
+ New strategies can be based on a predefined stamp called [DereferenceStrategy](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/dereference/strategies/DereferenceStrategy.ts).
1836
+
1837
+ ##### Manipulating dereference strategies
1838
+
1839
+ Dereference strategies can be added, removed, replaced or reordered. We've already covered these techniques in [Manipulating parser plugins section](#manipulating-parser-plugins).
1840
+
1841
+ ##### Increasing speed of dereference
1842
+
1843
+ Our default dereference strategies are built on asynchronous sequential traversing of ApiDOM.
1844
+ The total time of dereferencing is the sum of `traversing` + sum of `external resolution per file`.
1845
+ By having a huge number of external dependencies in your definition file, dereferencing can get quite slow.
1846
+ Fortunately there is solution for this by running an `external resolution` first,
1847
+ and passing its result to dereferencing via an option. External resolution ignores internal references,
1848
+ so it's theoretically always faster than the dereferencing.
1849
+
1850
+ ```js
1851
+ import { resolve, dereference } from '@speclynx/apidom-reference';
1852
+
1853
+ const refSet = await resolve('/home/user/oas.json', {
1854
+ parse: { mediType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1855
+ });
1856
+
1857
+ const dereferenced = await dereference('/home/user/oas.json', {
1858
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1859
+ dereference: { refSet },
1860
+ });
1861
+ ```
1862
+
1863
+ ## Bundle component
1864
+
1865
+ Bundling is a convenient way to package up resources spread across multiple files in a single file
1866
+ (**Compound Document**) using a specific [bundle strategy](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/bundle/strategies).
1867
+
1868
+ The bundling process for creating a Compound Document is defined as taking references (such as "$ref")
1869
+ to an external Resource and embedding the referenced Resources within the referring document.
1870
+ Bundling SHOULD be done in such a way that all URIs (used for referencing) in the base document
1871
+ and any referenced/embedded documents do not require altering.
1872
+
1873
+ Bundling strategy is determined by asserting on `mediaType` option. [File Resolution](#file-resolution) (file content is read/fetched)
1874
+ and [Parse component](#parse-component) (file content is parsed) are used under the hood.
1875
+
1876
+ **Bundling a file localed on a local filesystem:**
1877
+
1878
+ ```js
1879
+ import { bundle } from '@speclynx/apidom-reference';
1880
+
1881
+ await bundle('/home/user/oas.json', {
1882
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1883
+ }); // Promise<ParseResultElement>
1884
+ ```
1885
+
1886
+ **Bundling an HTTP(S) URL located on an internet:**
1887
+
1888
+ ```js
1889
+ import { bundle } from '@speclynx/apidom-reference';
1890
+
1891
+ await bundle('https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.1/webhook-example.json', {
1892
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
1893
+ resolve: {
1894
+ resolverOpts: {
1895
+ axiosConfig: {
1896
+ timeout: 10
1897
+ },
1898
+ },
1899
+ },
1900
+ }); // Promise<ParseResultElement>
1901
+ ```
1902
+
1903
+ #### [Bundle strategies](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/bundle/strategies)
1904
+
1905
+ Bundle strategy determines how a document is bundled into a Compound Document. Depending on document `mediaType` option,
1906
+ every strategy differs significantly. `Bundle component` comes with single (1) default bundle strategy.
1907
+
1908
+ ##### [openapi-3-1](https://github.com/speclynx/apidom/tree/main/packages/apidom-reference/src/bundle/strategies/openapi-3-1)
1909
+
1910
+ Bundle strategy for bundling [OpenApi 3.1.x](https://spec.openapis.org/oas/v3.1.2.html) definitions.
1911
+
1912
+ Supported media types:
1913
+
1914
+ ```js
1915
+ [
1916
+ 'application/vnd.oai.openapi;version=3.1.0',
1917
+ 'application/vnd.oai.openapi+json;version=3.1.0',
1918
+ 'application/vnd.oai.openapi+yaml;version=3.1.0',
1919
+ 'application/vnd.oai.openapi;version=3.1.1',
1920
+ 'application/vnd.oai.openapi+json;version=3.1.1',
1921
+ 'application/vnd.oai.openapi+yaml;version=3.1.1',
1922
+ 'application/vnd.oai.openapi;version=3.1.2',
1923
+ 'application/vnd.oai.openapi+json;version=3.1.2',
1924
+ 'application/vnd.oai.openapi+yaml;version=3.1.2'
1925
+ ]
1926
+ ```
1927
+
1928
+ ##### Bundle strategies execution order
1929
+
1930
+ It's important to understand that default bundle strategies are run in specific order. The order is determined
1931
+ by the `options.bundle.strategies` option.
1932
+ Every strategy is pulled from `options.bundle.strategies` option, and it's `canBundle` method is called to determine
1933
+ whether the strategy can bundle the URI. If `canBundle` returns `true`, `bundle` method of strategy is called
1934
+ and result from bundling is returned. No subsequent strategies are run. If `canBundle` returns
1935
+ `false`, next strategy is pulled and this process is repeated until one of the strategy's `canBundle` method
1936
+ returns `true` or until entire list of strategies is exhausted (throws error).
1937
+
1938
+ ```js
1939
+ [
1940
+ new OpenAPI3_1BundleStrategy(),
1941
+ ]
1942
+ ```
1943
+ Most specific strategies are listed first, most generic are listed last.
1944
+
1945
+ It's possible to **change** strategies **order globally** by mutating global `bundle` option:
1946
+
1947
+ ```js
1948
+ import { options } from '@speclynx/apidom-reference';
1949
+ import OpenAPI3_1BundleStrategy from '@speclynx/apidom-reference/bundle/strategies/openapi-3-1'
1950
+
1951
+ options.dereference.strategies = [
1952
+ new OpenAPI3_1DereferenceStrategy(),
1953
+ ];
1954
+ ```
1955
+
1956
+ To **change** the strategies **order** on ad-hoc basis:
1957
+
1958
+ ```js
1959
+ import { bundle } from '@speclynx/apidom-reference';
1960
+ import OpenAPI3_1BundleStrategy from '@speclynx/apidom-reference/bundle/strategies/openapi-3-1'
1961
+
1962
+ await bundle('/home/user/oas.json', {
1963
+ parse: {
1964
+ mediaType: 'application/vnd.oai.openapi+json;version=3.1.2',
1965
+ },
1966
+ bundle: {
1967
+ strategies: [
1968
+ new OpenAPI3_1BundleStrategy(),
1969
+ ]
1970
+ }
1971
+ });
1972
+ ```
1973
+ ##### Creating new bundle strategy
1974
+
1975
+ Bundle component can be extended by additional strategies. Every strategy is an object that
1976
+ must conform to the following interface/shape:
1977
+
1978
+ ```typescript
1979
+ interface BundleStrategy {
1980
+ // uniquely identifies this plugin
1981
+ readonly name: string;
1982
+
1983
+ // this method is called to determine whether the strategy can bundle the file
1984
+ canBundle(file: File, options: ReferenceOptions): boolean;
1985
+ // this method actually bundles the file
1986
+ bundle(file: File, options: ReferenceOptions): Promise<ParseResultElement>;
1987
+ }
1988
+ ```
1989
+
1990
+ New strategy is then provided as an option to the `bundle` function:
1991
+
1992
+ ```ts
1993
+ import { bundle, options, File, BundleStrategy } from '@speclynx/apidom-reference';
1994
+
1995
+ interface MyCustomBundleStrategyOptions extends Omit<BundleStrategyOptions, 'name'> {}
1996
+
1997
+ class MyCustomBundleStrategy extends BundleStrategy {
1998
+ constructor(options?: MyCustomBundleStrategyOptions) {
1999
+ super({ ...(options ?? {}), name: 'my-custom-bundle-strategy' });
2000
+ }
2001
+
2002
+ canBundle(file: File, options: typeof options) {
2003
+ return true;
2004
+ }
2005
+ async bundle(file: File, options: typeof options) {
2006
+ // implementation of bundling
2007
+ }
2008
+ }
2009
+
2010
+ await bundle('/home/user/oas.json', {
2011
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
2012
+ bundle: {
2013
+ strategies: [...options.bundle.strategies, new MyCustomBundleStrategy()],
2014
+ }
2015
+ });
2016
+ ```
2017
+
2018
+ In this particular example we're adding our custom strategy as the last strategy
2019
+ to the available default bundle strategy list, so there's a good chance that one of the
2020
+ default strategies detects that it can bundle the `/home/user/oas.json` file,
2021
+ bundles it and returns a bundled element.
2022
+
2023
+ If you want to force execution of your strategy, add it as a first one:
2024
+
2025
+ ```ts
2026
+ import { bundle, options, File, BundleStrategy } from '@speclynx/apidom-reference';
2027
+
2028
+ interface MyCustomBundleStrategyOptions extends Omit<BundleStrategyOptions, 'name'> {}
2029
+
2030
+ class MyCustomBundleStrategy extends BundleStrategy {
2031
+ constructor(options?: MyCustomBundleStrategyOptions) {
2032
+ super({ ...(options ?? {}), name: 'my-custom-bundle-strategy' });
2033
+ }
2034
+
2035
+ canBundle(file: File, options: typeof options) {
2036
+ return true;
2037
+ }
2038
+ async bundle(file: File, options: typeof options) {
2039
+ // implementation of bundling
2040
+ }
2041
+ }
2042
+
2043
+ await bundle('/home/user/oas.json', {
2044
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
2045
+ bundle: {
2046
+ strategies: [new MyCustomBundleStrategy(), ...options.bundle.strategies],
2047
+ }
2048
+ });
2049
+ ```
2050
+
2051
+ To override the default strategies entirely, set `MyCustomBundleStrategy` strategy to be the only one available:
2052
+
2053
+ ```ts
2054
+ import { bundle, options, File, BundleStrategy } from '@speclynx/apidom-reference';
2055
+
2056
+ interface MyCustomBundleStrategyOptions extends Omit<BundleStrategyOptions, 'name'> {}
2057
+
2058
+ class MyCustomBundleStrategy extends BundleStrategy {
2059
+ constructor(options?: MyCustomBundleStrategyOptions) {
2060
+ super({ ...(options ?? {}), name: 'my-custom-bundle-strategy' });
2061
+ }
2062
+
2063
+ canBundle(file: File, options: typeof options) {
2064
+ return true;
2065
+ }
2066
+ async bundle(file: File, options: typeof options) {
2067
+ // implementation of bundling
2068
+ }
2069
+ }
2070
+
2071
+ await bundle('/home/user/oas.json', {
2072
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
2073
+ bundle: {
2074
+ strategies: [new MyCustomBundleStrategy()],
2075
+ }
2076
+ });
2077
+ ```
2078
+
2079
+ New strategies can be based on a predefined stamp called [BundleStrategy](https://github.com/speclynx/apidom/blob/main/packages/apidom-reference/src/bundle/strategies/BundleStrategy.ts).
2080
+
2081
+ ##### Manipulating bundle strategies
2082
+
2083
+ Bundle strategies can be added, removed, replaced or reordered. We've already covered these techniques in [Manipulating parser plugins section](#manipulating-parser-plugins).
2084
+
2085
+ ##### Increasing speed of bundling
2086
+
2087
+ Our default bundling strategies are built on asynchronous sequential traversing of ApiDOM.
2088
+ The total time of bundling is the sum of `traversing` + sum of `external resolution per referencing element`.
2089
+ By having a huge number of external dependencies in your definition file, bundling can get quite slow.
2090
+ Fortunately there is solution for this by running an `external resolution` first,
2091
+ and passing its result to bundling via an option. External resolution is built on asynchronous parallel traversal (on single file),
2092
+ so it's theoretically always faster on huge amount of external dependencies than the bundling.
2093
+
2094
+ ```js
2095
+ import { resolve, bundle } from '@speclynx/apidom-reference';
2096
+
2097
+ const refSet = await resolve('/home/user/oas.json', {
2098
+ parse: { mediType: 'application/vnd.oai.openapi+json;version=3.1.2' },
2099
+ });
2100
+
2101
+ const bundled = await bundle('/home/user/oas.json', {
2102
+ parse: { mediaType: 'application/vnd.oai.openapi+json;version=3.1.2' },
2103
+ bundle: { refSet },
2104
+ });
2105
+ ```
2106
+
2107
+ Total time of bundling is now the sum of `external resolution traversing` + `bundle traversing` + sum of `max external resolution per file`.