@redocly/openapi-core 1.18.1 → 1.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (411) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/__tests__/utils.ts +14 -7
  3. package/lib/benchmark/benches/lint-with-many-rules.bench.d.ts +1 -0
  4. package/lib/benchmark/benches/lint-with-many-rules.bench.js +7 -3
  5. package/lib/benchmark/benches/lint-with-nested-rule.bench.d.ts +1 -0
  6. package/lib/benchmark/benches/lint-with-nested-rule.bench.js +7 -3
  7. package/lib/benchmark/benches/lint-with-no-rules.bench.d.ts +1 -0
  8. package/lib/benchmark/benches/lint-with-no-rules.bench.js +7 -3
  9. package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.d.ts +1 -0
  10. package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.js +19 -15
  11. package/lib/benchmark/benches/lint-with-top-level-rule.bench.d.ts +1 -0
  12. package/lib/benchmark/benches/lint-with-top-level-rule.bench.js +18 -14
  13. package/lib/benchmark/benches/recommended-oas3.bench.js +2 -2
  14. package/lib/benchmark/benches/resolve-with-no-external.bench.js +2 -2
  15. package/lib/benchmark/utils.d.ts +3 -3
  16. package/lib/benchmark/utils.js +10 -7
  17. package/lib/bundle.d.ts +2 -2
  18. package/lib/bundle.js +127 -120
  19. package/lib/config/all.js +13 -1
  20. package/lib/config/builtIn.js +18 -17
  21. package/lib/config/config-resolvers.d.ts +1 -1
  22. package/lib/config/config-resolvers.js +241 -158
  23. package/lib/config/config.d.ts +4 -3
  24. package/lib/config/config.js +53 -34
  25. package/lib/config/load.d.ts +1 -1
  26. package/lib/config/load.js +105 -117
  27. package/lib/config/minimal.js +13 -0
  28. package/lib/config/recommended-strict.js +14 -1
  29. package/lib/config/recommended.js +14 -1
  30. package/lib/config/rules.d.ts +3 -3
  31. package/lib/config/rules.js +1 -2
  32. package/lib/config/types.d.ts +17 -4
  33. package/lib/config/utils.d.ts +3 -1
  34. package/lib/config/utils.js +78 -49
  35. package/lib/decorators/async3/index.d.ts +1 -0
  36. package/lib/decorators/async3/index.js +4 -0
  37. package/lib/decorators/common/filters/filter-helper.d.ts +1 -1
  38. package/lib/decorators/common/filters/filter-helper.js +2 -3
  39. package/lib/decorators/common/filters/filter-in.d.ts +1 -1
  40. package/lib/decorators/common/filters/filter-in.js +1 -1
  41. package/lib/decorators/common/filters/filter-out.d.ts +1 -1
  42. package/lib/decorators/common/filters/filter-out.js +1 -1
  43. package/lib/decorators/common/info-description-override.d.ts +1 -1
  44. package/lib/decorators/common/info-override.d.ts +1 -1
  45. package/lib/decorators/common/info-override.js +1 -12
  46. package/lib/decorators/common/media-type-examples-override.d.ts +1 -1
  47. package/lib/decorators/common/media-type-examples-override.js +8 -2
  48. package/lib/decorators/common/operation-description-override.d.ts +1 -1
  49. package/lib/decorators/common/registry-dependencies.d.ts +1 -1
  50. package/lib/decorators/common/remove-x-internal.d.ts +1 -1
  51. package/lib/decorators/common/remove-x-internal.js +4 -5
  52. package/lib/decorators/common/tag-description-override.d.ts +1 -1
  53. package/lib/decorators/oas2/index.d.ts +1 -1
  54. package/lib/decorators/oas2/remove-unused-components.js +1 -2
  55. package/lib/decorators/oas3/index.d.ts +1 -1
  56. package/lib/decorators/oas3/remove-unused-components.js +1 -2
  57. package/lib/env.d.ts +0 -1
  58. package/lib/env.js +1 -1
  59. package/lib/format/codeframes.d.ts +1 -1
  60. package/lib/format/codeframes.js +10 -8
  61. package/lib/format/format.d.ts +1 -1
  62. package/lib/format/format.js +24 -16
  63. package/lib/index.d.ts +2 -1
  64. package/lib/index.js +6 -4
  65. package/lib/js-yaml/index.d.ts +1 -1
  66. package/lib/js-yaml/index.js +1 -1
  67. package/lib/lint.d.ts +3 -1
  68. package/lib/lint.js +92 -99
  69. package/lib/logger.js +2 -2
  70. package/lib/oas-types.d.ts +9 -5
  71. package/lib/oas-types.js +22 -12
  72. package/lib/redocly/domains.d.ts +1 -1
  73. package/lib/redocly/domains.js +6 -6
  74. package/lib/redocly/index.d.ts +1 -1
  75. package/lib/redocly/index.js +60 -73
  76. package/lib/redocly/registry-api.js +64 -82
  77. package/lib/ref-utils.d.ts +2 -2
  78. package/lib/ref-utils.js +14 -13
  79. package/lib/resolve.d.ts +2 -2
  80. package/lib/resolve.js +186 -205
  81. package/lib/rules/ajv.d.ts +1 -1
  82. package/lib/rules/ajv.js +10 -8
  83. package/lib/rules/arazzo/index.js +2 -0
  84. package/lib/rules/async2/channels-kebab-case.d.ts +1 -1
  85. package/lib/rules/async2/index.js +2 -0
  86. package/lib/rules/async2/no-channel-trailing-slash.d.ts +1 -1
  87. package/lib/rules/async3/channels-kebab-case.d.ts +2 -0
  88. package/lib/rules/async3/channels-kebab-case.js +19 -0
  89. package/lib/rules/async3/index.d.ts +3 -0
  90. package/lib/rules/async3/index.js +24 -0
  91. package/lib/rules/async3/no-channel-trailing-slash.d.ts +2 -0
  92. package/lib/rules/async3/no-channel-trailing-slash.js +16 -0
  93. package/lib/rules/common/assertions/asserts.d.ts +2 -2
  94. package/lib/rules/common/assertions/asserts.js +5 -5
  95. package/lib/rules/common/assertions/index.d.ts +4 -4
  96. package/lib/rules/common/assertions/utils.d.ts +1 -1
  97. package/lib/rules/common/assertions/utils.js +43 -28
  98. package/lib/rules/common/info-contact.d.ts +1 -1
  99. package/lib/rules/common/info-license-strict.d.ts +2 -0
  100. package/lib/rules/common/info-license-strict.js +26 -0
  101. package/lib/rules/common/info-license-url.d.ts +1 -1
  102. package/lib/rules/common/info-license.d.ts +1 -1
  103. package/lib/rules/common/no-ambiguous-paths.d.ts +1 -1
  104. package/lib/rules/common/no-enum-type-mismatch.d.ts +1 -1
  105. package/lib/rules/common/no-http-verbs-in-paths.d.ts +1 -1
  106. package/lib/rules/common/no-identical-paths.d.ts +1 -1
  107. package/lib/rules/common/no-invalid-parameter-examples.js +1 -2
  108. package/lib/rules/common/no-invalid-schema-examples.js +1 -2
  109. package/lib/rules/common/no-path-trailing-slash.d.ts +1 -1
  110. package/lib/rules/common/no-required-schema-properties-undefined.d.ts +1 -1
  111. package/lib/rules/common/no-required-schema-properties-undefined.js +1 -2
  112. package/lib/rules/common/operation-2xx-response.d.ts +1 -1
  113. package/lib/rules/common/operation-4xx-response.d.ts +1 -1
  114. package/lib/rules/common/operation-description.d.ts +1 -1
  115. package/lib/rules/common/operation-operationId-unique.d.ts +1 -1
  116. package/lib/rules/common/operation-operationId-url-safe.d.ts +1 -1
  117. package/lib/rules/common/operation-operationId-url-safe.js +1 -0
  118. package/lib/rules/common/operation-operationId.d.ts +1 -1
  119. package/lib/rules/common/operation-parameters-unique.d.ts +1 -1
  120. package/lib/rules/common/operation-singular-tag.d.ts +1 -1
  121. package/lib/rules/common/operation-summary.d.ts +1 -1
  122. package/lib/rules/common/operation-tag-defined.d.ts +1 -1
  123. package/lib/rules/common/operation-tag-defined.js +1 -2
  124. package/lib/rules/common/parameter-description.d.ts +1 -1
  125. package/lib/rules/common/path-declaration-must-exist.d.ts +1 -1
  126. package/lib/rules/common/path-excludes-patterns.d.ts +1 -1
  127. package/lib/rules/common/path-http-verbs-order.d.ts +1 -1
  128. package/lib/rules/common/path-http-verbs-order.js +1 -1
  129. package/lib/rules/common/path-not-include-query.d.ts +1 -1
  130. package/lib/rules/common/path-params-defined.d.ts +1 -1
  131. package/lib/rules/common/path-segment-plural.d.ts +1 -1
  132. package/lib/rules/common/paths-kebab-case.d.ts +1 -1
  133. package/lib/rules/common/required-string-property-missing-min-length.d.ts +1 -1
  134. package/lib/rules/common/required-string-property-missing-min-length.js +2 -2
  135. package/lib/rules/common/response-contains-header.d.ts +1 -1
  136. package/lib/rules/common/response-contains-header.js +2 -2
  137. package/lib/rules/common/security-defined.d.ts +1 -1
  138. package/lib/rules/common/security-defined.js +3 -7
  139. package/lib/rules/common/spec-strict-refs.d.ts +1 -1
  140. package/lib/rules/common/spec.d.ts +2 -2
  141. package/lib/rules/common/spec.js +6 -7
  142. package/lib/rules/common/tag-description.d.ts +1 -1
  143. package/lib/rules/common/tags-alphabetical.d.ts +1 -1
  144. package/lib/rules/no-unresolved-refs.d.ts +3 -3
  145. package/lib/rules/no-unresolved-refs.js +3 -4
  146. package/lib/rules/oas2/boolean-parameter-prefixes.d.ts +1 -1
  147. package/lib/rules/oas2/index.d.ts +1 -1
  148. package/lib/rules/oas2/index.js +2 -0
  149. package/lib/rules/oas2/response-contains-property.d.ts +1 -1
  150. package/lib/rules/oas2/response-contains-property.js +1 -2
  151. package/lib/rules/oas3/array-parameter-serialization.d.ts +1 -1
  152. package/lib/rules/oas3/array-parameter-serialization.js +1 -2
  153. package/lib/rules/oas3/boolean-parameter-prefixes.d.ts +1 -1
  154. package/lib/rules/oas3/component-name-unique.d.ts +1 -1
  155. package/lib/rules/oas3/component-name-unique.js +2 -4
  156. package/lib/rules/oas3/index.d.ts +1 -1
  157. package/lib/rules/oas3/index.js +2 -0
  158. package/lib/rules/oas3/no-empty-servers.d.ts +1 -1
  159. package/lib/rules/oas3/no-example-value-and-externalValue.d.ts +1 -1
  160. package/lib/rules/oas3/no-invalid-media-type-examples.d.ts +1 -1
  161. package/lib/rules/oas3/no-invalid-media-type-examples.js +1 -2
  162. package/lib/rules/oas3/no-server-example.com.d.ts +1 -1
  163. package/lib/rules/oas3/no-server-example.com.js +1 -0
  164. package/lib/rules/oas3/no-server-trailing-slash.d.ts +1 -1
  165. package/lib/rules/oas3/no-server-variables-empty-enum.d.ts +1 -1
  166. package/lib/rules/oas3/no-server-variables-empty-enum.js +1 -2
  167. package/lib/rules/oas3/no-undefined-server-variable.d.ts +1 -1
  168. package/lib/rules/oas3/no-undefined-server-variable.js +2 -3
  169. package/lib/rules/oas3/no-unused-components.d.ts +1 -1
  170. package/lib/rules/oas3/no-unused-components.js +1 -2
  171. package/lib/rules/oas3/response-contains-property.d.ts +1 -1
  172. package/lib/rules/oas3/response-contains-property.js +1 -2
  173. package/lib/rules/oas3/spec-components-invalid-map-name.d.ts +1 -1
  174. package/lib/rules/other/stats.d.ts +3 -3
  175. package/lib/rules/other/stats.js +5 -3
  176. package/lib/rules/spot/parameters-no-body-inside-in.d.ts +2 -0
  177. package/lib/rules/spot/parameters-no-body-inside-in.js +18 -0
  178. package/lib/rules/utils.d.ts +4 -2
  179. package/lib/rules/utils.js +41 -13
  180. package/lib/types/arazzo.d.ts +1 -2275
  181. package/lib/types/arazzo.js +246 -309
  182. package/lib/types/asyncapi2.d.ts +17 -0
  183. package/lib/types/{asyncapi.js → asyncapi2.js} +59 -53
  184. package/lib/types/asyncapi3.d.ts +2 -0
  185. package/lib/types/asyncapi3.js +347 -0
  186. package/lib/types/index.js +19 -10
  187. package/lib/types/json-schema-adapter.d.ts +1 -1
  188. package/lib/types/json-schema-adapter.js +4 -18
  189. package/lib/types/oas2.js +6 -6
  190. package/lib/types/oas3.d.ts +4 -0
  191. package/lib/types/oas3.js +19 -19
  192. package/lib/types/oas3_1.d.ts +3 -0
  193. package/lib/types/oas3_1.js +20 -14
  194. package/lib/types/redocly-yaml.d.ts +8 -6
  195. package/lib/types/redocly-yaml.js +135 -36
  196. package/lib/typings/arazzo.d.ts +145 -27
  197. package/lib/typings/asyncapi3.d.ts +53 -0
  198. package/lib/typings/asyncapi3.js +2 -0
  199. package/lib/typings/common.d.ts +1 -1
  200. package/lib/typings/swagger.d.ts +2 -2
  201. package/lib/utils.d.ts +4 -3
  202. package/lib/utils.js +55 -72
  203. package/lib/visitors.d.ts +29 -1
  204. package/lib/visitors.js +21 -8
  205. package/lib/walk.d.ts +3 -3
  206. package/lib/walk.js +30 -23
  207. package/package.json +3 -3
  208. package/src/__tests__/bundle.test.ts +144 -2
  209. package/src/__tests__/lint.test.ts +29 -21
  210. package/src/__tests__/walk.test.ts +25 -25
  211. package/src/benchmark/benches/lint-with-many-rules.bench.ts +7 -1
  212. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +7 -1
  213. package/src/benchmark/benches/lint-with-no-rules.bench.ts +8 -1
  214. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +18 -13
  215. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +17 -11
  216. package/src/benchmark/fork.js +4 -0
  217. package/src/benchmark/utils.ts +6 -5
  218. package/src/bundle.ts +19 -4
  219. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +32 -2
  220. package/src/config/__tests__/__snapshots__/config.test.ts.snap +24 -0
  221. package/src/config/__tests__/config-resolvers.test.ts +82 -0
  222. package/src/config/__tests__/config.test.ts +11 -0
  223. package/src/config/__tests__/fixtures/resolve-config/local-config-with-commonjs-export-function.yaml +2 -0
  224. package/src/config/__tests__/fixtures/resolve-config/local-config-with-esm.yaml +2 -0
  225. package/src/config/__tests__/fixtures/resolve-config/plugin-esm.mjs +10 -0
  226. package/src/config/__tests__/fixtures/resolve-config/plugin-with-export-function.cjs +10 -0
  227. package/src/config/__tests__/resolve-plugins.test.ts +4 -1
  228. package/src/config/all.ts +13 -1
  229. package/src/config/builtIn.ts +9 -8
  230. package/src/config/config-resolvers.ts +92 -21
  231. package/src/config/config.ts +31 -13
  232. package/src/config/load.ts +2 -2
  233. package/src/config/minimal.ts +13 -0
  234. package/src/config/recommended-strict.ts +14 -1
  235. package/src/config/recommended.ts +14 -1
  236. package/src/config/rules.ts +12 -4
  237. package/src/config/types.ts +34 -5
  238. package/src/config/utils.ts +28 -2
  239. package/src/decorators/__tests__/filter-in.test.ts +29 -26
  240. package/src/decorators/__tests__/filter-out.test.ts +32 -23
  241. package/src/decorators/__tests__/media-type-examples-override.test.ts +45 -45
  242. package/src/decorators/__tests__/remove-x-internal.test.ts +8 -5
  243. package/src/decorators/async3/index.ts +1 -0
  244. package/src/decorators/common/filters/filter-helper.ts +2 -1
  245. package/src/decorators/common/filters/filter-in.ts +2 -1
  246. package/src/decorators/common/filters/filter-out.ts +2 -1
  247. package/src/decorators/common/info-description-override.ts +3 -2
  248. package/src/decorators/common/info-override.ts +1 -1
  249. package/src/decorators/common/media-type-examples-override.ts +4 -3
  250. package/src/decorators/common/operation-description-override.ts +5 -4
  251. package/src/decorators/common/registry-dependencies.ts +2 -2
  252. package/src/decorators/common/remove-x-internal.ts +5 -4
  253. package/src/decorators/common/tag-description-override.ts +3 -2
  254. package/src/decorators/oas2/__tests__/remove-unused-components.test.ts +3 -3
  255. package/src/decorators/oas2/index.ts +2 -1
  256. package/src/decorators/oas2/remove-unused-components.ts +1 -1
  257. package/src/decorators/oas3/__tests__/remove-unused-components.test.ts +4 -4
  258. package/src/decorators/oas3/index.ts +2 -1
  259. package/src/decorators/oas3/remove-unused-components.ts +1 -1
  260. package/src/format/codeframes.ts +2 -1
  261. package/src/format/format.ts +9 -4
  262. package/src/index.ts +2 -1
  263. package/src/js-yaml/index.ts +3 -1
  264. package/src/lint.ts +28 -4
  265. package/src/logger.ts +2 -2
  266. package/src/oas-types.ts +41 -22
  267. package/src/redocly/domains.ts +1 -1
  268. package/src/redocly/index.ts +3 -3
  269. package/src/redocly/registry-api.ts +5 -3
  270. package/src/ref-utils.ts +4 -2
  271. package/src/resolve.ts +6 -4
  272. package/src/rules/__tests__/no-unresolved-refs.test.ts +21 -7
  273. package/src/rules/ajv.ts +2 -1
  274. package/src/rules/arazzo/__tests__/parameters-no-body-inside-in.test.ts +76 -0
  275. package/src/rules/arazzo/index.ts +6 -3
  276. package/src/rules/async2/__tests__/channels-kebab-case.test.ts +9 -5
  277. package/src/rules/async2/__tests__/no-channel-trailing-slash.test.ts +3 -3
  278. package/src/rules/async2/channels-kebab-case.ts +2 -2
  279. package/src/rules/async2/index.ts +9 -6
  280. package/src/rules/async2/no-channel-trailing-slash.ts +2 -2
  281. package/src/rules/async3/__tests__/channels-kebab-case.test.ts +145 -0
  282. package/src/rules/async3/__tests__/no-channel-trailing-slash.test.ts +96 -0
  283. package/src/rules/async3/channels-kebab-case.ts +19 -0
  284. package/src/rules/async3/index.ts +26 -0
  285. package/src/rules/async3/no-channel-trailing-slash.ts +16 -0
  286. package/src/rules/common/__tests__/info-license-strict.test.ts +141 -0
  287. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  288. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  289. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  290. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +5 -5
  291. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  292. package/src/rules/common/__tests__/no-invalid-parameter-examples.test.ts +1 -1
  293. package/src/rules/common/__tests__/no-invalid-schema-examples.test.ts +1 -1
  294. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +4 -4
  295. package/src/rules/common/__tests__/no-required-schema-properties-undefined.test.ts +11 -11
  296. package/src/rules/common/__tests__/operation-2xx-response.test.ts +8 -6
  297. package/src/rules/common/__tests__/operation-4xx-response.test.ts +9 -7
  298. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  299. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  300. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  301. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  302. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  303. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  304. package/src/rules/common/__tests__/path-params-defined.test.ts +5 -5
  305. package/src/rules/common/__tests__/paths-kebab-case.test.ts +6 -4
  306. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
  307. package/src/rules/common/__tests__/security-defined.test.ts +14 -8
  308. package/src/rules/common/__tests__/spec-strict-refs.test.ts +1 -1
  309. package/src/rules/common/__tests__/spec.test.ts +10 -10
  310. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  311. package/src/rules/common/__tests__/tags-alphabetical.test.ts +6 -4
  312. package/src/rules/common/assertions/asserts.ts +5 -9
  313. package/src/rules/common/assertions/index.ts +12 -4
  314. package/src/rules/common/assertions/utils.ts +4 -2
  315. package/src/rules/common/info-contact.ts +2 -1
  316. package/src/rules/common/info-license-strict.ts +24 -0
  317. package/src/rules/common/info-license-url.ts +2 -1
  318. package/src/rules/common/info-license.ts +2 -1
  319. package/src/rules/common/no-ambiguous-paths.ts +4 -4
  320. package/src/rules/common/no-enum-type-mismatch.ts +5 -4
  321. package/src/rules/common/no-http-verbs-in-paths.ts +5 -4
  322. package/src/rules/common/no-identical-paths.ts +4 -4
  323. package/src/rules/common/no-invalid-parameter-examples.ts +3 -2
  324. package/src/rules/common/no-path-trailing-slash.ts +2 -2
  325. package/src/rules/common/no-required-schema-properties-undefined.ts +5 -4
  326. package/src/rules/common/operation-2xx-response.ts +3 -2
  327. package/src/rules/common/operation-4xx-response.ts +3 -2
  328. package/src/rules/common/operation-description.ts +5 -4
  329. package/src/rules/common/operation-operationId-unique.ts +4 -4
  330. package/src/rules/common/operation-operationId-url-safe.ts +5 -4
  331. package/src/rules/common/operation-operationId.ts +5 -4
  332. package/src/rules/common/operation-parameters-unique.ts +4 -4
  333. package/src/rules/common/operation-singular-tag.ts +4 -4
  334. package/src/rules/common/operation-summary.ts +5 -4
  335. package/src/rules/common/operation-tag-defined.ts +4 -4
  336. package/src/rules/common/parameter-description.ts +4 -4
  337. package/src/rules/common/path-declaration-must-exist.ts +2 -2
  338. package/src/rules/common/path-excludes-patterns.ts +4 -4
  339. package/src/rules/common/path-http-verbs-order.ts +4 -4
  340. package/src/rules/common/path-not-include-query.ts +2 -2
  341. package/src/rules/common/path-params-defined.ts +4 -4
  342. package/src/rules/common/path-segment-plural.ts +3 -2
  343. package/src/rules/common/paths-kebab-case.ts +2 -2
  344. package/src/rules/common/required-string-property-missing-min-length.ts +4 -4
  345. package/src/rules/common/response-contains-header.ts +5 -4
  346. package/src/rules/common/scalar-property-missing-example.ts +2 -1
  347. package/src/rules/common/security-defined.ts +5 -5
  348. package/src/rules/common/spec-strict-refs.ts +2 -1
  349. package/src/rules/common/spec.ts +4 -3
  350. package/src/rules/common/tag-description.ts +2 -1
  351. package/src/rules/common/tags-alphabetical.ts +4 -4
  352. package/src/rules/no-unresolved-refs.ts +4 -3
  353. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +7 -5
  354. package/src/rules/oas2/__tests__/response-contains-header.test.ts +14 -8
  355. package/src/rules/oas2/__tests__/response-contains-property.test.ts +14 -8
  356. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +3 -1
  357. package/src/rules/oas2/boolean-parameter-prefixes.ts +1 -1
  358. package/src/rules/oas2/index.ts +8 -6
  359. package/src/rules/oas2/request-mime-type.ts +2 -1
  360. package/src/rules/oas2/response-contains-property.ts +3 -2
  361. package/src/rules/oas2/response-mime-type.ts +2 -1
  362. package/src/rules/oas3/__tests__/array-parameter-serialization.test.ts +18 -6
  363. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +7 -5
  364. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +6 -6
  365. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  366. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +34 -24
  367. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +3 -3
  368. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  369. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  370. package/src/rules/oas3/__tests__/operation-4xx-problem-details-rfc7807.test.ts +3 -3
  371. package/src/rules/oas3/__tests__/response-contains-header.test.ts +34 -22
  372. package/src/rules/oas3/__tests__/response-contains-property.test.ts +34 -20
  373. package/src/rules/oas3/__tests__/spec/spec.test.ts +12 -3
  374. package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +9 -3
  375. package/src/rules/oas3/__tests__/utils/lint-document-for-test.ts +1 -1
  376. package/src/rules/oas3/array-parameter-serialization.ts +3 -2
  377. package/src/rules/oas3/boolean-parameter-prefixes.ts +1 -1
  378. package/src/rules/oas3/component-name-unique.ts +3 -3
  379. package/src/rules/oas3/index.ts +42 -38
  380. package/src/rules/oas3/no-empty-servers.ts +1 -1
  381. package/src/rules/oas3/no-example-value-and-externalValue.ts +1 -1
  382. package/src/rules/oas3/no-invalid-media-type-examples.ts +6 -4
  383. package/src/rules/oas3/no-server-example.com.ts +2 -1
  384. package/src/rules/oas3/no-server-trailing-slash.ts +1 -1
  385. package/src/rules/oas3/no-server-variables-empty-enum.ts +2 -2
  386. package/src/rules/oas3/no-undefined-server-variable.ts +1 -1
  387. package/src/rules/oas3/no-unused-components.ts +2 -2
  388. package/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +2 -1
  389. package/src/rules/oas3/request-mime-type.ts +2 -1
  390. package/src/rules/oas3/response-contains-property.ts +3 -2
  391. package/src/rules/oas3/response-mime-type.ts +2 -1
  392. package/src/rules/oas3/spec-components-invalid-map-name.ts +3 -3
  393. package/src/rules/other/stats.ts +8 -6
  394. package/src/rules/spot/parameters-no-body-inside-in.ts +17 -0
  395. package/src/rules/utils.ts +41 -4
  396. package/src/types/arazzo.ts +257 -334
  397. package/src/types/{asyncapi.ts → asyncapi2.ts} +41 -35
  398. package/src/types/asyncapi3.ts +383 -0
  399. package/src/types/json-schema-adapter.ts +2 -2
  400. package/src/types/oas3.ts +4 -4
  401. package/src/types/oas3_1.ts +5 -4
  402. package/src/types/redocly-yaml.ts +21 -4
  403. package/src/typings/arazzo.ts +169 -41
  404. package/src/typings/asyncapi3.ts +61 -0
  405. package/src/typings/common.ts +1 -0
  406. package/src/typings/swagger.ts +2 -2
  407. package/src/utils.ts +5 -3
  408. package/src/visitors.ts +58 -1
  409. package/src/walk.ts +3 -3
  410. package/tsconfig.tsbuildinfo +1 -1
  411. package/lib/types/asyncapi.d.ts +0 -2
