@speclynx/apidom-ns-openapi-3-1 4.0.2 → 4.0.3

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 (287) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/package.json +9 -10
  3. package/src/elements/Callback.cjs +10 -0
  4. package/src/elements/Callback.mjs +7 -0
  5. package/src/elements/Callback.ts +8 -0
  6. package/src/elements/Components.cjs +17 -0
  7. package/src/elements/Components.mjs +14 -0
  8. package/src/elements/Components.ts +17 -0
  9. package/src/elements/Contact.cjs +10 -0
  10. package/src/elements/Contact.mjs +7 -0
  11. package/src/elements/Contact.ts +8 -0
  12. package/src/elements/Discriminator.cjs +10 -0
  13. package/src/elements/Discriminator.mjs +7 -0
  14. package/src/elements/Discriminator.ts +8 -0
  15. package/src/elements/Encoding.cjs +10 -0
  16. package/src/elements/Encoding.mjs +7 -0
  17. package/src/elements/Encoding.ts +8 -0
  18. package/src/elements/Example.cjs +10 -0
  19. package/src/elements/Example.mjs +7 -0
  20. package/src/elements/Example.ts +8 -0
  21. package/src/elements/ExternalDocumentation.cjs +10 -0
  22. package/src/elements/ExternalDocumentation.mjs +7 -0
  23. package/src/elements/ExternalDocumentation.ts +8 -0
  24. package/src/elements/Header.cjs +17 -0
  25. package/src/elements/Header.mjs +13 -0
  26. package/src/elements/Header.ts +18 -0
  27. package/src/elements/Info.cjs +23 -0
  28. package/src/elements/Info.mjs +19 -0
  29. package/src/elements/Info.ts +27 -0
  30. package/src/elements/JsonSchemaDialect.cjs +16 -0
  31. package/src/elements/JsonSchemaDialect.mjs +13 -0
  32. package/src/elements/JsonSchemaDialect.ts +15 -0
  33. package/src/elements/License.cjs +17 -0
  34. package/src/elements/License.mjs +14 -0
  35. package/src/elements/License.ts +17 -0
  36. package/src/elements/Link.cjs +10 -0
  37. package/src/elements/Link.mjs +7 -0
  38. package/src/elements/Link.ts +8 -0
  39. package/src/elements/MediaType.cjs +17 -0
  40. package/src/elements/MediaType.mjs +13 -0
  41. package/src/elements/MediaType.ts +18 -0
  42. package/src/elements/OAuthFlow.cjs +10 -0
  43. package/src/elements/OAuthFlow.mjs +7 -0
  44. package/src/elements/OAuthFlow.ts +8 -0
  45. package/src/elements/OAuthFlows.cjs +10 -0
  46. package/src/elements/OAuthFlows.mjs +7 -0
  47. package/src/elements/OAuthFlows.ts +8 -0
  48. package/src/elements/OpenApi3-1.cjs +77 -0
  49. package/src/elements/OpenApi3-1.mjs +73 -0
  50. package/src/elements/OpenApi3-1.ts +107 -0
  51. package/src/elements/Openapi.cjs +10 -0
  52. package/src/elements/Openapi.mjs +7 -0
  53. package/src/elements/Openapi.ts +8 -0
  54. package/src/elements/Operation.cjs +17 -0
  55. package/src/elements/Operation.mjs +13 -0
  56. package/src/elements/Operation.ts +19 -0
  57. package/src/elements/Parameter.cjs +17 -0
  58. package/src/elements/Parameter.mjs +13 -0
  59. package/src/elements/Parameter.ts +18 -0
  60. package/src/elements/PathItem.cjs +59 -0
  61. package/src/elements/PathItem.mjs +55 -0
  62. package/src/elements/PathItem.ts +74 -0
  63. package/src/elements/Paths.cjs +10 -0
  64. package/src/elements/Paths.mjs +7 -0
  65. package/src/elements/Paths.ts +8 -0
  66. package/src/elements/Reference.cjs +28 -0
  67. package/src/elements/Reference.mjs +25 -0
  68. package/src/elements/Reference.ts +29 -0
  69. package/src/elements/RequestBody.cjs +10 -0
  70. package/src/elements/RequestBody.mjs +7 -0
  71. package/src/elements/RequestBody.ts +8 -0
  72. package/src/elements/Response.cjs +10 -0
  73. package/src/elements/Response.mjs +7 -0
  74. package/src/elements/Response.ts +8 -0
  75. package/src/elements/Responses.cjs +10 -0
  76. package/src/elements/Responses.mjs +7 -0
  77. package/src/elements/Responses.ts +8 -0
  78. package/src/elements/Schema.cjs +50 -0
  79. package/src/elements/Schema.mjs +46 -0
  80. package/src/elements/Schema.ts +59 -0
  81. package/src/elements/SecurityRequirement.cjs +10 -0
  82. package/src/elements/SecurityRequirement.mjs +7 -0
  83. package/src/elements/SecurityRequirement.ts +8 -0
  84. package/src/elements/SecurityScheme.cjs +10 -0
  85. package/src/elements/SecurityScheme.mjs +7 -0
  86. package/src/elements/SecurityScheme.ts +8 -0
  87. package/src/elements/Server.cjs +10 -0
  88. package/src/elements/Server.mjs +7 -0
  89. package/src/elements/Server.ts +8 -0
  90. package/src/elements/ServerVariable.cjs +10 -0
  91. package/src/elements/ServerVariable.mjs +7 -0
  92. package/src/elements/ServerVariable.ts +8 -0
  93. package/src/elements/Tag.cjs +10 -0
  94. package/src/elements/Tag.mjs +7 -0
  95. package/src/elements/Tag.ts +8 -0
  96. package/src/elements/Xml.cjs +10 -0
  97. package/src/elements/Xml.mjs +7 -0
  98. package/src/elements/Xml.ts +8 -0
  99. package/src/elements/nces/ComponentsPathItems.cjs +16 -0
  100. package/src/elements/nces/ComponentsPathItems.mjs +13 -0
  101. package/src/elements/nces/ComponentsPathItems.ts +15 -0
  102. package/src/elements/nces/Webhooks.cjs +16 -0
  103. package/src/elements/nces/Webhooks.mjs +13 -0
  104. package/src/elements/nces/Webhooks.ts +15 -0
  105. package/src/index.cjs +182 -0
  106. package/src/index.mjs +31 -0
  107. package/src/index.ts +592 -0
  108. package/src/media-types.cjs +34 -0
  109. package/src/media-types.mjs +30 -0
  110. package/src/media-types.ts +46 -0
  111. package/src/namespace.cjs +81 -0
  112. package/src/namespace.mjs +76 -0
  113. package/src/namespace.ts +80 -0
  114. package/src/predicates.cjs +228 -0
  115. package/src/predicates.mjs +195 -0
  116. package/src/predicates.ts +229 -0
  117. package/src/refractor/index.cjs +368 -0
  118. package/src/refractor/index.mjs +330 -0
  119. package/src/refractor/index.ts +380 -0
  120. package/src/refractor/inspect.cjs +207 -0
  121. package/src/refractor/inspect.mjs +171 -0
  122. package/src/refractor/inspect.ts +241 -0
  123. package/src/refractor/plugins/normalize-header-examples/NormalizeStorage.cjs +38 -0
  124. package/src/refractor/plugins/normalize-header-examples/NormalizeStorage.mjs +34 -0
  125. package/src/refractor/plugins/normalize-header-examples/NormalizeStorage.ts +53 -0
  126. package/src/refractor/plugins/normalize-header-examples/index.cjs +109 -0
  127. package/src/refractor/plugins/normalize-header-examples/index.mjs +103 -0
  128. package/src/refractor/plugins/normalize-header-examples/index.ts +125 -0
  129. package/src/refractor/plugins/normalize-operation-ids.cjs +166 -0
  130. package/src/refractor/plugins/normalize-operation-ids.mjs +161 -0
  131. package/src/refractor/plugins/normalize-operation-ids.ts +198 -0
  132. package/src/refractor/plugins/normalize-parameter-examples.cjs +109 -0
  133. package/src/refractor/plugins/normalize-parameter-examples.mjs +103 -0
  134. package/src/refractor/plugins/normalize-parameter-examples.ts +128 -0
  135. package/src/refractor/plugins/normalize-parameters.cjs +109 -0
  136. package/src/refractor/plugins/normalize-parameters.mjs +103 -0
  137. package/src/refractor/plugins/normalize-parameters.ts +136 -0
  138. package/src/refractor/plugins/normalize-security-requirements.cjs +75 -0
  139. package/src/refractor/plugins/normalize-security-requirements.mjs +69 -0
  140. package/src/refractor/plugins/normalize-security-requirements.ts +87 -0
  141. package/src/refractor/plugins/normalize-servers.cjs +124 -0
  142. package/src/refractor/plugins/normalize-servers.mjs +118 -0
  143. package/src/refractor/plugins/normalize-servers.ts +144 -0
  144. package/src/refractor/plugins/replace-empty-element.cjs +669 -0
  145. package/src/refractor/plugins/replace-empty-element.mjs +661 -0
  146. package/src/refractor/plugins/replace-empty-element.ts +726 -0
  147. package/src/refractor/predicates.cjs +36 -0
  148. package/src/refractor/predicates.mjs +31 -0
  149. package/src/refractor/predicates.ts +39 -0
  150. package/src/refractor/specification.cjs +531 -0
  151. package/src/refractor/specification.mjs +526 -0
  152. package/src/refractor/specification.ts +594 -0
  153. package/src/refractor/toolbox.cjs +61 -0
  154. package/src/refractor/toolbox.mjs +53 -0
  155. package/src/refractor/toolbox.ts +70 -0
  156. package/src/refractor/visitors/open-api-3-1/JsonSchemaDialectVisitor.cjs +25 -0
  157. package/src/refractor/visitors/open-api-3-1/JsonSchemaDialectVisitor.mjs +19 -0
  158. package/src/refractor/visitors/open-api-3-1/JsonSchemaDialectVisitor.ts +32 -0
  159. package/src/refractor/visitors/open-api-3-1/OpenapiVisitor.cjs +25 -0
  160. package/src/refractor/visitors/open-api-3-1/OpenapiVisitor.mjs +19 -0
  161. package/src/refractor/visitors/open-api-3-1/OpenapiVisitor.ts +30 -0
  162. package/src/refractor/visitors/open-api-3-1/WebhooksVisitor.cjs +43 -0
  163. package/src/refractor/visitors/open-api-3-1/WebhooksVisitor.mjs +37 -0
  164. package/src/refractor/visitors/open-api-3-1/WebhooksVisitor.ts +57 -0
  165. package/src/refractor/visitors/open-api-3-1/bases.cjs +46 -0
  166. package/src/refractor/visitors/open-api-3-1/bases.mjs +43 -0
  167. package/src/refractor/visitors/open-api-3-1/bases.ts +66 -0
  168. package/src/refractor/visitors/open-api-3-1/callback/index.cjs +36 -0
  169. package/src/refractor/visitors/open-api-3-1/callback/index.mjs +31 -0
  170. package/src/refractor/visitors/open-api-3-1/callback/index.ts +56 -0
  171. package/src/refractor/visitors/open-api-3-1/components/PathItemsVisitor.cjs +33 -0
  172. package/src/refractor/visitors/open-api-3-1/components/PathItemsVisitor.mjs +27 -0
  173. package/src/refractor/visitors/open-api-3-1/components/PathItemsVisitor.ts +45 -0
  174. package/src/refractor/visitors/open-api-3-1/components/SchemasVisitor.cjs +22 -0
  175. package/src/refractor/visitors/open-api-3-1/components/SchemasVisitor.mjs +17 -0
  176. package/src/refractor/visitors/open-api-3-1/components/SchemasVisitor.ts +26 -0
  177. package/src/refractor/visitors/open-api-3-1/components/index.cjs +21 -0
  178. package/src/refractor/visitors/open-api-3-1/components/index.mjs +16 -0
  179. package/src/refractor/visitors/open-api-3-1/components/index.ts +29 -0
  180. package/src/refractor/visitors/open-api-3-1/contact/index.cjs +21 -0
  181. package/src/refractor/visitors/open-api-3-1/contact/index.mjs +16 -0
  182. package/src/refractor/visitors/open-api-3-1/contact/index.ts +29 -0
  183. package/src/refractor/visitors/open-api-3-1/distriminator/index.cjs +22 -0
  184. package/src/refractor/visitors/open-api-3-1/distriminator/index.mjs +17 -0
  185. package/src/refractor/visitors/open-api-3-1/distriminator/index.ts +32 -0
  186. package/src/refractor/visitors/open-api-3-1/encoding/index.cjs +21 -0
  187. package/src/refractor/visitors/open-api-3-1/encoding/index.mjs +16 -0
  188. package/src/refractor/visitors/open-api-3-1/encoding/index.ts +29 -0
  189. package/src/refractor/visitors/open-api-3-1/example/index.cjs +21 -0
  190. package/src/refractor/visitors/open-api-3-1/example/index.mjs +16 -0
  191. package/src/refractor/visitors/open-api-3-1/example/index.ts +29 -0
  192. package/src/refractor/visitors/open-api-3-1/external-documentation/index.cjs +21 -0
  193. package/src/refractor/visitors/open-api-3-1/external-documentation/index.mjs +16 -0
  194. package/src/refractor/visitors/open-api-3-1/external-documentation/index.ts +29 -0
  195. package/src/refractor/visitors/open-api-3-1/header/index.cjs +21 -0
  196. package/src/refractor/visitors/open-api-3-1/header/index.mjs +16 -0
  197. package/src/refractor/visitors/open-api-3-1/header/index.ts +29 -0
  198. package/src/refractor/visitors/open-api-3-1/index.cjs +41 -0
  199. package/src/refractor/visitors/open-api-3-1/index.mjs +35 -0
  200. package/src/refractor/visitors/open-api-3-1/index.ts +52 -0
  201. package/src/refractor/visitors/open-api-3-1/info/index.cjs +21 -0
  202. package/src/refractor/visitors/open-api-3-1/info/index.mjs +16 -0
  203. package/src/refractor/visitors/open-api-3-1/info/index.ts +29 -0
  204. package/src/refractor/visitors/open-api-3-1/license/index.cjs +21 -0
  205. package/src/refractor/visitors/open-api-3-1/license/index.mjs +16 -0
  206. package/src/refractor/visitors/open-api-3-1/license/index.ts +29 -0
  207. package/src/refractor/visitors/open-api-3-1/link/index.cjs +21 -0
  208. package/src/refractor/visitors/open-api-3-1/link/index.mjs +16 -0
  209. package/src/refractor/visitors/open-api-3-1/link/index.ts +29 -0
  210. package/src/refractor/visitors/open-api-3-1/media-type/index.cjs +21 -0
  211. package/src/refractor/visitors/open-api-3-1/media-type/index.mjs +16 -0
  212. package/src/refractor/visitors/open-api-3-1/media-type/index.ts +29 -0
  213. package/src/refractor/visitors/open-api-3-1/oauth-flow/index.cjs +21 -0
  214. package/src/refractor/visitors/open-api-3-1/oauth-flow/index.mjs +16 -0
  215. package/src/refractor/visitors/open-api-3-1/oauth-flow/index.ts +29 -0
  216. package/src/refractor/visitors/open-api-3-1/oauth-flows/index.cjs +21 -0
  217. package/src/refractor/visitors/open-api-3-1/oauth-flows/index.mjs +16 -0
  218. package/src/refractor/visitors/open-api-3-1/oauth-flows/index.ts +29 -0
  219. package/src/refractor/visitors/open-api-3-1/operation/index.cjs +21 -0
  220. package/src/refractor/visitors/open-api-3-1/operation/index.mjs +16 -0
  221. package/src/refractor/visitors/open-api-3-1/operation/index.ts +29 -0
  222. package/src/refractor/visitors/open-api-3-1/parameter/index.cjs +21 -0
  223. package/src/refractor/visitors/open-api-3-1/parameter/index.mjs +16 -0
  224. package/src/refractor/visitors/open-api-3-1/parameter/index.ts +29 -0
  225. package/src/refractor/visitors/open-api-3-1/path-item/index.cjs +21 -0
  226. package/src/refractor/visitors/open-api-3-1/path-item/index.mjs +16 -0
  227. package/src/refractor/visitors/open-api-3-1/path-item/index.ts +29 -0
  228. package/src/refractor/visitors/open-api-3-1/paths/index.cjs +21 -0
  229. package/src/refractor/visitors/open-api-3-1/paths/index.mjs +16 -0
  230. package/src/refractor/visitors/open-api-3-1/paths/index.ts +29 -0
  231. package/src/refractor/visitors/open-api-3-1/reference/index.cjs +21 -0
  232. package/src/refractor/visitors/open-api-3-1/reference/index.mjs +16 -0
  233. package/src/refractor/visitors/open-api-3-1/reference/index.ts +29 -0
  234. package/src/refractor/visitors/open-api-3-1/request-body/index.cjs +21 -0
  235. package/src/refractor/visitors/open-api-3-1/request-body/index.mjs +16 -0
  236. package/src/refractor/visitors/open-api-3-1/request-body/index.ts +29 -0
  237. package/src/refractor/visitors/open-api-3-1/response/index.cjs +21 -0
  238. package/src/refractor/visitors/open-api-3-1/response/index.mjs +16 -0
  239. package/src/refractor/visitors/open-api-3-1/response/index.ts +29 -0
  240. package/src/refractor/visitors/open-api-3-1/responses/index.cjs +21 -0
  241. package/src/refractor/visitors/open-api-3-1/responses/index.mjs +16 -0
  242. package/src/refractor/visitors/open-api-3-1/responses/index.ts +29 -0
  243. package/src/refractor/visitors/open-api-3-1/schema/$defsVisitor.cjs +19 -0
  244. package/src/refractor/visitors/open-api-3-1/schema/$defsVisitor.mjs +16 -0
  245. package/src/refractor/visitors/open-api-3-1/schema/$defsVisitor.ts +21 -0
  246. package/src/refractor/visitors/open-api-3-1/schema/AllOfVisitor.cjs +15 -0
  247. package/src/refractor/visitors/open-api-3-1/schema/AllOfVisitor.mjs +11 -0
  248. package/src/refractor/visitors/open-api-3-1/schema/AllOfVisitor.ts +18 -0
  249. package/src/refractor/visitors/open-api-3-1/schema/AnyOfVisitor.cjs +15 -0
  250. package/src/refractor/visitors/open-api-3-1/schema/AnyOfVisitor.mjs +11 -0
  251. package/src/refractor/visitors/open-api-3-1/schema/AnyOfVisitor.ts +18 -0
  252. package/src/refractor/visitors/open-api-3-1/schema/DependentSchemasVisitor.cjs +15 -0
  253. package/src/refractor/visitors/open-api-3-1/schema/DependentSchemasVisitor.mjs +11 -0
  254. package/src/refractor/visitors/open-api-3-1/schema/DependentSchemasVisitor.ts +18 -0
  255. package/src/refractor/visitors/open-api-3-1/schema/OneOfVisitor.cjs +15 -0
  256. package/src/refractor/visitors/open-api-3-1/schema/OneOfVisitor.mjs +11 -0
  257. package/src/refractor/visitors/open-api-3-1/schema/OneOfVisitor.ts +18 -0
  258. package/src/refractor/visitors/open-api-3-1/schema/PatternPropertiesVisitor.cjs +15 -0
  259. package/src/refractor/visitors/open-api-3-1/schema/PatternPropertiesVisitor.mjs +11 -0
  260. package/src/refractor/visitors/open-api-3-1/schema/PatternPropertiesVisitor.ts +18 -0
  261. package/src/refractor/visitors/open-api-3-1/schema/PrefixItemsVisitor.cjs +15 -0
  262. package/src/refractor/visitors/open-api-3-1/schema/PrefixItemsVisitor.mjs +11 -0
  263. package/src/refractor/visitors/open-api-3-1/schema/PrefixItemsVisitor.ts +18 -0
  264. package/src/refractor/visitors/open-api-3-1/schema/PropertiesVisitor.cjs +15 -0
  265. package/src/refractor/visitors/open-api-3-1/schema/PropertiesVisitor.mjs +11 -0
  266. package/src/refractor/visitors/open-api-3-1/schema/PropertiesVisitor.ts +18 -0
  267. package/src/refractor/visitors/open-api-3-1/schema/index.cjs +76 -0
  268. package/src/refractor/visitors/open-api-3-1/schema/index.mjs +70 -0
  269. package/src/refractor/visitors/open-api-3-1/schema/index.ts +88 -0
  270. package/src/refractor/visitors/open-api-3-1/security-requirement/index.cjs +21 -0
  271. package/src/refractor/visitors/open-api-3-1/security-requirement/index.mjs +16 -0
  272. package/src/refractor/visitors/open-api-3-1/security-requirement/index.ts +29 -0
  273. package/src/refractor/visitors/open-api-3-1/security-scheme/index.cjs +21 -0
  274. package/src/refractor/visitors/open-api-3-1/security-scheme/index.mjs +16 -0
  275. package/src/refractor/visitors/open-api-3-1/security-scheme/index.ts +29 -0
  276. package/src/refractor/visitors/open-api-3-1/server/index.cjs +21 -0
  277. package/src/refractor/visitors/open-api-3-1/server/index.mjs +16 -0
  278. package/src/refractor/visitors/open-api-3-1/server/index.ts +29 -0
  279. package/src/refractor/visitors/open-api-3-1/server-variable/index.cjs +21 -0
  280. package/src/refractor/visitors/open-api-3-1/server-variable/index.mjs +16 -0
  281. package/src/refractor/visitors/open-api-3-1/server-variable/index.ts +29 -0
  282. package/src/refractor/visitors/open-api-3-1/tag/index.cjs +21 -0
  283. package/src/refractor/visitors/open-api-3-1/tag/index.mjs +16 -0
  284. package/src/refractor/visitors/open-api-3-1/tag/index.ts +29 -0
  285. package/src/refractor/visitors/open-api-3-1/xml/index.cjs +21 -0
  286. package/src/refractor/visitors/open-api-3-1/xml/index.mjs +16 -0
  287. package/src/refractor/visitors/open-api-3-1/xml/index.ts +29 -0