@@ -0,0 +1,76 @@
1
+ import { outdent } from 'outdent';
2
+ import { lintDocument } from '../../../lint';
3
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
+ import { BaseResolver } from '../../../resolve';
5
+ import { StyleguideConfig } from '../../../config';
6
+ import { ArazzoRule } from '../../../visitors';
7
+
8
+ describe('Arazzo parameters-no-body-inside-in', () => {
9
+ const document = parseYamlToDocument(
10
+ outdent`
11
+ arazzo: '1.0.0'
12
+ info:
13
+ title: Cool API
14
+ version: 1.0.0
15
+ description: A cool API
16
+ sourceDescriptions:
17
+ - name: museum-api
18
+ type: openapi
19
+ url: openapi.yaml
20
+ workflows:
21
+ - workflowId: get-museum-hours
22
+ description: This workflow demonstrates how to get the museum opening hours and buy tickets.
23
+ parameters:
24
+ - in: body
25
+ name: Authorization
26
+ value: Basic Og==
27
+ steps:
28
+ - stepId: get-museum-hours
29
+ description: >-
30
+ Get museum hours by resolving request details with getMuseumHours operationId from openapi.yaml description.
31
+ operationId: museum-api.getMuseumHours
32
+ successCriteria:
33
+ - condition: $statusCode == 200
34
+ `,
35
+ 'arazzo.yaml'
36
+ );
37
+
38
+ it('should not report on `body` inside parameter `in` field', async () => {
39
+ const results = await lintDocument({
40
+ externalRefResolver: new BaseResolver(),
41
+ document,
42
+ config: await makeConfig({ rules: {} }),
43
+ });
44
+
45
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
46
+ });
47
+
48
+ it('should report on `body` inside parameter `in` field', async () => {
49
+ const results = await lintDocument({
50
+ externalRefResolver: new BaseResolver(),
51
+ document,
52
+ config: await makeConfig({
53
+ rules: {},
54
+ arazzoRules: { 'parameters-no-body-inside-in': 'error' },
55
+ }),
56
+ });
57
+
58
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
59
+ [
60
+ {
61
+ "location": [
62
+ {
63
+ "pointer": "#/workflows/0/parameters/0/in",
64
+ "reportOnKey": false,
65
+ "source": "arazzo.yaml",
66
+ },
67
+ ],
68
+ "message": "The \`body\` value of the \`in\` property is not supported by Spot.",
69
+ "ruleId": "parameters-no-body-inside-in",
70
+ "severity": "error",
71
+ "suggest": [],
72
+ },
73
+ ]
74
+ `);
75
+ });
76
+ });
@@ -1,11 +1,14 @@
1
- import { ArazzoRule } from '../../visitors';
2
1
  import { Spec } from '../common/spec';
3
- import type { ArazzoRuleSet } from '../../oas-types';
4
2
  import { Assertions } from '../common/assertions';
3
+ import { ParametersNoBodyInsideIn } from '../spot/parameters-no-body-inside-in';
4
+
5
+ import type { ArazzoRule } from '../../visitors';
6
+ import type { ArazzoRuleSet } from '../../oas-types';
5
7
 
6
8
  export const rules: ArazzoRuleSet<'built-in'> = {
7
9
  spec: Spec as ArazzoRule,
8
- assertions: Assertions,
10
+ assertions: Assertions as ArazzoRule,
11
+ 'parameters-no-body-inside-in': ParametersNoBodyInsideIn as ArazzoRule,
9
12
  };
10
13
 
11
14
  export const preprocessors = {};
@@ -23,7 +23,7 @@ describe('Async2 channels-kebab-case', () => {
23
23
  const results = await lintDocument({
24
24
  externalRefResolver: new BaseResolver(),
25
25
  document,
26
- config: await makeConfig({ 'channels-kebab-case': 'error' }),
26
+ config: await makeConfig({ rules: { 'channels-kebab-case': 'error' } }),
27
27
  });
28
28
 
29
29
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
@@ -64,7 +64,7 @@ describe('Async2 channels-kebab-case', () => {
64
64
  const results = await lintDocument({
65
65
  externalRefResolver: new BaseResolver(),
66
66
  document,
67
- config: await makeConfig({ 'channels-kebab-case': 'error' }),
67
+ config: await makeConfig({ rules: { 'channels-kebab-case': 'error' } }),
68
68
  });
69
69
 
70
70
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
@@ -106,8 +106,10 @@ describe('Async2 channels-kebab-case', () => {
106
106
  externalRefResolver: new BaseResolver(),
107
107
  document,
108
108
  config: await makeConfig({
109
- 'paths-kebab-case': 'error',
110
- 'no-path-trailing-slash': 'off',
109
+ rules: {
110
+ 'paths-kebab-case': 'error',
111
+ 'no-path-trailing-slash': 'off',
112
+ },
111
113
  }),
112
114
  });
113
115
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
@@ -133,7 +135,9 @@ describe('Async2 channels-kebab-case', () => {
133
135
  externalRefResolver: new BaseResolver(),
134
136
  document,
135
137
  config: await makeConfig({
136
- 'paths-kebab-case': 'error',
138
+ rules: {
139
+ 'paths-kebab-case': 'error',
140
+ },
137
141
  }),
138
142
  });
139
143
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
@@ -23,7 +23,7 @@ describe('no-channel-trailing-slash', () => {
23
23
  const results = await lintDocument({
24
24
  externalRefResolver: new BaseResolver(),
25
25
  document,
26
- config: await makeConfig({ 'no-channel-trailing-slash': 'error' }),
26
+ config: await makeConfig({ rules: { 'no-channel-trailing-slash': 'error' } }),
27
27
  });
28
28
 
29
29
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
@@ -64,7 +64,7 @@ describe('no-channel-trailing-slash', () => {
64
64
  const results = await lintDocument({
65
65
  externalRefResolver: new BaseResolver(),
66
66
  document,
67
- config: await makeConfig({ 'no-channel-trailing-slash': 'error' }),
67
+ config: await makeConfig({ rules: { 'no-channel-trailing-slash': 'error' } }),
68
68
  });
69
69
 
70
70
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
@@ -89,7 +89,7 @@ describe('no-channel-trailing-slash', () => {
89
89
  const results = await lintDocument({
90
90
  externalRefResolver: new BaseResolver(),
91
91
  document,
92
- config: await makeConfig({ 'no-channel-trailing-slash': 'error' }),
92
+ config: await makeConfig({ rules: { 'no-channel-trailing-slash': 'error' } }),
93
93
  });
94
94
 
95
95
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
@@ -1,5 +1,5 @@
1
- import { Async2Rule } from '../../visitors';
2
- import { UserContext } from '../../walk';
1
+ import type { Async2Rule } from '../../visitors';
2
+ import type { UserContext } from '../../walk';
3
3
 
4
4
  export const ChannelsKebabCase: Async2Rule = () => {
5
5
  return {
@@ -1,23 +1,26 @@
1
- import { Async2Rule } from '../../visitors';
2
1
  import { Assertions } from '../common/assertions';
3
2
  import { Spec } from '../common/spec';
4
3
  import { InfoContact } from '../common/info-contact';
4
+ import { InfoLicenseStrict } from '../common/info-license-strict';
5
5
  import { OperationOperationId } from '../common/operation-operationId';
6
6
  import { TagDescription } from '../common/tag-description';
7
7
  import { TagsAlphabetical } from '../common/tags-alphabetical';
8
8
  import { ChannelsKebabCase } from './channels-kebab-case';
9
9
  import { NoChannelTrailingSlash } from './no-channel-trailing-slash';
10
+
11
+ import type { Async2Rule } from '../../visitors';
10
12
  import type { Async2RuleSet } from '../../oas-types';
11
13
 
12
14
  export const rules: Async2RuleSet<'built-in'> = {
13
15
  spec: Spec as Async2Rule,
14
- assertions: Assertions,
15
- 'info-contact': InfoContact,
16
- 'operation-operationId': OperationOperationId,
16
+ assertions: Assertions as Async2Rule,
17
+ 'info-contact': InfoContact as Async2Rule,
18
+ 'info-license-strict': InfoLicenseStrict as Async2Rule,
19
+ 'operation-operationId': OperationOperationId as Async2Rule,
17
20
  'channels-kebab-case': ChannelsKebabCase,
18
21
  'no-channel-trailing-slash': NoChannelTrailingSlash,
19
- 'tag-description': TagDescription,
20
- 'tags-alphabetical': TagsAlphabetical,
22
+ 'tag-description': TagDescription as Async2Rule,
23
+ 'tags-alphabetical': TagsAlphabetical as Async2Rule,
21
24
  };
22
25
 
23
26
  export const preprocessors = {};
@@ -1,5 +1,5 @@
1
- import { Async2Rule } from '../../visitors';
2
- import { UserContext } from '../../walk';
1
+ import type { Async2Rule } from '../../visitors';
2
+ import type { UserContext } from '../../walk';
3
3
 
4
4
  export const NoChannelTrailingSlash: Async2Rule = () => {
5
5
  return {
@@ -0,0 +1,145 @@
1
+ import { outdent } from 'outdent';
2
+ import { lintDocument } from '../../../lint';
3
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('Async2 channels-kebab-case', () => {
7
+ it('should report on no kebab-case channel path', async () => {
8
+ const document = parseYamlToDocument(
9
+ outdent`
10
+ asyncapi: '3.0.0'
11
+ info:
12
+ title: Cool API
13
+ version: 1.0.0
14
+ channels:
15
+ channel1:
16
+ address: /NOT_A_KEBAB/
17
+ payload:
18
+ type: object
19
+ `,
20
+ 'asyncapi.yaml'
21
+ );
22
+
23
+ const results = await lintDocument({
24
+ externalRefResolver: new BaseResolver(),
25
+ document,
26
+ config: await makeConfig({ rules: { 'channels-kebab-case': 'error' } }),
27
+ });
28
+
29
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
30
+ [
31
+ {
32
+ "location": [
33
+ {
34
+ "pointer": "#/channels/channel1",
35
+ "reportOnKey": true,
36
+ "source": "asyncapi.yaml",
37
+ },
38
+ ],
39
+ "message": "\`/NOT_A_KEBAB/\` does not use kebab-case.",
40
+ "ruleId": "channels-kebab-case",
41
+ "severity": "error",
42
+ "suggest": [],
43
+ },
44
+ ]
45
+ `);
46
+ });
47
+
48
+ it('should report on snake_case in channel path', async () => {
49
+ const document = parseYamlToDocument(
50
+ outdent`
51
+ asyncapi: '3.0.0'
52
+ info:
53
+ title: Cool API
54
+ version: 1.0.0
55
+ channels:
56
+ channel1:
57
+ address: snake_kebab
58
+ payload:
59
+ type: object
60
+ `,
61
+ 'asyncapi.yaml'
62
+ );
63
+
64
+ const results = await lintDocument({
65
+ externalRefResolver: new BaseResolver(),
66
+ document,
67
+ config: await makeConfig({ rules: { 'channels-kebab-case': 'error' } }),
68
+ });
69
+
70
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
71
+ [
72
+ {
73
+ "location": [
74
+ {
75
+ "pointer": "#/channels/channel1",
76
+ "reportOnKey": true,
77
+ "source": "asyncapi.yaml",
78
+ },
79
+ ],
80
+ "message": "\`snake_kebab\` does not use kebab-case.",
81
+ "ruleId": "channels-kebab-case",
82
+ "severity": "error",
83
+ "suggest": [],
84
+ },
85
+ ]
86
+ `);
87
+ });
88
+
89
+ it('should allow trailing slash in channel path with "channels-kebab-case" rule', async () => {
90
+ const document = parseYamlToDocument(
91
+ outdent`
92
+ asyncapi: '3.0.0'
93
+ info:
94
+ title: Cool API
95
+ version: 1.0.0
96
+ channels:
97
+ channel1:
98
+ address: kebab/
99
+ payload:
100
+ type: object
101
+ `,
102
+ 'asyncapi.yaml'
103
+ );
104
+
105
+ const results = await lintDocument({
106
+ externalRefResolver: new BaseResolver(),
107
+ document,
108
+ config: await makeConfig({
109
+ rules: {
110
+ 'paths-kebab-case': 'error',
111
+ 'no-path-trailing-slash': 'off',
112
+ },
113
+ }),
114
+ });
115
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
116
+ });
117
+
118
+ it('words with hyphens are allowed with "channels-kebab-case" rule', async () => {
119
+ const document = parseYamlToDocument(
120
+ outdent`
121
+ asyncapi: '3.0.0'
122
+ info:
123
+ title: Cool API
124
+ version: 1.0.0
125
+ channels:
126
+ channel1:
127
+ address: kebab-with-longer-channel-path:/
128
+ payload:
129
+ type: object
130
+ `,
131
+ 'asyncapi.yaml'
132
+ );
133
+
134
+ const results = await lintDocument({
135
+ externalRefResolver: new BaseResolver(),
136
+ document,
137
+ config: await makeConfig({
138
+ rules: {
139
+ 'paths-kebab-case': 'error',
140
+ },
141
+ }),
142
+ });
143
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
144
+ });
145
+ });
@@ -0,0 +1,96 @@
1
+ import { outdent } from 'outdent';
2
+ import { lintDocument } from '../../../lint';
3
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('no-channel-trailing-slash', () => {
7
+ it.only('should report on trailing slash in a channel path', async () => {
8
+ const document = parseYamlToDocument(
9
+ outdent`
10
+ asyncapi: '3.0.0'
11
+ info:
12
+ title: Excellent API
13
+ version: 1.0.0
14
+ channels:
15
+ channel1:
16
+ address: /trailing/
17
+ payload:
18
+ type: object
19
+ `,
20
+ 'asyncapi.yaml'
21
+ );
22
+
23
+ const results = await lintDocument({
24
+ externalRefResolver: new BaseResolver(),
25
+ document,
26
+ config: await makeConfig({ rules: { 'no-channel-trailing-slash': 'error' } }),
27
+ });
28
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
29
+ [
30
+ {
31
+ "location": [
32
+ {
33
+ "pointer": "#/channels/channel1",
34
+ "reportOnKey": true,
35
+ "source": "asyncapi.yaml",
36
+ },
37
+ ],
38
+ "message": "\`/trailing/\` should not have a trailing slash.",
39
+ "ruleId": "no-channel-trailing-slash",
40
+ "severity": "error",
41
+ "suggest": [],
42
+ },
43
+ ]
44
+ `);
45
+ });
46
+
47
+ it('should not report on if no trailing slash in path', async () => {
48
+ const document = parseYamlToDocument(
49
+ outdent`
50
+ asyncapi: '3.0.0'
51
+ info:
52
+ title: Excellent API
53
+ version: 1.0.0
54
+ channels:
55
+ channel1:
56
+ address: /expected
57
+ payload:
58
+ type: object
59
+ `,
60
+ 'asyncapi.yaml'
61
+ );
62
+
63
+ const results = await lintDocument({
64
+ externalRefResolver: new BaseResolver(),
65
+ document,
66
+ config: await makeConfig({ rules: { 'no-channel-trailing-slash': 'error' } }),
67
+ });
68
+
69
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
70
+ });
71
+
72
+ it('should not report on trailing slash in path if the path is root', async () => {
73
+ const document = parseYamlToDocument(
74
+ outdent`
75
+ asyncapi: '3.0.0'
76
+ info:
77
+ title: Excellent API
78
+ version: 1.0.0
79
+ channels:
80
+ channel1:
81
+ address: /
82
+ payload:
83
+ type: object
84
+ `,
85
+ 'foobar.yaml'
86
+ );
87
+
88
+ const results = await lintDocument({
89
+ externalRefResolver: new BaseResolver(),
90
+ document,
91
+ config: await makeConfig({ rules: { 'no-channel-trailing-slash': 'error' } }),
92
+ });
93
+
94
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
95
+ });
96
+ });
@@ -0,0 +1,19 @@
1
+ import type { Channel } from '../../typings/asyncapi3';
2
+ import type { Async3Rule } from '../../visitors';
3
+ import type { UserContext } from '../../walk';
4
+
5
+ export const ChannelsKebabCase: Async3Rule = () => {
6
+ return {
7
+ Channel(channel: Channel, { report }: UserContext) {
8
+ const segments = (channel.address || '')
9
+ .split(/[/.:]/) // split on / or : as likely channel namespacers
10
+ .filter((s) => s !== ''); // filter out empty segments
11
+ if (!segments.every((segment) => /^{.+}$/.test(segment) || /^[a-z0-9-.]+$/.test(segment))) {
12
+ report({
13
+ message: `\`${channel.address}\` does not use kebab-case.`,
14
+ location: { reportOnKey: true },
15
+ });
16
+ }
17
+ },
18
+ };
19
+ };
@@ -0,0 +1,26 @@
1
+ import { Assertions } from '../common/assertions';
2
+ import { Spec } from '../common/spec';
3
+ import { InfoContact } from '../common/info-contact';
4
+ import { InfoLicenseStrict } from '../common/info-license-strict';
5
+ import { OperationOperationId } from '../common/operation-operationId';
6
+ import { TagDescription } from '../common/tag-description';
7
+ import { TagsAlphabetical } from '../common/tags-alphabetical';
8
+ import { ChannelsKebabCase } from './channels-kebab-case';
9
+ import { NoChannelTrailingSlash } from './no-channel-trailing-slash';
10
+
11
+ import type { Async3Rule } from '../../visitors';
12
+ import type { Async3RuleSet } from '../../oas-types';
13
+
14
+ export const rules: Async3RuleSet<'built-in'> = {
15
+ spec: Spec as Async3Rule,
16
+ assertions: Assertions as Async3Rule,
17
+ 'info-contact': InfoContact as Async3Rule,
18
+ 'info-license-strict': InfoLicenseStrict as Async3Rule,
19
+ 'operation-operationId': OperationOperationId as Async3Rule,
20
+ 'channels-kebab-case': ChannelsKebabCase,
21
+ 'no-channel-trailing-slash': NoChannelTrailingSlash,
22
+ 'tag-description': TagDescription as Async3Rule,
23
+ 'tags-alphabetical': TagsAlphabetical as Async3Rule,
24
+ };
25
+
26
+ export const preprocessors = {};
@@ -0,0 +1,16 @@
1
+ import type { Async3Rule } from '../../visitors';
2
+ import type { UserContext } from '../../walk';
3
+ import type { Channel } from '../../typings/asyncapi3';
4
+
5
+ export const NoChannelTrailingSlash: Async3Rule = () => {
6
+ return {
7
+ Channel(channel: Channel, { report, location }: UserContext) {
8
+ if ((channel.address as string).endsWith('/') && channel.address !== '/') {
9
+ report({
10
+ message: `\`${channel.address}\` should not have a trailing slash.`,
11
+ location: location.key(),
12
+ });
13
+ }
14
+ },
15
+ };
16
+ };
@@ -0,0 +1,141 @@
1
+ import { outdent } from 'outdent';
2
+ import { lintDocument } from '../../../lint';
3
+ import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
4
+ import { BaseResolver } from '../../../resolve';
5
+
6
+ describe('license-strict', () => {
7
+ it('should report on info.license with no url or identifier for OpenAPI 3.1', async () => {
8
+ const document = parseYamlToDocument(
9
+ outdent`
10
+ openapi: 3.1.0
11
+ info:
12
+ license:
13
+ name: MIT
14
+ `,
15
+ 'foobar.yaml'
16
+ );
17
+
18
+ const results = await lintDocument({
19
+ externalRefResolver: new BaseResolver(),
20
+ document,
21
+ config: await makeConfig({ rules: { 'info-license-strict': 'error' } }),
22
+ });
23
+
24
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
25
+ [
26
+ {
27
+ "location": [
28
+ {
29
+ "pointer": "#/info/license",
30
+ "reportOnKey": true,
31
+ "source": "foobar.yaml",
32
+ },
33
+ ],
34
+ "message": "License object should contain one of the fields: \`url\`, \`identifier\`.",
35
+ "ruleId": "info-license-strict",
36
+ "severity": "error",
37
+ "suggest": [],
38
+ },
39
+ ]
40
+ `);
41
+ });
42
+
43
+ it('should not report on info.license with url for OpenAPI 3.1', async () => {
44
+ const document = parseYamlToDocument(
45
+ outdent`
46
+ openapi: 3.1.0
47
+ info:
48
+ license:
49
+ name: MIT
50
+ url: google.com
51
+ `,
52
+ 'foobar.yaml'
53
+ );
54
+
55
+ const results = await lintDocument({
56
+ externalRefResolver: new BaseResolver(),
57
+ document,
58
+ config: await makeConfig({ rules: { 'info-license-strict': 'error' } }),
59
+ });
60
+
61
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
62
+ });
63
+
64
+ it('should not report on info.license with identifier', async () => {
65
+ const document = parseYamlToDocument(
66
+ outdent`
67
+ openapi: 3.1.0
68
+ info:
69
+ license:
70
+ name: MIT
71
+ identifier: MIT
72
+ `,
73
+ 'foobar.yaml'
74
+ );
75
+
76
+ const results = await lintDocument({
77
+ externalRefResolver: new BaseResolver(),
78
+ document,
79
+ config: await makeConfig({ rules: { 'info-license-strict': 'error' } }),
80
+ });
81
+
82
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
83
+ });
84
+
85
+ it('should report on info.license with no url for AsyncAPI 3.0', async () => {
86
+ const document = parseYamlToDocument(
87
+ outdent`
88
+ asyncapi: 3.0.0
89
+ info:
90
+ license:
91
+ name: MIT
92
+ `,
93
+ 'foobar.yaml'
94
+ );
95
+
96
+ const results = await lintDocument({
97
+ externalRefResolver: new BaseResolver(),
98
+ document,
99
+ config: await makeConfig({ rules: { 'info-license-strict': 'error' } }),
100
+ });
101
+
102
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
103
+ [
104
+ {
105
+ "location": [
106
+ {
107
+ "pointer": "#/info/license/url",
108
+ "reportOnKey": true,
109
+ "source": "foobar.yaml",
110
+ },
111
+ ],
112
+ "message": "License object should contain \`url\` field.",
113
+ "ruleId": "info-license-strict",
114
+ "severity": "error",
115
+ "suggest": [],
116
+ },
117
+ ]
118
+ `);
119
+ });
120
+
121
+ it('should not report on info.license with url for AsyncAPI 3.0', async () => {
122
+ const document = parseYamlToDocument(
123
+ outdent`
124
+ asyncapi: 3.0.0
125
+ info:
126
+ license:
127
+ name: MIT
128
+ url: google.com
129
+ `,
130
+ 'foobar.yaml'
131
+ );
132
+
133
+ const results = await lintDocument({
134
+ externalRefResolver: new BaseResolver(),
135
+ document,
136
+ config: await makeConfig({ rules: { 'info-license-strict': 'error' } }),
137
+ });
138
+
139
+ expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);
140
+ });
141
+ });
@@ -17,7 +17,7 @@ describe('Oas3 info-license', () => {
17
17
  const results = await lintDocument({
18
18
  externalRefResolver: new BaseResolver(),
19
19
  document,
20
- config: await makeConfig({ 'info-license': 'error' }),
20
+ config: await makeConfig({ rules: { 'info-license': 'error' } }),
21
21
  });
22
22
 
23
23
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
@@ -54,7 +54,7 @@ describe('Oas3 info-license', () => {
54
54
  const results = await lintDocument({
55
55
  externalRefResolver: new BaseResolver(),
56
56
  document,
57
- config: await makeConfig({ 'info-license': 'error' }),
57
+ config: await makeConfig({ rules: { 'info-license': 'error' } }),
58
58
  });
59
59
 
60
60
  expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`);