@@ -0,0 +1,103 @@
1
+ import { cloneDeep } from '@speclynx/apidom-datamodel';
2
+ import NormalizeStorage from "./NormalizeStorage.mjs";
3
+ /**
4
+ * Override of Schema.example and Schema.examples field inside the Header Objects.
5
+ *
6
+ * Header Object has two fixed fields:
7
+ * - `example` of type `Any`
8
+ * - `examples` of type `Map[string, Example Object | Reference Object]`
9
+ *
10
+ * OpenAPI 3.1 specification excerpt that defines the override behavior:
11
+ *
12
+ * The example value SHALL override the example provided by the schema.
13
+ * Furthermore, if referencing a schema that contains an example, the examples value SHALL override the example provided by the schema.
14
+ *
15
+ * NOTE: this plugin is idempotent
16
+ * @public
17
+ */
18
+ /**
19
+ * @public
20
+ */
21
+ const plugin = ({
22
+ storageField = 'x-normalized'
23
+ } = {}) => toolbox => {
24
+ const {
25
+ predicates,
26
+ ancestorLineageToJSONPointer
27
+ } = toolbox;
28
+ let storage;
29
+ return {
30
+ visitor: {
31
+ OpenApi3_1Element: {
32
+ enter(path) {
33
+ const element = path.node;
34
+ storage = new NormalizeStorage(element, storageField, 'header-examples');
35
+ },
36
+ leave() {
37
+ storage = undefined;
38
+ }
39
+ },
40
+ HeaderElement: {
41
+ leave(path) {
42
+ const headerElement = path.node;
43
+ const ancestors = path.getAncestorNodes().reverse(); // root to parent order
44
+
45
+ // skip visiting this Header Object
46
+ if (ancestors.some(predicates.isComponentsElement)) {
47
+ return;
48
+ }
49
+
50
+ // no Header.schema field present
51
+ if (typeof headerElement.schema === 'undefined' || !predicates.isSchemaElement(headerElement.schema)) {
52
+ return;
53
+ }
54
+ // Schema contains no example
55
+ if (typeof headerElement.schema?.example === 'undefined' && typeof headerElement.schema?.examples === 'undefined') {
56
+ return;
57
+ }
58
+ const headerJSONPointer = ancestorLineageToJSONPointer([...ancestors, headerElement]);
59
+
60
+ // skip visiting this Header Object if it's already normalized
61
+ if (storage.includes(headerJSONPointer)) {
62
+ return;
63
+ }
64
+
65
+ /**
66
+ * Header.examples and Schema.examples have preferences over the older
67
+ * and deprected `example` field.
68
+ */
69
+ if (typeof headerElement.examples !== 'undefined' && predicates.isObjectElement(headerElement.examples)) {
70
+ // @ts-ignore
71
+ const examples = headerElement.examples.map(example => {
72
+ return cloneDeep.safe(example.value);
73
+ });
74
+ if (typeof headerElement.schema.examples !== 'undefined') {
75
+ headerElement.schema.set('examples', examples);
76
+ storage.append(headerJSONPointer);
77
+ }
78
+ if (typeof headerElement.schema.example !== 'undefined') {
79
+ headerElement.schema.set('example', examples[0]);
80
+ storage.append(headerJSONPointer);
81
+ }
82
+ return;
83
+ }
84
+
85
+ /**
86
+ * Handle deprecated `example` field.
87
+ */
88
+ if (typeof headerElement.example !== 'undefined') {
89
+ if (typeof headerElement.schema.examples !== 'undefined') {
90
+ headerElement.schema.set('examples', [cloneDeep(headerElement.example)]);
91
+ storage.append(headerJSONPointer);
92
+ }
93
+ if (typeof headerElement.schema.example !== 'undefined') {
94
+ headerElement.schema.set('example', cloneDeep(headerElement.example));
95
+ storage.append(headerJSONPointer);
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ };
102
+ };
103
+ export default plugin;
@@ -0,0 +1,125 @@
1
+ import { cloneDeep } from '@speclynx/apidom-datamodel';
2
+ import { Path } from '@speclynx/apidom-traverse';
3
+
4
+ import HeaderElement from '../../../elements/Header.ts';
5
+ import ExampleElement from '../../../elements/Example.ts';
6
+ import type { Toolbox } from '../../toolbox.ts';
7
+ import OpenApi3_1Element from '../../../elements/OpenApi3-1.ts';
8
+ import NormalizeStorage from './NormalizeStorage.ts';
9
+
10
+ /**
11
+ * Override of Schema.example and Schema.examples field inside the Header Objects.
12
+ *
13
+ * Header Object has two fixed fields:
14
+ * - `example` of type `Any`
15
+ * - `examples` of type `Map[string, Example Object | Reference Object]`
16
+ *
17
+ * OpenAPI 3.1 specification excerpt that defines the override behavior:
18
+ *
19
+ * The example value SHALL override the example provided by the schema.
20
+ * Furthermore, if referencing a schema that contains an example, the examples value SHALL override the example provided by the schema.
21
+ *
22
+ * NOTE: this plugin is idempotent
23
+ * @public
24
+ */
25
+
26
+ export interface PluginOptions {
27
+ storageField?: string;
28
+ }
29
+
30
+ /**
31
+ * @public
32
+ */
33
+ const plugin =
34
+ ({ storageField = 'x-normalized' }: PluginOptions = {}) =>
35
+ (toolbox: Toolbox) => {
36
+ const { predicates, ancestorLineageToJSONPointer } = toolbox;
37
+ let storage: NormalizeStorage | undefined;
38
+
39
+ return {
40
+ visitor: {
41
+ OpenApi3_1Element: {
42
+ enter(path: Path<OpenApi3_1Element>) {
43
+ const element = path.node;
44
+ storage = new NormalizeStorage(element, storageField, 'header-examples');
45
+ },
46
+ leave() {
47
+ storage = undefined;
48
+ },
49
+ },
50
+ HeaderElement: {
51
+ leave(path: Path<HeaderElement>) {
52
+ const headerElement = path.node;
53
+ const ancestors = path.getAncestorNodes().reverse(); // root to parent order
54
+
55
+ // skip visiting this Header Object
56
+ if (ancestors.some(predicates.isComponentsElement)) {
57
+ return;
58
+ }
59
+
60
+ // no Header.schema field present
61
+ if (
62
+ typeof headerElement.schema === 'undefined' ||
63
+ !predicates.isSchemaElement(headerElement.schema)
64
+ ) {
65
+ return;
66
+ }
67
+ // Schema contains no example
68
+ if (
69
+ typeof headerElement.schema?.example === 'undefined' &&
70
+ typeof headerElement.schema?.examples === 'undefined'
71
+ ) {
72
+ return;
73
+ }
74
+
75
+ const headerJSONPointer = ancestorLineageToJSONPointer([...ancestors, headerElement]);
76
+
77
+ // skip visiting this Header Object if it's already normalized
78
+ if (storage!.includes(headerJSONPointer)) {
79
+ return;
80
+ }
81
+
82
+ /**
83
+ * Header.examples and Schema.examples have preferences over the older
84
+ * and deprected `example` field.
85
+ */
86
+ if (
87
+ typeof headerElement.examples !== 'undefined' &&
88
+ predicates.isObjectElement(headerElement.examples)
89
+ ) {
90
+ // @ts-ignore
91
+ const examples = headerElement.examples.map((example: ExampleElement) => {
92
+ return cloneDeep.safe(example.value);
93
+ });
94
+
95
+ if (typeof headerElement.schema.examples !== 'undefined') {
96
+ headerElement.schema.set('examples', examples);
97
+ storage!.append(headerJSONPointer);
98
+ }
99
+ if (typeof headerElement.schema.example !== 'undefined') {
100
+ headerElement.schema.set('example', examples[0]);
101
+ storage!.append(headerJSONPointer);
102
+ }
103
+ return;
104
+ }
105
+
106
+ /**
107
+ * Handle deprecated `example` field.
108
+ */
109
+ if (typeof headerElement.example !== 'undefined') {
110
+ if (typeof headerElement.schema.examples !== 'undefined') {
111
+ headerElement.schema.set('examples', [cloneDeep(headerElement.example)]);
112
+ storage!.append(headerJSONPointer);
113
+ }
114
+ if (typeof headerElement.schema.example !== 'undefined') {
115
+ headerElement.schema.set('example', cloneDeep(headerElement.example));
116
+ storage!.append(headerJSONPointer);
117
+ }
118
+ }
119
+ },
120
+ },
121
+ },
122
+ };
123
+ };
124
+
125
+ export default plugin;
@@ -0,0 +1,166 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault").default;
4
+ exports.__esModule = true;
5
+ exports.default = void 0;
6
+ var _ramda = require("ramda");
7
+ var _apidomDatamodel = require("@speclynx/apidom-datamodel");
8
+ var _apidomCore = require("@speclynx/apidom-core");
9
+ var _NormalizeStorage = _interopRequireDefault(require("./normalize-header-examples/NormalizeStorage.cjs"));
10
+ const removeSpaces = operationId => {
11
+ return operationId.replace(/\s/g, '');
12
+ };
13
+ const replaceSpecialCharsWithUnderscore = operationId => {
14
+ return operationId.replace(/\W/gi, '_');
15
+ };
16
+ const createNormalizedOperationId = (path, method) => {
17
+ const normalizedMethod = replaceSpecialCharsWithUnderscore(removeSpaces(method.toLowerCase()));
18
+ const normalizedPath = replaceSpecialCharsWithUnderscore(removeSpaces(path));
19
+ return `${normalizedMethod}${normalizedPath}`;
20
+ };
21
+ const normalizeOperationId = (operationId, path, method) => {
22
+ const withoutSpaces = removeSpaces(operationId);
23
+ if (withoutSpaces.length > 0) {
24
+ return replaceSpecialCharsWithUnderscore(withoutSpaces);
25
+ }
26
+ return createNormalizedOperationId(path, method);
27
+ };
28
+
29
+ /**
30
+ * Normalization of Operation.operationId field.
31
+ *
32
+ * This normalization is not guided by OpenAPI 3.1 specification.
33
+ *
34
+ * Existing Operation.operationId fields are normalized into snake case form.
35
+ *
36
+ * Operation Objects, that do not define operationId field, are left untouched.
37
+ *
38
+ * Original operationId is stored in meta and as new `__originalOperationId` field.
39
+ *
40
+ * This plugin also guarantees the uniqueness of all defined Operation.operationId fields,
41
+ * and make sure Link.operationId fields are pointing to correct and normalized Operation.operationId fields.
42
+ *
43
+ * NOTE: this plugin is idempotent
44
+ * @public
45
+ */
46
+
47
+ /**
48
+ * @public
49
+ */
50
+ const plugin = ({
51
+ storageField = 'x-normalized',
52
+ operationIdNormalizer = normalizeOperationId
53
+ } = {}) => toolbox => {
54
+ const {
55
+ predicates,
56
+ ancestorLineageToJSONPointer,
57
+ namespace
58
+ } = toolbox;
59
+ const pathTemplates = [];
60
+ const normalizedOperations = [];
61
+ const links = [];
62
+ let storage;
63
+ return {
64
+ visitor: {
65
+ OpenApi3_1Element: {
66
+ enter(path) {
67
+ const element = path.node;
68
+ storage = new _NormalizeStorage.default(element, storageField, 'operation-ids');
69
+ },
70
+ leave() {
71
+ // group normalized operations by normalized operationId
72
+ const normalizedOperationGroups = (0, _ramda.groupBy)(operationElement => {
73
+ return (0, _apidomCore.toValue)(operationElement.operationId);
74
+ }, normalizedOperations);
75
+
76
+ // append incremental numerical suffixes to identical operationIds
77
+ Object.entries(normalizedOperationGroups).forEach(([normalizedOperationId, operationElements]) => {
78
+ if (!Array.isArray(operationElements)) return;
79
+ if (operationElements.length <= 1) return;
80
+ operationElements.forEach((operationElement, index) => {
81
+ const indexedNormalizedOperationId = `${normalizedOperationId}${index + 1}`;
82
+ // @ts-ignore
83
+ operationElement.operationId = new namespace.elements.String(indexedNormalizedOperationId);
84
+ });
85
+ });
86
+
87
+ // rectify possibly broken Link.operationId fields
88
+ links.forEach(linkElement => {
89
+ if (typeof linkElement.operationId === 'undefined') return;
90
+ const linkOperationId = String((0, _apidomCore.toValue)(linkElement.operationId));
91
+ const operationElement = normalizedOperations.find(normalizedOperationElement => {
92
+ const originalOperationId = normalizedOperationElement.meta.get('originalOperationId');
93
+ return originalOperationId === linkOperationId;
94
+ });
95
+
96
+ // Link Object doesn't need to be rectified
97
+ if (typeof operationElement === 'undefined') return;
98
+ linkElement.operationId = _apidomDatamodel.cloneDeep.safe(operationElement.operationId);
99
+ linkElement.meta.set('originalOperationId', linkOperationId);
100
+ linkElement.set('__originalOperationId', linkOperationId);
101
+ });
102
+
103
+ // cleanup the references
104
+ normalizedOperations.length = 0;
105
+ links.length = 0;
106
+ storage = undefined;
107
+ }
108
+ },
109
+ PathItemElement: {
110
+ enter(path) {
111
+ const pathItemElement = path.node;
112
+ // `path` meta may not be always available, e.g. in Callback Object or Components Object
113
+ const pathTemplate = (0, _ramda.defaultTo)('path', pathItemElement.meta.get('path'));
114
+ pathTemplates.push(pathTemplate);
115
+ },
116
+ leave() {
117
+ pathTemplates.pop();
118
+ }
119
+ },
120
+ OperationElement: {
121
+ enter(path) {
122
+ const operationElement = path.node;
123
+ const ancestors = path.getAncestorNodes().reverse(); // root to parent order
124
+
125
+ // operationId field is undefined, needs no normalization
126
+ if (typeof operationElement.operationId === 'undefined') return;
127
+ const operationJSONPointer = ancestorLineageToJSONPointer([...ancestors, operationElement]);
128
+
129
+ // skip visiting this Operation Object if it's already normalized
130
+ if (storage.includes(operationJSONPointer)) {
131
+ return;
132
+ }
133
+
134
+ // cast operationId to string type
135
+ const originalOperationId = String((0, _apidomCore.toValue)(operationElement.operationId));
136
+ // perform operationId normalization
137
+ const pathTemplate = (0, _ramda.last)(pathTemplates);
138
+ // `http-method` meta may not be always available, e.g. in Callback Object or Components Object
139
+ const method = (0, _ramda.defaultTo)('method', operationElement.meta.get('http-method'));
140
+ const normalizedOperationId = operationIdNormalizer(originalOperationId, pathTemplate, method);
141
+
142
+ // normalization is not necessary
143
+ if (originalOperationId === normalizedOperationId) return;
144
+
145
+ // @ts-ignore
146
+ operationElement.operationId = new namespace.elements.String(normalizedOperationId);
147
+ operationElement.set('__originalOperationId', originalOperationId);
148
+ operationElement.meta.set('originalOperationId', originalOperationId);
149
+ normalizedOperations.push(operationElement);
150
+ storage.append(operationJSONPointer);
151
+ }
152
+ },
153
+ LinkElement: {
154
+ leave(path) {
155
+ const linkElement = path.node;
156
+ // make sure this Link elements doesn't come from base namespace
157
+ if (!predicates.isLinkElement(linkElement)) return;
158
+ // ignore Link Objects with undefined operationId
159
+ if (typeof linkElement.operationId === 'undefined') return;
160
+ links.push(linkElement);
161
+ }
162
+ }
163
+ }
164
+ };
165
+ };
166
+ var _default = exports.default = plugin;
@@ -0,0 +1,161 @@
1
+ import { last, defaultTo, groupBy } from 'ramda';
2
+ import { cloneDeep } from '@speclynx/apidom-datamodel';
3
+ import { toValue } from '@speclynx/apidom-core';
4
+ import NormalizeStorage from "./normalize-header-examples/NormalizeStorage.mjs";
5
+ const removeSpaces = operationId => {
6
+ return operationId.replace(/\s/g, '');
7
+ };
8
+ const replaceSpecialCharsWithUnderscore = operationId => {
9
+ return operationId.replace(/\W/gi, '_');
10
+ };
11
+ const createNormalizedOperationId = (path, method) => {
12
+ const normalizedMethod = replaceSpecialCharsWithUnderscore(removeSpaces(method.toLowerCase()));
13
+ const normalizedPath = replaceSpecialCharsWithUnderscore(removeSpaces(path));
14
+ return `${normalizedMethod}${normalizedPath}`;
15
+ };
16
+ const normalizeOperationId = (operationId, path, method) => {
17
+ const withoutSpaces = removeSpaces(operationId);
18
+ if (withoutSpaces.length > 0) {
19
+ return replaceSpecialCharsWithUnderscore(withoutSpaces);
20
+ }
21
+ return createNormalizedOperationId(path, method);
22
+ };
23
+
24
+ /**
25
+ * Normalization of Operation.operationId field.
26
+ *
27
+ * This normalization is not guided by OpenAPI 3.1 specification.
28
+ *
29
+ * Existing Operation.operationId fields are normalized into snake case form.
30
+ *
31
+ * Operation Objects, that do not define operationId field, are left untouched.
32
+ *
33
+ * Original operationId is stored in meta and as new `__originalOperationId` field.
34
+ *
35
+ * This plugin also guarantees the uniqueness of all defined Operation.operationId fields,
36
+ * and make sure Link.operationId fields are pointing to correct and normalized Operation.operationId fields.
37
+ *
38
+ * NOTE: this plugin is idempotent
39
+ * @public
40
+ */
41
+
42
+ /**
43
+ * @public
44
+ */
45
+ const plugin = ({
46
+ storageField = 'x-normalized',
47
+ operationIdNormalizer = normalizeOperationId
48
+ } = {}) => toolbox => {
49
+ const {
50
+ predicates,
51
+ ancestorLineageToJSONPointer,
52
+ namespace
53
+ } = toolbox;
54
+ const pathTemplates = [];
55
+ const normalizedOperations = [];
56
+ const links = [];
57
+ let storage;
58
+ return {
59
+ visitor: {
60
+ OpenApi3_1Element: {
61
+ enter(path) {
62
+ const element = path.node;
63
+ storage = new NormalizeStorage(element, storageField, 'operation-ids');
64
+ },
65
+ leave() {
66
+ // group normalized operations by normalized operationId
67
+ const normalizedOperationGroups = groupBy(operationElement => {
68
+ return toValue(operationElement.operationId);
69
+ }, normalizedOperations);
70
+
71
+ // append incremental numerical suffixes to identical operationIds
72
+ Object.entries(normalizedOperationGroups).forEach(([normalizedOperationId, operationElements]) => {
73
+ if (!Array.isArray(operationElements)) return;
74
+ if (operationElements.length <= 1) return;
75
+ operationElements.forEach((operationElement, index) => {
76
+ const indexedNormalizedOperationId = `${normalizedOperationId}${index + 1}`;
77
+ // @ts-ignore
78
+ operationElement.operationId = new namespace.elements.String(indexedNormalizedOperationId);
79
+ });
80
+ });
81
+
82
+ // rectify possibly broken Link.operationId fields
83
+ links.forEach(linkElement => {
84
+ if (typeof linkElement.operationId === 'undefined') return;
85
+ const linkOperationId = String(toValue(linkElement.operationId));
86
+ const operationElement = normalizedOperations.find(normalizedOperationElement => {
87
+ const originalOperationId = normalizedOperationElement.meta.get('originalOperationId');
88
+ return originalOperationId === linkOperationId;
89
+ });
90
+
91
+ // Link Object doesn't need to be rectified
92
+ if (typeof operationElement === 'undefined') return;
93
+ linkElement.operationId = cloneDeep.safe(operationElement.operationId);
94
+ linkElement.meta.set('originalOperationId', linkOperationId);
95
+ linkElement.set('__originalOperationId', linkOperationId);
96
+ });
97
+
98
+ // cleanup the references
99
+ normalizedOperations.length = 0;
100
+ links.length = 0;
101
+ storage = undefined;
102
+ }
103
+ },
104
+ PathItemElement: {
105
+ enter(path) {
106
+ const pathItemElement = path.node;
107
+ // `path` meta may not be always available, e.g. in Callback Object or Components Object
108
+ const pathTemplate = defaultTo('path', pathItemElement.meta.get('path'));
109
+ pathTemplates.push(pathTemplate);
110
+ },
111
+ leave() {
112
+ pathTemplates.pop();
113
+ }
114
+ },
115
+ OperationElement: {
116
+ enter(path) {
117
+ const operationElement = path.node;
118
+ const ancestors = path.getAncestorNodes().reverse(); // root to parent order
119
+
120
+ // operationId field is undefined, needs no normalization
121
+ if (typeof operationElement.operationId === 'undefined') return;
122
+ const operationJSONPointer = ancestorLineageToJSONPointer([...ancestors, operationElement]);
123
+
124
+ // skip visiting this Operation Object if it's already normalized
125
+ if (storage.includes(operationJSONPointer)) {
126
+ return;
127
+ }
128
+
129
+ // cast operationId to string type
130
+ const originalOperationId = String(toValue(operationElement.operationId));
131
+ // perform operationId normalization
132
+ const pathTemplate = last(pathTemplates);
133
+ // `http-method` meta may not be always available, e.g. in Callback Object or Components Object
134
+ const method = defaultTo('method', operationElement.meta.get('http-method'));
135
+ const normalizedOperationId = operationIdNormalizer(originalOperationId, pathTemplate, method);
136
+
137
+ // normalization is not necessary
138
+ if (originalOperationId === normalizedOperationId) return;
139
+
140
+ // @ts-ignore
141
+ operationElement.operationId = new namespace.elements.String(normalizedOperationId);
142
+ operationElement.set('__originalOperationId', originalOperationId);
143
+ operationElement.meta.set('originalOperationId', originalOperationId);
144
+ normalizedOperations.push(operationElement);
145
+ storage.append(operationJSONPointer);
146
+ }
147
+ },
148
+ LinkElement: {
149
+ leave(path) {
150
+ const linkElement = path.node;
151
+ // make sure this Link elements doesn't come from base namespace
152
+ if (!predicates.isLinkElement(linkElement)) return;
153
+ // ignore Link Objects with undefined operationId
154
+ if (typeof linkElement.operationId === 'undefined') return;
155
+ links.push(linkElement);
156
+ }
157
+ }
158
+ }
159
+ };
160
+ };
161
+ export default plugin;