@redocly/openapi-core 1.0.0-beta.99 → 1.0.0-rc.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 (382) hide show
  1. package/README.md +6 -6
  2. package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.js +0 -1
  3. package/lib/benchmark/benches/recommended-oas3.bench.js +1 -1
  4. package/lib/benchmark/benches/resolve-with-no-external.bench.js +1 -1
  5. package/lib/benchmark/utils.d.ts +2 -2
  6. package/lib/benchmark/utils.js +2 -2
  7. package/lib/bundle.d.ts +10 -15
  8. package/lib/bundle.js +32 -12
  9. package/lib/config/all.d.ts +2 -2
  10. package/lib/config/all.js +16 -6
  11. package/lib/config/builtIn.d.ts +2 -2
  12. package/lib/config/builtIn.js +2 -2
  13. package/lib/config/config-resolvers.d.ts +5 -5
  14. package/lib/config/config-resolvers.js +121 -66
  15. package/lib/config/config.d.ts +12 -18
  16. package/lib/config/config.js +42 -26
  17. package/lib/config/load.d.ts +16 -3
  18. package/lib/config/load.js +36 -14
  19. package/lib/config/minimal.d.ts +2 -2
  20. package/lib/config/minimal.js +10 -6
  21. package/lib/config/recommended.d.ts +2 -2
  22. package/lib/config/recommended.js +10 -6
  23. package/lib/config/rules.d.ts +7 -4
  24. package/lib/config/rules.js +5 -4
  25. package/lib/config/types.d.ts +72 -23
  26. package/lib/config/types.js +13 -0
  27. package/lib/config/utils.d.ts +6 -5
  28. package/lib/config/utils.js +110 -32
  29. package/lib/decorators/common/filters/filter-helper.d.ts +3 -0
  30. package/lib/decorators/common/filters/filter-helper.js +67 -0
  31. package/lib/decorators/common/filters/filter-in.d.ts +2 -0
  32. package/lib/decorators/common/filters/filter-in.js +17 -0
  33. package/lib/decorators/common/filters/filter-out.d.ts +2 -0
  34. package/lib/decorators/common/filters/filter-out.js +17 -0
  35. package/lib/decorators/common/info-override.d.ts +2 -0
  36. package/lib/decorators/common/info-override.js +28 -0
  37. package/lib/decorators/common/media-type-examples-override.d.ts +2 -0
  38. package/lib/decorators/common/media-type-examples-override.js +53 -0
  39. package/lib/decorators/common/registry-dependencies.js +2 -2
  40. package/lib/decorators/common/remove-x-internal.js +2 -2
  41. package/lib/decorators/oas2/index.d.ts +3 -0
  42. package/lib/decorators/oas2/index.js +7 -1
  43. package/lib/decorators/oas3/index.d.ts +4 -0
  44. package/lib/decorators/oas3/index.js +9 -1
  45. package/lib/env.d.ts +3 -0
  46. package/lib/env.js +8 -0
  47. package/lib/format/codeframes.js +16 -10
  48. package/lib/format/format.d.ts +1 -1
  49. package/lib/format/format.js +64 -32
  50. package/lib/index.d.ts +6 -6
  51. package/lib/index.js +7 -2
  52. package/lib/js-yaml/index.js +2 -6
  53. package/lib/lint.d.ts +4 -2
  54. package/lib/lint.js +36 -11
  55. package/lib/logger.d.ts +10 -0
  56. package/lib/logger.js +31 -0
  57. package/lib/output.d.ts +3 -0
  58. package/lib/output.js +9 -0
  59. package/lib/redocly/index.js +10 -9
  60. package/lib/redocly/registry-api-types.d.ts +28 -28
  61. package/lib/redocly/registry-api.d.ts +3 -3
  62. package/lib/redocly/registry-api.js +10 -2
  63. package/lib/ref-utils.d.ts +1 -0
  64. package/lib/ref-utils.js +7 -2
  65. package/lib/resolve.d.ts +1 -1
  66. package/lib/resolve.js +33 -3
  67. package/lib/rules/ajv.d.ts +2 -2
  68. package/lib/rules/ajv.js +12 -12
  69. package/lib/rules/common/assertions/asserts.d.ts +29 -4
  70. package/lib/rules/common/assertions/asserts.js +227 -97
  71. package/lib/rules/common/assertions/index.d.ts +27 -2
  72. package/lib/rules/common/assertions/index.js +9 -37
  73. package/lib/rules/common/assertions/utils.d.ts +16 -8
  74. package/lib/rules/common/assertions/utils.js +160 -76
  75. package/lib/rules/common/info-license-url.d.ts +1 -1
  76. package/lib/rules/common/info-license-url.js +5 -10
  77. package/lib/rules/common/info-license.d.ts +2 -0
  78. package/lib/rules/common/info-license.js +17 -0
  79. package/lib/rules/common/no-ambiguous-paths.js +1 -1
  80. package/lib/rules/common/no-enum-type-mismatch.js +1 -3
  81. package/lib/rules/common/no-identical-paths.js +4 -4
  82. package/lib/rules/common/no-invalid-parameter-examples.js +3 -3
  83. package/lib/rules/common/no-invalid-schema-examples.js +3 -3
  84. package/lib/rules/common/operation-2xx-response.js +15 -9
  85. package/lib/rules/common/operation-4xx-response.js +15 -9
  86. package/lib/rules/common/operation-operationId.js +2 -2
  87. package/lib/rules/common/operation-tag-defined.js +1 -1
  88. package/lib/rules/common/path-not-include-query.js +2 -2
  89. package/lib/rules/common/path-params-defined.js +7 -2
  90. package/lib/rules/common/paths-kebab-case.js +4 -1
  91. package/lib/rules/common/required-string-property-missing-min-length.d.ts +2 -0
  92. package/lib/rules/common/required-string-property-missing-min-length.js +37 -0
  93. package/lib/rules/common/response-contains-header.js +2 -2
  94. package/lib/rules/common/scalar-property-missing-example.js +2 -1
  95. package/lib/rules/common/security-defined.d.ts +2 -0
  96. package/lib/rules/common/{operation-security-defined.js → security-defined.js} +25 -6
  97. package/lib/rules/common/spec-strict-refs.d.ts +2 -0
  98. package/lib/rules/common/spec-strict-refs.js +30 -0
  99. package/lib/rules/common/spec.js +41 -18
  100. package/lib/rules/common/tags-alphabetical.js +1 -1
  101. package/lib/rules/oas2/index.d.ts +3 -2
  102. package/lib/rules/oas2/index.js +10 -8
  103. package/lib/rules/oas2/remove-unused-components.js +6 -6
  104. package/lib/rules/oas2/request-mime-type.d.ts +1 -1
  105. package/lib/rules/oas2/request-mime-type.js +1 -1
  106. package/lib/rules/oas2/response-mime-type.d.ts +1 -1
  107. package/lib/rules/oas2/response-mime-type.js +1 -1
  108. package/lib/rules/oas3/component-name-unique.d.ts +2 -0
  109. package/lib/rules/oas3/component-name-unique.js +124 -0
  110. package/lib/rules/oas3/index.js +18 -10
  111. package/lib/rules/oas3/no-empty-servers.js +2 -2
  112. package/lib/rules/oas3/no-invalid-media-type-examples.js +2 -2
  113. package/lib/rules/oas3/no-server-variables-empty-enum.d.ts +2 -0
  114. package/lib/rules/oas3/{no-servers-empty-enum.js → no-server-variables-empty-enum.js} +5 -5
  115. package/lib/rules/oas3/no-unused-components.js +2 -2
  116. package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.d.ts +5 -0
  117. package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.js +36 -0
  118. package/lib/rules/oas3/remove-unused-components.js +6 -6
  119. package/lib/rules/oas3/request-mime-type.d.ts +1 -1
  120. package/lib/rules/oas3/request-mime-type.js +1 -1
  121. package/lib/rules/oas3/response-mime-type.d.ts +1 -1
  122. package/lib/rules/oas3/response-mime-type.js +1 -1
  123. package/lib/rules/oas3/spec-components-invalid-map-name.d.ts +2 -0
  124. package/lib/rules/oas3/spec-components-invalid-map-name.js +62 -0
  125. package/lib/rules/other/stats.d.ts +2 -2
  126. package/lib/rules/other/stats.js +45 -16
  127. package/lib/rules/utils.d.ts +5 -2
  128. package/lib/rules/utils.js +54 -6
  129. package/lib/types/config-external-schemas.d.ts +2193 -0
  130. package/lib/types/config-external-schemas.js +805 -0
  131. package/lib/types/index.d.ts +3 -2
  132. package/lib/types/index.js +9 -1
  133. package/lib/types/oas2.js +91 -15
  134. package/lib/types/oas3.js +125 -46
  135. package/lib/types/oas3_1.js +23 -19
  136. package/lib/types/redocly-yaml.js +406 -60
  137. package/lib/utils.d.ts +15 -4
  138. package/lib/utils.js +72 -8
  139. package/lib/visitors.d.ts +20 -16
  140. package/lib/visitors.js +28 -3
  141. package/lib/walk.d.ts +11 -19
  142. package/lib/walk.js +74 -53
  143. package/package.json +5 -6
  144. package/__tests__/utils.ts +0 -86
  145. package/lib/rules/common/info-description.d.ts +0 -2
  146. package/lib/rules/common/info-description.js +0 -12
  147. package/lib/rules/common/license-url.d.ts +0 -2
  148. package/lib/rules/common/license-url.js +0 -12
  149. package/lib/rules/common/operation-security-defined.d.ts +0 -2
  150. package/lib/rules/oas3/no-servers-empty-enum.d.ts +0 -2
  151. package/src/__tests__/__snapshots__/bundle.test.ts.snap +0 -255
  152. package/src/__tests__/bundle.test.ts +0 -156
  153. package/src/__tests__/codeframes.test.ts +0 -531
  154. package/src/__tests__/fixtures/extension.js +0 -24
  155. package/src/__tests__/fixtures/refs/definitions.yaml +0 -3
  156. package/src/__tests__/fixtures/refs/examples.yaml +0 -8
  157. package/src/__tests__/fixtures/refs/external-request-body.yaml +0 -13
  158. package/src/__tests__/fixtures/refs/externalref.yaml +0 -35
  159. package/src/__tests__/fixtures/refs/hosted.yaml +0 -35
  160. package/src/__tests__/fixtures/refs/openapi-with-external-refs-conflicting-names.yaml +0 -21
  161. package/src/__tests__/fixtures/refs/openapi-with-external-refs.yaml +0 -33
  162. package/src/__tests__/fixtures/refs/openapi-with-url-refs.yaml +0 -18
  163. package/src/__tests__/fixtures/refs/param-b.yaml +0 -1
  164. package/src/__tests__/fixtures/refs/param-c.yaml +0 -1
  165. package/src/__tests__/fixtures/refs/rename.yaml +0 -1
  166. package/src/__tests__/fixtures/refs/requestBody.yaml +0 -9
  167. package/src/__tests__/fixtures/refs/schema-a.yaml +0 -1
  168. package/src/__tests__/fixtures/refs/simple.yaml +0 -1
  169. package/src/__tests__/fixtures/refs/vendor.schema.yaml +0 -20
  170. package/src/__tests__/fixtures/resolve/External.yaml +0 -10
  171. package/src/__tests__/fixtures/resolve/External2.yaml +0 -4
  172. package/src/__tests__/fixtures/resolve/description.md +0 -3
  173. package/src/__tests__/fixtures/resolve/externalInfo.yaml +0 -4
  174. package/src/__tests__/fixtures/resolve/externalLicense.yaml +0 -1
  175. package/src/__tests__/fixtures/resolve/openapi-with-back.yaml +0 -13
  176. package/src/__tests__/fixtures/resolve/openapi-with-md-description.yaml +0 -5
  177. package/src/__tests__/fixtures/resolve/openapi.yaml +0 -28
  178. package/src/__tests__/fixtures/resolve/schemas/type-a.yaml +0 -10
  179. package/src/__tests__/fixtures/resolve/schemas/type-b.yaml +0 -6
  180. package/src/__tests__/fixtures/resolve/transitive/a.yaml +0 -1
  181. package/src/__tests__/fixtures/resolve/transitive/components.yaml +0 -5
  182. package/src/__tests__/fixtures/resolve/transitive/schemas.yaml +0 -3
  183. package/src/__tests__/js-yaml.test.ts +0 -71
  184. package/src/__tests__/lint.test.ts +0 -195
  185. package/src/__tests__/login.test.ts +0 -17
  186. package/src/__tests__/normalizeVisitors.test.ts +0 -151
  187. package/src/__tests__/ref-utils.test.ts +0 -120
  188. package/src/__tests__/resolve-http.test.ts +0 -77
  189. package/src/__tests__/resolve.test.ts +0 -405
  190. package/src/__tests__/utils.test.ts +0 -85
  191. package/src/__tests__/walk.test.ts +0 -1485
  192. package/src/benchmark/benches/lint-with-many-rules.bench.ts +0 -35
  193. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +0 -39
  194. package/src/benchmark/benches/lint-with-no-rules.bench.ts +0 -20
  195. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +0 -36
  196. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +0 -32
  197. package/src/benchmark/benches/rebilly.yaml +0 -32267
  198. package/src/benchmark/benches/recommended-oas3.bench.ts +0 -22
  199. package/src/benchmark/benches/resolve-with-no-external.bench.ts +0 -23
  200. package/src/benchmark/benchmark.js +0 -307
  201. package/src/benchmark/colors.js +0 -29
  202. package/src/benchmark/fork.js +0 -83
  203. package/src/benchmark/utils.ts +0 -36
  204. package/src/bundle.ts +0 -386
  205. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +0 -157
  206. package/src/config/__tests__/config-resolvers.test.ts +0 -429
  207. package/src/config/__tests__/config.test.ts +0 -244
  208. package/src/config/__tests__/fixtures/plugin-config.yaml +0 -3
  209. package/src/config/__tests__/fixtures/plugin.js +0 -56
  210. package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +0 -12
  211. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +0 -67
  212. package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +0 -8
  213. package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +0 -19
  214. package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +0 -10
  215. package/src/config/__tests__/fixtures/resolve-config/plugin.js +0 -66
  216. package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +0 -4
  217. package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +0 -5
  218. package/src/config/__tests__/load.test.ts +0 -83
  219. package/src/config/__tests__/resolve-plugins.test.ts +0 -27
  220. package/src/config/all.ts +0 -66
  221. package/src/config/builtIn.ts +0 -37
  222. package/src/config/config-resolvers.ts +0 -359
  223. package/src/config/config.ts +0 -312
  224. package/src/config/index.ts +0 -7
  225. package/src/config/load.ts +0 -84
  226. package/src/config/minimal.ts +0 -58
  227. package/src/config/recommended.ts +0 -58
  228. package/src/config/rules.ts +0 -46
  229. package/src/config/types.ts +0 -168
  230. package/src/config/utils.ts +0 -208
  231. package/src/decorators/__tests__/remove-x-internal.test.ts +0 -316
  232. package/src/decorators/common/info-description-override.ts +0 -24
  233. package/src/decorators/common/operation-description-override.ts +0 -30
  234. package/src/decorators/common/registry-dependencies.ts +0 -25
  235. package/src/decorators/common/remove-x-internal.ts +0 -59
  236. package/src/decorators/common/tag-description-override.ts +0 -25
  237. package/src/decorators/oas2/index.ts +0 -14
  238. package/src/decorators/oas3/index.ts +0 -14
  239. package/src/format/codeframes.ts +0 -210
  240. package/src/format/format.ts +0 -339
  241. package/src/index.ts +0 -68
  242. package/src/js-yaml/index.ts +0 -18
  243. package/src/lint.ts +0 -125
  244. package/src/oas-types.ts +0 -62
  245. package/src/redocly/__tests__/redocly-client.test.ts +0 -140
  246. package/src/redocly/index.ts +0 -182
  247. package/src/redocly/redocly-client-types.ts +0 -10
  248. package/src/redocly/registry-api-types.ts +0 -32
  249. package/src/redocly/registry-api.ts +0 -134
  250. package/src/ref-utils.ts +0 -80
  251. package/src/resolve.ts +0 -378
  252. package/src/rules/__tests__/fixtures/invalid-yaml.yaml +0 -1
  253. package/src/rules/__tests__/fixtures/ref.yaml +0 -1
  254. package/src/rules/__tests__/no-unresolved-refs.test.ts +0 -168
  255. package/src/rules/ajv.ts +0 -103
  256. package/src/rules/common/__tests__/info-description.test.ts +0 -102
  257. package/src/rules/common/__tests__/info-license.test.ts +0 -62
  258. package/src/rules/common/__tests__/license-url.test.ts +0 -63
  259. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +0 -96
  260. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +0 -209
  261. package/src/rules/common/__tests__/no-identical-paths.test.ts +0 -58
  262. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +0 -85
  263. package/src/rules/common/__tests__/operation-2xx-response.test.ts +0 -91
  264. package/src/rules/common/__tests__/operation-4xx-response.test.ts +0 -107
  265. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +0 -76
  266. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +0 -45
  267. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +0 -167
  268. package/src/rules/common/__tests__/operation-security-defined.test.ts +0 -69
  269. package/src/rules/common/__tests__/operation-singular-tag.test.ts +0 -72
  270. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +0 -95
  271. package/src/rules/common/__tests__/path-not-include-query.test.ts +0 -64
  272. package/src/rules/common/__tests__/path-params-defined.test.ts +0 -133
  273. package/src/rules/common/__tests__/paths-kebab-case.test.ts +0 -108
  274. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +0 -207
  275. package/src/rules/common/__tests__/spec.test.ts +0 -62
  276. package/src/rules/common/__tests__/tag-description.test.ts +0 -65
  277. package/src/rules/common/__tests__/tags-alphabetical.test.ts +0 -64
  278. package/src/rules/common/assertions/__tests__/asserts.test.ts +0 -231
  279. package/src/rules/common/assertions/__tests__/index.test.ts +0 -65
  280. package/src/rules/common/assertions/__tests__/utils.test.ts +0 -89
  281. package/src/rules/common/assertions/asserts.ts +0 -137
  282. package/src/rules/common/assertions/index.ts +0 -75
  283. package/src/rules/common/assertions/utils.ts +0 -167
  284. package/src/rules/common/info-contact.ts +0 -15
  285. package/src/rules/common/info-description.ts +0 -10
  286. package/src/rules/common/info-license-url.ts +0 -15
  287. package/src/rules/common/license-url.ts +0 -10
  288. package/src/rules/common/no-ambiguous-paths.ts +0 -50
  289. package/src/rules/common/no-enum-type-mismatch.ts +0 -49
  290. package/src/rules/common/no-http-verbs-in-paths.ts +0 -36
  291. package/src/rules/common/no-identical-paths.ts +0 -24
  292. package/src/rules/common/no-invalid-parameter-examples.ts +0 -36
  293. package/src/rules/common/no-invalid-schema-examples.ts +0 -27
  294. package/src/rules/common/no-path-trailing-slash.ts +0 -15
  295. package/src/rules/common/operation-2xx-response.ts +0 -16
  296. package/src/rules/common/operation-4xx-response.ts +0 -17
  297. package/src/rules/common/operation-description.ts +0 -13
  298. package/src/rules/common/operation-operationId-unique.ts +0 -21
  299. package/src/rules/common/operation-operationId-url-safe.ts +0 -19
  300. package/src/rules/common/operation-operationId.ts +0 -17
  301. package/src/rules/common/operation-parameters-unique.ts +0 -48
  302. package/src/rules/common/operation-security-defined.ts +0 -45
  303. package/src/rules/common/operation-singular-tag.ts +0 -17
  304. package/src/rules/common/operation-summary.ts +0 -13
  305. package/src/rules/common/operation-tag-defined.ts +0 -26
  306. package/src/rules/common/parameter-description.ts +0 -22
  307. package/src/rules/common/path-declaration-must-exist.ts +0 -15
  308. package/src/rules/common/path-excludes-patterns.ts +0 -23
  309. package/src/rules/common/path-http-verbs-order.ts +0 -30
  310. package/src/rules/common/path-not-include-query.ts +0 -17
  311. package/src/rules/common/path-params-defined.ts +0 -58
  312. package/src/rules/common/path-segment-plural.ts +0 -31
  313. package/src/rules/common/paths-kebab-case.ts +0 -16
  314. package/src/rules/common/response-contains-header.ts +0 -30
  315. package/src/rules/common/scalar-property-missing-example.ts +0 -55
  316. package/src/rules/common/spec.ts +0 -143
  317. package/src/rules/common/tag-description.ts +0 -10
  318. package/src/rules/common/tags-alphabetical.ts +0 -20
  319. package/src/rules/no-unresolved-refs.ts +0 -51
  320. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +0 -110
  321. package/src/rules/oas2/__tests__/response-contains-header.test.ts +0 -174
  322. package/src/rules/oas2/__tests__/response-contains-property.test.ts +0 -155
  323. package/src/rules/oas2/__tests__/spec/fixtures/description.md +0 -1
  324. package/src/rules/oas2/__tests__/spec/info.test.ts +0 -355
  325. package/src/rules/oas2/__tests__/spec/operation.test.ts +0 -123
  326. package/src/rules/oas2/__tests__/spec/paths.test.ts +0 -245
  327. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +0 -31
  328. package/src/rules/oas2/__tests__/spec/utils.ts +0 -32
  329. package/src/rules/oas2/boolean-parameter-prefixes.ts +0 -26
  330. package/src/rules/oas2/index.ts +0 -89
  331. package/src/rules/oas2/remove-unused-components.ts +0 -76
  332. package/src/rules/oas2/request-mime-type.ts +0 -17
  333. package/src/rules/oas2/response-contains-property.ts +0 -36
  334. package/src/rules/oas2/response-mime-type.ts +0 -17
  335. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +0 -111
  336. package/src/rules/oas3/__tests__/fixtures/common.yaml +0 -11
  337. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +0 -205
  338. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +0 -65
  339. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +0 -392
  340. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +0 -60
  341. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +0 -79
  342. package/src/rules/oas3/__tests__/no-unused-components.test.ts +0 -131
  343. package/src/rules/oas3/__tests__/response-contains-header.test.ts +0 -273
  344. package/src/rules/oas3/__tests__/response-contains-property.test.ts +0 -403
  345. package/src/rules/oas3/__tests__/spec/callbacks.test.ts +0 -41
  346. package/src/rules/oas3/__tests__/spec/fixtures/description.md +0 -1
  347. package/src/rules/oas3/__tests__/spec/info.test.ts +0 -391
  348. package/src/rules/oas3/__tests__/spec/operation.test.ts +0 -253
  349. package/src/rules/oas3/__tests__/spec/paths.test.ts +0 -284
  350. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +0 -77
  351. package/src/rules/oas3/__tests__/spec/servers.test.ts +0 -499
  352. package/src/rules/oas3/__tests__/spec/spec.test.ts +0 -288
  353. package/src/rules/oas3/__tests__/spec/utils.ts +0 -32
  354. package/src/rules/oas3/boolean-parameter-prefixes.ts +0 -28
  355. package/src/rules/oas3/index.ts +0 -105
  356. package/src/rules/oas3/no-empty-servers.ts +0 -22
  357. package/src/rules/oas3/no-example-value-and-externalValue.ts +0 -14
  358. package/src/rules/oas3/no-invalid-media-type-examples.ts +0 -41
  359. package/src/rules/oas3/no-server-example.com.ts +0 -14
  360. package/src/rules/oas3/no-server-trailing-slash.ts +0 -15
  361. package/src/rules/oas3/no-servers-empty-enum.ts +0 -67
  362. package/src/rules/oas3/no-undefined-server-variable.ts +0 -30
  363. package/src/rules/oas3/no-unused-components.ts +0 -75
  364. package/src/rules/oas3/remove-unused-components.ts +0 -84
  365. package/src/rules/oas3/request-mime-type.ts +0 -31
  366. package/src/rules/oas3/response-contains-property.ts +0 -38
  367. package/src/rules/oas3/response-mime-type.ts +0 -31
  368. package/src/rules/other/stats.ts +0 -44
  369. package/src/rules/utils.ts +0 -123
  370. package/src/types/index.ts +0 -138
  371. package/src/types/oas2.ts +0 -397
  372. package/src/types/oas3.ts +0 -515
  373. package/src/types/oas3_1.ts +0 -253
  374. package/src/types/redocly-yaml.ts +0 -647
  375. package/src/typings/common.ts +0 -9
  376. package/src/typings/openapi.ts +0 -298
  377. package/src/typings/swagger.ts +0 -236
  378. package/src/utils.ts +0 -193
  379. package/src/visitors.ts +0 -448
  380. package/src/walk.ts +0 -416
  381. package/tsconfig.json +0 -8
  382. package/tsconfig.tsbuildinfo +0 -1
@@ -1,1485 +0,0 @@
1
- import outdent from 'outdent';
2
- import each from 'jest-each';
3
- import * as path from 'path';
4
-
5
- import { lintDocument } from '../lint';
6
-
7
- import { parseYamlToDocument, replaceSourceWithRef, makeConfigForRuleset } from '../../__tests__/utils';
8
- import { BaseResolver, Document } from '../resolve';
9
- import { listOf } from '../types';
10
- import { Oas3RuleSet } from '../oas-types';
11
-
12
- describe('walk order', () => {
13
- it('should run visitors', async () => {
14
- const visitors = {
15
- DefinitionRoot: {
16
- enter: jest.fn(),
17
- leave: jest.fn(),
18
- },
19
- Info: {
20
- enter: jest.fn(),
21
- leave: jest.fn(),
22
- },
23
- Contact: {
24
- enter: jest.fn(),
25
- leave: jest.fn(),
26
- },
27
- License: {
28
- enter: jest.fn(),
29
- leave: jest.fn(),
30
- },
31
- };
32
-
33
- const testRuleSet: Oas3RuleSet = {
34
- test: jest.fn(() => {
35
- return visitors;
36
- }),
37
- };
38
-
39
- const document = parseYamlToDocument(
40
- outdent`
41
- openapi: 3.0.0
42
- info:
43
- contact: {}
44
- license: {}
45
- `,
46
- '',
47
- );
48
-
49
- await lintDocument({
50
- externalRefResolver: new BaseResolver(),
51
- document,
52
- config: makeConfigForRuleset(testRuleSet),
53
- });
54
-
55
- expect(testRuleSet.test).toBeCalledTimes(1);
56
- for (const fns of Object.values(visitors)) {
57
- expect(fns.enter).toBeCalled();
58
- expect(fns.leave).toBeCalled();
59
- }
60
- });
61
-
62
- it('should run nested visitors correctly', async () => {
63
- const calls: string[] = [];
64
-
65
- const testRuleSet: Oas3RuleSet = {
66
- test: jest.fn(() => {
67
- return {
68
- Operation: {
69
- enter: jest.fn((op) => calls.push(`enter operation: ${op.operationId}`)),
70
- leave: jest.fn((op) => calls.push(`leave operation: ${op.operationId}`)),
71
- Parameter: {
72
- enter: jest.fn((param, _ctx, parents) =>
73
- calls.push(
74
- `enter operation ${parents.Operation.operationId} > param ${param.name}`,
75
- ),
76
- ),
77
- leave: jest.fn((param, _ctx, parents) =>
78
- calls.push(
79
- `leave operation ${parents.Operation.operationId} > param ${param.name}`,
80
- ),
81
- ),
82
- },
83
- },
84
- Parameter: {
85
- enter: jest.fn((param) => calls.push(`enter param ${param.name}`)),
86
- leave: jest.fn((param) => calls.push(`leave param ${param.name}`)),
87
- },
88
- };
89
- }),
90
- };
91
-
92
- const document = parseYamlToDocument(
93
- outdent`
94
- openapi: 3.0.0
95
- info:
96
- contact: {}
97
- license: {}
98
- paths:
99
- /pet:
100
- parameters:
101
- - name: path-param
102
- get:
103
- operationId: get
104
- parameters:
105
- - name: get_a
106
- - name: get_b
107
- post:
108
- operationId: post
109
- parameters:
110
- - name: post_a
111
-
112
- `,
113
- '',
114
- );
115
-
116
- await lintDocument({
117
- externalRefResolver: new BaseResolver(),
118
- document,
119
- config: makeConfigForRuleset(testRuleSet),
120
- });
121
-
122
- expect(calls).toMatchInlineSnapshot(`
123
- Array [
124
- "enter param path-param",
125
- "leave param path-param",
126
- "enter operation: get",
127
- "enter operation get > param get_a",
128
- "enter param get_a",
129
- "leave param get_a",
130
- "leave operation get > param get_a",
131
- "enter operation get > param get_b",
132
- "enter param get_b",
133
- "leave param get_b",
134
- "leave operation get > param get_b",
135
- "leave operation: get",
136
- "enter operation: post",
137
- "enter operation post > param post_a",
138
- "enter param post_a",
139
- "leave param post_a",
140
- "leave operation post > param post_a",
141
- "leave operation: post",
142
- ]
143
- `);
144
- });
145
-
146
- it('should run nested visitors correctly oas2', async () => {
147
- const calls: string[] = [];
148
-
149
- const testRuleSet: Oas3RuleSet = {
150
- test: jest.fn(() => {
151
- return {
152
- Operation: {
153
- enter: jest.fn((op) => calls.push(`enter operation: ${op.operationId}`)),
154
- leave: jest.fn((op) => calls.push(`leave operation: ${op.operationId}`)),
155
- Parameter: {
156
- enter: jest.fn((param, _ctx, parents) =>
157
- calls.push(
158
- `enter operation ${parents.Operation.operationId} > param ${param.name}`,
159
- ),
160
- ),
161
- leave: jest.fn((param, _ctx, parents) =>
162
- calls.push(
163
- `leave operation ${parents.Operation.operationId} > param ${param.name}`,
164
- ),
165
- ),
166
- },
167
- },
168
- Parameter: {
169
- enter: jest.fn((param) => calls.push(`enter param ${param.name}`)),
170
- leave: jest.fn((param) => calls.push(`leave param ${param.name}`)),
171
- },
172
- };
173
- }),
174
- };
175
-
176
- const document = parseYamlToDocument(
177
- outdent`
178
- swagger: "2.0"
179
- info:
180
- contact: {}
181
- license: {}
182
- paths:
183
- /pet:
184
- parameters:
185
- - name: path-param
186
- get:
187
- operationId: get
188
- parameters:
189
- - name: get_a
190
- - name: get_b
191
- post:
192
- operationId: post
193
- parameters:
194
- - name: post_a
195
-
196
- `,
197
- '',
198
- );
199
-
200
- await lintDocument({
201
- externalRefResolver: new BaseResolver(),
202
- document,
203
- config: makeConfigForRuleset(testRuleSet, undefined, 'oas2'),
204
- });
205
-
206
- expect(calls).toMatchInlineSnapshot(`
207
- Array [
208
- "enter param path-param",
209
- "leave param path-param",
210
- "enter operation: get",
211
- "enter operation get > param get_a",
212
- "enter param get_a",
213
- "leave param get_a",
214
- "leave operation get > param get_a",
215
- "enter operation get > param get_b",
216
- "enter param get_b",
217
- "leave param get_b",
218
- "leave operation get > param get_b",
219
- "leave operation: get",
220
- "enter operation: post",
221
- "enter operation post > param post_a",
222
- "enter param post_a",
223
- "leave param post_a",
224
- "leave operation post > param post_a",
225
- "leave operation: post",
226
- ]
227
- `);
228
- });
229
-
230
- it('should resolve refs', async () => {
231
- const calls: string[] = [];
232
-
233
- const testRuleSet: Oas3RuleSet = {
234
- test: jest.fn(() => {
235
- return {
236
- Operation: {
237
- enter: jest.fn((op) => calls.push(`enter operation: ${op.operationId}`)),
238
- leave: jest.fn((op) => calls.push(`leave operation: ${op.operationId}`)),
239
- Parameter: {
240
- enter: jest.fn((param, _ctx, parents) =>
241
- calls.push(
242
- `enter operation ${parents.Operation.operationId} > param ${param.name}`,
243
- ),
244
- ),
245
- leave: jest.fn((param, _ctx, parents) =>
246
- calls.push(
247
- `leave operation ${parents.Operation.operationId} > param ${param.name}`,
248
- ),
249
- ),
250
- },
251
- },
252
- Parameter: {
253
- enter: jest.fn((param) => calls.push(`enter param ${param.name}`)),
254
- leave: jest.fn((param) => calls.push(`leave param ${param.name}`)),
255
- },
256
- };
257
- }),
258
- };
259
-
260
- const document = parseYamlToDocument(
261
- outdent`
262
- openapi: 3.0.0
263
- info:
264
- contact: {}
265
- license: {}
266
- paths:
267
- /pet:
268
- get:
269
- operationId: get
270
- parameters:
271
- - $ref: '#/components/parameters/shared_a'
272
- - name: get_b
273
- post:
274
- operationId: post
275
- parameters:
276
- - $ref: '#/components/parameters/shared_a'
277
- components:
278
- parameters:
279
- shared_a:
280
- name: shared-a
281
- `,
282
- '',
283
- );
284
-
285
- await lintDocument({
286
- externalRefResolver: new BaseResolver(),
287
- document,
288
- config: makeConfigForRuleset(testRuleSet),
289
- });
290
-
291
- expect(calls).toMatchInlineSnapshot(`
292
- Array [
293
- "enter operation: get",
294
- "enter operation get > param shared-a",
295
- "enter param shared-a",
296
- "leave param shared-a",
297
- "leave operation get > param shared-a",
298
- "enter operation get > param get_b",
299
- "enter param get_b",
300
- "leave param get_b",
301
- "leave operation get > param get_b",
302
- "leave operation: get",
303
- "enter operation: post",
304
- "enter operation post > param shared-a",
305
- "leave operation post > param shared-a",
306
- "leave operation: post",
307
- ]
308
- `);
309
- });
310
-
311
- it('should visit with context same refs with gaps in visitor simple', async () => {
312
- const calls: string[] = [];
313
-
314
- const testRuleSet: Oas3RuleSet = {
315
- test: jest.fn(() => {
316
- return {
317
- PathItem: {
318
- Parameter: {
319
- enter: jest.fn((param, _ctx, parents) =>
320
- calls.push(`enter path ${parents.PathItem.id} > param ${param.name}`),
321
- ),
322
- },
323
- },
324
- };
325
- }),
326
- };
327
-
328
- const document = parseYamlToDocument(
329
- outdent`
330
- openapi: 3.0.0
331
- paths:
332
- /pet:
333
- id: pet
334
- parameters:
335
- $ref: '#/components/fake_parameters_list'
336
- get:
337
- operationId: get
338
- parameters:
339
- - $ref: '#/components/parameters/shared_a'
340
- - name: get_b
341
- /dog:
342
- id: dog
343
- post:
344
- operationId: post
345
- parameters:
346
- - $ref: '#/components/parameters/shared_a'
347
- components:
348
- fake_parameters_list:
349
- - name: path-param
350
- parameters:
351
- shared_a:
352
- name: shared-a
353
- `,
354
- '',
355
- );
356
-
357
- await lintDocument({
358
- externalRefResolver: new BaseResolver(),
359
- document,
360
- config: makeConfigForRuleset(testRuleSet),
361
- });
362
-
363
- expect(calls).toMatchInlineSnapshot(`
364
- Array [
365
- "enter path pet > param path-param",
366
- "enter path pet > param shared-a",
367
- "enter path pet > param get_b",
368
- "enter path dog > param shared-a",
369
- ]
370
- `);
371
- });
372
-
373
- it('should correctly visit more specific visitor', async () => {
374
- const calls: string[] = [];
375
-
376
- const testRuleSet: Oas3RuleSet = {
377
- test: jest.fn(() => {
378
- return {
379
- PathItem: {
380
- Parameter: {
381
- enter: jest.fn((param, _ctx, parents) =>
382
- calls.push(`enter path ${parents.PathItem.id} > param ${param.name}`),
383
- ),
384
- },
385
- Operation: {
386
- Parameter: {
387
- enter: jest.fn((param, _ctx, parents) =>
388
- calls.push(
389
- `enter operation ${parents.Operation.operationId} > param ${param.name}`,
390
- ),
391
- ),
392
- },
393
- },
394
- },
395
- };
396
- }),
397
- };
398
-
399
- const document = parseYamlToDocument(
400
- outdent`
401
- openapi: 3.0.0
402
- paths:
403
- /pet:
404
- id: pet
405
- parameters:
406
- - name: path-param
407
- get:
408
- operationId: get
409
- parameters:
410
- - $ref: '#/components/parameters/shared_a'
411
- - name: get_b
412
- - name: get_c
413
- /dog:
414
- id: dog
415
- post:
416
- operationId: post
417
- parameters:
418
- - $ref: '#/components/parameters/shared_b'
419
- components:
420
- parameters:
421
- shared_a:
422
- name: shared-a
423
- shared_b:
424
- name: shared-b
425
- `,
426
- '',
427
- );
428
-
429
- await lintDocument({
430
- externalRefResolver: new BaseResolver(),
431
- document,
432
- config: makeConfigForRuleset(testRuleSet),
433
- });
434
-
435
- expect(calls).toMatchInlineSnapshot(`
436
- Array [
437
- "enter path pet > param path-param",
438
- "enter operation get > param shared-a",
439
- "enter operation get > param get_b",
440
- "enter operation get > param get_c",
441
- "enter operation post > param shared-b",
442
- ]
443
- `);
444
- });
445
-
446
- it('should visit with context same refs with gaps in visitor and nested rule', async () => {
447
- const calls: string[] = [];
448
-
449
- const testRuleSet: Oas3RuleSet = {
450
- test: jest.fn(() => {
451
- return {
452
- PathItem: {
453
- Parameter: {
454
- enter: jest.fn((param, _ctx, parents) =>
455
- calls.push(`enter path ${parents.PathItem.id} > param ${param.name}`),
456
- ),
457
- leave: jest.fn((param, _ctx, parents) =>
458
- calls.push(`leave path ${parents.PathItem.id} > param ${param.name}`),
459
- ),
460
- },
461
- Operation(op, _ctx, parents) {
462
- calls.push(`enter path ${parents.PathItem.id} > op ${op.operationId}`);
463
- },
464
- },
465
- };
466
- }),
467
- };
468
-
469
- const document = parseYamlToDocument(
470
- outdent`
471
- openapi: 3.0.0
472
- paths:
473
- /pet:
474
- id: pet
475
- parameters:
476
- - name: path-param
477
- get:
478
- operationId: get
479
- parameters:
480
- - $ref: '#/components/parameters/shared_a'
481
- - name: get_b
482
- /dog:
483
- id: dog
484
- post:
485
- operationId: post
486
- parameters:
487
- - $ref: '#/components/parameters/shared_a'
488
- components:
489
- parameters:
490
- shared_a:
491
- name: shared-a
492
- `,
493
- '',
494
- );
495
-
496
- await lintDocument({
497
- externalRefResolver: new BaseResolver(),
498
- document,
499
- config: makeConfigForRuleset(testRuleSet),
500
- });
501
-
502
- expect(calls).toMatchInlineSnapshot(`
503
- Array [
504
- "enter path pet > param path-param",
505
- "leave path pet > param path-param",
506
- "enter path pet > op get",
507
- "enter path pet > param shared-a",
508
- "leave path pet > param shared-a",
509
- "enter path pet > param get_b",
510
- "leave path pet > param get_b",
511
- "enter path dog > op post",
512
- "enter path dog > param shared-a",
513
- "leave path dog > param shared-a",
514
- ]
515
- `);
516
- });
517
-
518
- it('should visit and do not recurse for circular refs top-level', async () => {
519
- const calls: string[] = [];
520
-
521
- const testRuleSet: Oas3RuleSet = {
522
- test: jest.fn(() => {
523
- return {
524
- Schema: jest.fn((schema: any) => calls.push(`enter schema ${schema.id}`)),
525
- };
526
- }),
527
- };
528
-
529
- const document = parseYamlToDocument(
530
- outdent`
531
- openapi: 3.0.0
532
- paths:
533
- /pet:
534
- id: pet
535
- parameters:
536
- - name: path-param
537
- schema:
538
- $ref: "#/components/parameters/shared_a"
539
- components:
540
- parameters:
541
- shared_a:
542
- id: 'shared_a'
543
- allOf:
544
- - $ref: "#/components/parameters/shared_a"
545
- - id: 'nested'
546
- `,
547
- '',
548
- );
549
-
550
- await lintDocument({
551
- externalRefResolver: new BaseResolver(),
552
- document,
553
- config: makeConfigForRuleset(testRuleSet),
554
- });
555
-
556
- expect(calls).toMatchInlineSnapshot(`
557
- Array [
558
- "enter schema shared_a",
559
- "enter schema nested",
560
- ]
561
- `);
562
- });
563
-
564
- it('should visit and do not recurse for circular refs with context', async () => {
565
- const calls: string[] = [];
566
-
567
- const testRuleSet: Oas3RuleSet = {
568
- test: jest.fn(() => {
569
- return {
570
- Parameter: {
571
- Schema: jest.fn((schema: any, _ctx, parents) =>
572
- calls.push(`enter param ${parents.Parameter.name} > schema ${schema.id}`),
573
- ),
574
- },
575
- };
576
- }),
577
- };
578
-
579
- const document = parseYamlToDocument(
580
- outdent`
581
- openapi: 3.0.0
582
- paths:
583
- /pet:
584
- id: pet
585
- parameters:
586
- - name: a
587
- schema:
588
- $ref: "#/components/parameters/shared_a"
589
- - name: b
590
- schema:
591
- $ref: "#/components/parameters/shared_a"
592
- components:
593
- parameters:
594
- shared_a:
595
- id: 'shared_a'
596
- properties:
597
- a:
598
- id: a
599
- allOf:
600
- - $ref: "#/components/parameters/shared_a"
601
- - id: 'nested'
602
- `,
603
- '',
604
- );
605
-
606
- await lintDocument({
607
- externalRefResolver: new BaseResolver(),
608
- document,
609
- config: makeConfigForRuleset(testRuleSet),
610
- });
611
-
612
- expect(calls).toMatchInlineSnapshot(`
613
- Array [
614
- "enter param a > schema shared_a",
615
- "enter param b > schema shared_a",
616
- ]
617
- `);
618
- });
619
-
620
- it('should correctly skip top level', async () => {
621
- const calls: string[] = [];
622
-
623
- const testRuleSet: Oas3RuleSet = {
624
- test: jest.fn(() => {
625
- return {
626
- Operation: {
627
- skip: (op) => op.operationId === 'put',
628
- enter: jest.fn((op) => calls.push(`enter operation ${op.operationId}`)),
629
- leave: jest.fn((op) => calls.push(`leave operation ${op.operationId}`)),
630
- },
631
- };
632
- }),
633
- };
634
-
635
- const document = parseYamlToDocument(
636
- outdent`
637
- openapi: 3.0.0
638
- paths:
639
- /pet:
640
- get:
641
- operationId: get
642
- put:
643
- operationId: put
644
- `,
645
- '',
646
- );
647
-
648
- await lintDocument({
649
- externalRefResolver: new BaseResolver(),
650
- document,
651
- config: makeConfigForRuleset(testRuleSet),
652
- });
653
-
654
- expect(calls).toMatchInlineSnapshot(`
655
- Array [
656
- "enter operation get",
657
- "leave operation get",
658
- ]
659
- `);
660
- });
661
-
662
- it('should correctly skip nested levels', async () => {
663
- const calls: string[] = [];
664
-
665
- const testRuleSet: Oas3RuleSet = {
666
- test: jest.fn(() => {
667
- return {
668
- Operation: {
669
- skip: (op) => op.operationId === 'put',
670
- Parameter: jest.fn((param, _ctx, parents) =>
671
- calls.push(`enter operation ${parents.Operation.operationId} > param ${param.name}`),
672
- ),
673
- },
674
- };
675
- }),
676
- };
677
-
678
- const document = parseYamlToDocument(
679
- outdent`
680
- openapi: 3.0.0
681
- paths:
682
- /pet:
683
- get:
684
- operationId: get
685
- parameters:
686
- - $ref: '#/components/parameters/shared_a'
687
- - name: get_b
688
- - name: get_c
689
- put:
690
- operationId: put
691
- parameters:
692
- - $ref: '#/components/parameters/shared_a'
693
- - name: get_b
694
- - name: get_c
695
- components:
696
- parameters:
697
- shared_a:
698
- name: shared-a
699
- `,
700
- '',
701
- );
702
-
703
- await lintDocument({
704
- externalRefResolver: new BaseResolver(),
705
- document,
706
- config: makeConfigForRuleset(testRuleSet),
707
- });
708
-
709
- expect(calls).toMatchInlineSnapshot(`
710
- Array [
711
- "enter operation get > param shared-a",
712
- "enter operation get > param get_b",
713
- "enter operation get > param get_c",
714
- ]
715
- `);
716
- });
717
-
718
- it('should correctly visit more specific visitor with skips', async () => {
719
- const calls: string[] = [];
720
-
721
- const testRuleSet: Oas3RuleSet = {
722
- test: jest.fn(() => {
723
- return {
724
- PathItem: {
725
- Parameter: {
726
- enter: jest.fn((param, _ctx, parents) =>
727
- calls.push(`enter path ${parents.PathItem.id} > param ${param.name}`),
728
- ),
729
- leave: jest.fn((param, _ctx, parents) =>
730
- calls.push(`leave path ${parents.PathItem.id} > param ${param.name}`),
731
- ),
732
- },
733
- Operation: {
734
- skip: (op) => op.operationId === 'put',
735
- Parameter: {
736
- enter: jest.fn((param, _ctx, parents) =>
737
- calls.push(
738
- `enter operation ${parents.Operation.operationId} > param ${param.name}`,
739
- ),
740
- ),
741
- leave: jest.fn((param, _ctx, parents) =>
742
- calls.push(
743
- `leave operation ${parents.Operation.operationId} > param ${param.name}`,
744
- ),
745
- ),
746
- },
747
- },
748
- },
749
- };
750
- }),
751
- };
752
-
753
- const document = parseYamlToDocument(
754
- outdent`
755
- openapi: 3.0.0
756
- paths:
757
- /pet:
758
- id: pet
759
- parameters:
760
- - name: path-param
761
- get:
762
- operationId: get
763
- parameters:
764
- - $ref: '#/components/parameters/shared_a'
765
- - name: get_b
766
- - name: get_c
767
- put:
768
- operationId: put
769
- parameters:
770
- - $ref: '#/components/parameters/shared_a'
771
- - name: get_b
772
- - name: get_c
773
- /dog:
774
- id: dog
775
- post:
776
- operationId: post
777
- parameters:
778
- - $ref: '#/components/parameters/shared_b'
779
- components:
780
- parameters:
781
- shared_a:
782
- name: shared-a
783
- shared_b:
784
- name: shared-b
785
- `,
786
- '',
787
- );
788
-
789
- await lintDocument({
790
- externalRefResolver: new BaseResolver(),
791
- document,
792
- config: makeConfigForRuleset(testRuleSet),
793
- });
794
-
795
- expect(calls).toMatchInlineSnapshot(`
796
- Array [
797
- "enter path pet > param path-param",
798
- "leave path pet > param path-param",
799
- "enter operation get > param shared-a",
800
- "leave operation get > param shared-a",
801
- "enter operation get > param get_b",
802
- "leave operation get > param get_b",
803
- "enter operation get > param get_c",
804
- "leave operation get > param get_c",
805
- "enter operation post > param shared-b",
806
- "leave operation post > param shared-b",
807
- ]
808
- `);
809
- });
810
-
811
- it('should correctly visit with nested rules', async () => {
812
- const calls: string[] = [];
813
-
814
- const testRuleSet: Oas3RuleSet = {
815
- test: jest.fn(() => {
816
- return {
817
- Schema: {
818
- Schema: {
819
- enter: jest.fn((schema: any, _ctx, parents) =>
820
- calls.push(`enter nested schema ${parents.Schema.id} > ${schema.id}`),
821
- ),
822
- leave: jest.fn((schema: any, _ctx, parents) =>
823
- calls.push(`leave nested schema ${parents.Schema.id} > ${schema.id}`),
824
- ),
825
- },
826
- },
827
- };
828
- }),
829
- };
830
-
831
- const document = parseYamlToDocument(
832
- outdent`
833
- openapi: 3.0.0
834
- paths:
835
- /pet:
836
- get:
837
- requestBody:
838
- content:
839
- application/json:
840
- schema:
841
- id: inline-top
842
- type: object
843
- properties:
844
- b:
845
- $ref: "#/components/schemas/b"
846
- a:
847
- type: object
848
- id: inline-nested-2
849
- properties:
850
- a:
851
- id: inline-nested-nested-2
852
- components:
853
- schemas:
854
- b:
855
- id: inline-top
856
- type: object
857
- properties:
858
- a:
859
- type: object
860
- id: inline-nested
861
- properties:
862
- a:
863
- id: inline-nested-nested
864
- `,
865
- 'foobar.yaml',
866
- );
867
-
868
- await lintDocument({
869
- externalRefResolver: new BaseResolver(),
870
- document,
871
- config: makeConfigForRuleset(testRuleSet),
872
- });
873
-
874
- expect(calls).toMatchInlineSnapshot(`
875
- Array [
876
- "enter nested schema inline-top > inline-top",
877
- "enter nested schema inline-top > inline-nested",
878
- "enter nested schema inline-nested > inline-nested-nested",
879
- "leave nested schema inline-nested > inline-nested-nested",
880
- "leave nested schema inline-top > inline-nested",
881
- "leave nested schema inline-top > inline-top",
882
- "enter nested schema inline-top > inline-nested-2",
883
- "enter nested schema inline-nested-2 > inline-nested-nested-2",
884
- "leave nested schema inline-nested-2 > inline-nested-nested-2",
885
- "leave nested schema inline-top > inline-nested-2",
886
- ]
887
- `);
888
- });
889
-
890
- it('should correctly visit refs', async () => {
891
- const calls: string[] = [];
892
-
893
- const testRuleSet: Oas3RuleSet = {
894
- test: jest.fn(() => {
895
- return {
896
- ref(node, _, { node: target }) {
897
- calls.push(`enter $ref ${node.$ref} with target ${target?.name}`);
898
- },
899
- };
900
- }),
901
- };
902
-
903
- const document = parseYamlToDocument(
904
- outdent`
905
- openapi: 3.0.0
906
- paths:
907
- /pet:
908
- id: pet
909
- parameters:
910
- - name: path-param
911
- get:
912
- operationId: get
913
- parameters:
914
- - $ref: '#/components/parameters/shared_b'
915
- put:
916
- operationId: put
917
- parameters:
918
- - $ref: '#/components/parameters/shared_a'
919
- /dog:
920
- id: dog
921
- post:
922
- operationId: post
923
- schema:
924
- example:
925
- $ref: 123
926
- parameters:
927
- - $ref: '#/components/parameters/shared_a'
928
- components:
929
- parameters:
930
- shared_a:
931
- name: shared-a
932
- shared_b:
933
- name: shared-b
934
- schema:
935
- $ref: '#/components/parameters/shared_b'
936
- `,
937
- 'foobar.yaml',
938
- );
939
-
940
- await lintDocument({
941
- externalRefResolver: new BaseResolver(),
942
- document,
943
- config: makeConfigForRuleset(testRuleSet),
944
- });
945
-
946
- expect(calls).toMatchInlineSnapshot(`
947
- Array [
948
- "enter $ref #/components/parameters/shared_b with target shared-b",
949
- "enter $ref #/components/parameters/shared_b with target shared-b",
950
- "enter $ref #/components/parameters/shared_a with target shared-a",
951
- "enter $ref #/components/parameters/shared_a with target shared-a",
952
- ]
953
- `);
954
- });
955
-
956
- it('should correctly visit refs', async () => {
957
- const calls: string[] = [];
958
-
959
- const testRuleSet: Oas3RuleSet = {
960
- test: jest.fn(() => {
961
- return {
962
- NamedSchemas: {
963
- Schema(node, { key }) {
964
- calls.push(`enter schema ${key}: ${node.type}`);
965
- },
966
- },
967
- };
968
- }),
969
- };
970
-
971
- const document = parseYamlToDocument(
972
- outdent`
973
- openapi: 3.0.0
974
- components:
975
- schemas:
976
- a:
977
- type: string
978
- b:
979
- type: number
980
- `,
981
- 'foobar.yaml',
982
- );
983
-
984
- await lintDocument({
985
- externalRefResolver: new BaseResolver(),
986
- document,
987
- config: makeConfigForRuleset(testRuleSet),
988
- });
989
-
990
- expect(calls).toMatchInlineSnapshot(`
991
- Array [
992
- "enter schema a: string",
993
- "enter schema b: number",
994
- ]
995
- `);
996
- });
997
-
998
- it('should correctly visit any visitor', async () => {
999
- const calls: string[] = [];
1000
-
1001
- const testRuleSet: Oas3RuleSet = {
1002
- test: jest.fn(() => {
1003
- return {
1004
- ref: {
1005
- enter(ref: any) {
1006
- calls.push(`enter ref ${ref.$ref}`);
1007
- },
1008
- leave(ref) {
1009
- calls.push(`leave ref ${ref.$ref}`);
1010
- },
1011
- },
1012
- any: {
1013
- enter(_node: any, { type }) {
1014
- calls.push(`enter ${type.name}`);
1015
- },
1016
- leave(_node, { type }) {
1017
- calls.push(`leave ${type.name}`);
1018
- },
1019
- },
1020
- };
1021
- }),
1022
- };
1023
-
1024
- const document = parseYamlToDocument(
1025
- outdent`
1026
- openapi: 3.0.0
1027
- paths:
1028
- /pet:
1029
- id: pet
1030
- parameters:
1031
- - name: path-param
1032
- get:
1033
- operationId: get
1034
- parameters:
1035
- - $ref: '#/components/parameters/shared_a'
1036
- - name: get_b
1037
- - name: get_c
1038
- components:
1039
- parameters:
1040
- shared_a:
1041
- name: shared-a
1042
- schemas:
1043
- a:
1044
- type: object
1045
- `,
1046
- '',
1047
- );
1048
-
1049
- await lintDocument({
1050
- externalRefResolver: new BaseResolver(),
1051
- document,
1052
- config: makeConfigForRuleset(testRuleSet),
1053
- });
1054
-
1055
- expect(calls).toMatchInlineSnapshot(`
1056
- Array [
1057
- "enter DefinitionRoot",
1058
- "enter PathMap",
1059
- "enter PathItem",
1060
- "enter ParameterList",
1061
- "enter Parameter",
1062
- "leave Parameter",
1063
- "leave ParameterList",
1064
- "enter Operation",
1065
- "enter ParameterList",
1066
- "enter ref #/components/parameters/shared_a",
1067
- "enter Parameter",
1068
- "leave Parameter",
1069
- "leave ref #/components/parameters/shared_a",
1070
- "enter Parameter",
1071
- "leave Parameter",
1072
- "enter Parameter",
1073
- "leave Parameter",
1074
- "leave ParameterList",
1075
- "leave Operation",
1076
- "leave PathItem",
1077
- "leave PathMap",
1078
- "enter Components",
1079
- "enter NamedParameters",
1080
- "leave NamedParameters",
1081
- "enter NamedSchemas",
1082
- "enter Schema",
1083
- "leave Schema",
1084
- "leave NamedSchemas",
1085
- "leave Components",
1086
- "leave DefinitionRoot",
1087
- ]
1088
- `);
1089
- });
1090
- });
1091
-
1092
- describe('context.report', () => {
1093
- it('should report errors correctly', async () => {
1094
- const testRuleSet: Oas3RuleSet = {
1095
- test: jest.fn(() => {
1096
- return {
1097
- Parameter: {
1098
- enter: jest.fn((param, ctx) => {
1099
- if (param.name.indexOf('_') > -1) {
1100
- ctx.report({
1101
- message: `Parameter name shouldn't contain '_: ${param.name}`,
1102
- });
1103
- }
1104
- }),
1105
- },
1106
- };
1107
- }),
1108
- };
1109
-
1110
- const document = parseYamlToDocument(
1111
- outdent`
1112
- openapi: 3.0.0
1113
- info:
1114
- contact: {}
1115
- license: {}
1116
- paths:
1117
- /pet:
1118
- parameters:
1119
- - name: path-param
1120
- get:
1121
- operationId: get
1122
- parameters:
1123
- - name: get_a
1124
- - name: get_b
1125
- post:
1126
- operationId: post
1127
- parameters:
1128
- - $ref: '#/components/parameters/shared_a'
1129
- components:
1130
- parameters:
1131
- shared_a:
1132
- name: shared_a
1133
- `,
1134
- 'foobar.yaml',
1135
- );
1136
-
1137
- const results = await lintDocument({
1138
- externalRefResolver: new BaseResolver(),
1139
- document,
1140
- config: makeConfigForRuleset(testRuleSet),
1141
- });
1142
-
1143
- expect(results).toHaveLength(3);
1144
- expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
1145
- Array [
1146
- Object {
1147
- "location": Array [
1148
- Object {
1149
- "pointer": "#/paths/~1pet/get/parameters/0",
1150
- "reportOnKey": false,
1151
- "source": "foobar.yaml",
1152
- },
1153
- ],
1154
- "message": "Parameter name shouldn't contain '_: get_a",
1155
- "ruleId": "test/test",
1156
- "severity": "error",
1157
- "suggest": Array [],
1158
- },
1159
- Object {
1160
- "location": Array [
1161
- Object {
1162
- "pointer": "#/paths/~1pet/get/parameters/1",
1163
- "reportOnKey": false,
1164
- "source": "foobar.yaml",
1165
- },
1166
- ],
1167
- "message": "Parameter name shouldn't contain '_: get_b",
1168
- "ruleId": "test/test",
1169
- "severity": "error",
1170
- "suggest": Array [],
1171
- },
1172
- Object {
1173
- "location": Array [
1174
- Object {
1175
- "pointer": "#/components/parameters/shared_a",
1176
- "reportOnKey": false,
1177
- "source": "foobar.yaml",
1178
- },
1179
- ],
1180
- "message": "Parameter name shouldn't contain '_: shared_a",
1181
- "ruleId": "test/test",
1182
- "severity": "error",
1183
- "suggest": Array [],
1184
- },
1185
- ]
1186
- `);
1187
- });
1188
-
1189
- it('should report errors correctly', async () => {
1190
- const testRuleSet: Oas3RuleSet = {
1191
- test: jest.fn(() => {
1192
- return {
1193
- Parameter: {
1194
- enter: jest.fn((param, ctx) => {
1195
- if (param.name.indexOf('_') > -1) {
1196
- ctx.report({
1197
- message: `Parameter name shouldn't contain '_: ${param.name}`,
1198
- });
1199
- }
1200
- }),
1201
- },
1202
- };
1203
- }),
1204
- };
1205
-
1206
- const cwd = path.join(__dirname, 'fixtures/refs');
1207
- const externalRefResolver = new BaseResolver();
1208
- const document = (await externalRefResolver.resolveDocument(
1209
- null,
1210
- `${cwd}/openapi-with-external-refs.yaml`,
1211
- )) as Document;
1212
-
1213
- if (document === null) {
1214
- throw 'Should never happen';
1215
- }
1216
-
1217
- const results = await lintDocument({
1218
- externalRefResolver: new BaseResolver(),
1219
- document,
1220
- config: makeConfigForRuleset(testRuleSet),
1221
- });
1222
-
1223
- expect(results).toHaveLength(4);
1224
- expect(replaceSourceWithRef(results, cwd)).toMatchInlineSnapshot(`
1225
- Array [
1226
- Object {
1227
- "location": Array [
1228
- Object {
1229
- "pointer": "#/components/parameters/path-param",
1230
- "reportOnKey": false,
1231
- "source": "openapi-with-external-refs.yaml",
1232
- },
1233
- ],
1234
- "message": "Parameter name shouldn't contain '_: path_param",
1235
- "ruleId": "test/test",
1236
- "severity": "error",
1237
- "suggest": Array [],
1238
- },
1239
- Object {
1240
- "location": Array [
1241
- Object {
1242
- "pointer": "#/components/parameters/param-a",
1243
- "reportOnKey": false,
1244
- "source": "openapi-with-external-refs.yaml",
1245
- },
1246
- ],
1247
- "message": "Parameter name shouldn't contain '_: param_a",
1248
- "ruleId": "test/test",
1249
- "severity": "error",
1250
- "suggest": Array [],
1251
- },
1252
- Object {
1253
- "location": Array [
1254
- Object {
1255
- "pointer": "#/",
1256
- "reportOnKey": false,
1257
- "source": "param-c.yaml",
1258
- },
1259
- ],
1260
- "message": "Parameter name shouldn't contain '_: param_c",
1261
- "ruleId": "test/test",
1262
- "severity": "error",
1263
- "suggest": Array [],
1264
- },
1265
- Object {
1266
- "location": Array [
1267
- Object {
1268
- "pointer": "#/",
1269
- "reportOnKey": false,
1270
- "source": "param-b.yaml",
1271
- },
1272
- ],
1273
- "message": "Parameter name shouldn't contain '_: param_b",
1274
- "ruleId": "test/test",
1275
- "severity": "error",
1276
- "suggest": Array [],
1277
- },
1278
- ]
1279
- `);
1280
- });
1281
- });
1282
-
1283
- describe('context.resolve', () => {
1284
- it('should resolve refs correctly', async () => {
1285
- const testRuleSet: Oas3RuleSet = {
1286
- test: jest.fn(() => {
1287
- return {
1288
- Schema: jest.fn((schema, { resolve }) => {
1289
- if (schema.properties) {
1290
- expect(schema.properties.a.$ref).toBeDefined();
1291
- const { location, node } = resolve(schema.properties.a);
1292
- expect(node).toMatchInlineSnapshot(`
1293
- Object {
1294
- "type": "string",
1295
- }
1296
- `);
1297
- expect(location?.pointer).toEqual('#/components/schemas/b');
1298
- expect(location?.source).toStrictEqual(document.source);
1299
- }
1300
- }),
1301
- };
1302
- }),
1303
- };
1304
-
1305
- const document = parseYamlToDocument(
1306
- outdent`
1307
- openapi: 3.0.0
1308
- info:
1309
- contact: {}
1310
- license: {}
1311
- paths: {}
1312
- components:
1313
- schemas:
1314
- b:
1315
- type: string
1316
- a:
1317
- type: object
1318
- properties:
1319
- a:
1320
- $ref: '#/components/schemas/b'
1321
- `,
1322
- 'foobar.yaml',
1323
- );
1324
-
1325
- await lintDocument({
1326
- externalRefResolver: new BaseResolver(),
1327
- document,
1328
- config: makeConfigForRuleset(testRuleSet),
1329
- });
1330
- });
1331
- });
1332
-
1333
- describe('type extensions', () => {
1334
- each([
1335
- ['3.0.0', 'oas3_0'],
1336
- ['3.1.0', 'oas3_1'],
1337
- ]).it('should correctly visit OpenAPI %s extended types', async (openapi, oas) => {
1338
- const calls: string[] = [];
1339
-
1340
- const testRuleSet: Oas3RuleSet = {
1341
- test: jest.fn(() => {
1342
- return {
1343
- any: {
1344
- enter(_node: any, { type }) {
1345
- calls.push(`enter ${type.name}`);
1346
- },
1347
- leave(_node, { type }) {
1348
- calls.push(`leave ${type.name}`);
1349
- },
1350
- },
1351
- XWebHooks: {
1352
- enter(hook: any) {
1353
- calls.push(`enter hook ${hook.name}`);
1354
- },
1355
- leave(hook) {
1356
- calls.push(`leave hook ${hook.name}`);
1357
- },
1358
- },
1359
- };
1360
- }),
1361
- };
1362
-
1363
- const document = parseYamlToDocument(
1364
- outdent`
1365
- openapi: ${openapi}
1366
- x-webhooks:
1367
- name: test
1368
- parameters:
1369
- - name: a
1370
- `,
1371
- 'foobar.yaml',
1372
- );
1373
-
1374
- await lintDocument({
1375
- externalRefResolver: new BaseResolver(),
1376
- document,
1377
- config: makeConfigForRuleset(testRuleSet, {
1378
- typeExtension: {
1379
- oas3(types, version) {
1380
- expect(version).toEqual(oas);
1381
-
1382
- return {
1383
- ...types,
1384
- XWebHooks: {
1385
- properties: {
1386
- parameters: listOf('Parameter'),
1387
- },
1388
- },
1389
- DefinitionRoot: {
1390
- ...types.DefinitionRoot,
1391
- properties: {
1392
- ...types.DefinitionRoot.properties,
1393
- 'x-webhooks': 'XWebHooks',
1394
- },
1395
- },
1396
- };
1397
- },
1398
- },
1399
- }),
1400
- });
1401
-
1402
- expect(calls).toMatchInlineSnapshot(`
1403
- Array [
1404
- "enter DefinitionRoot",
1405
- "enter XWebHooks",
1406
- "enter hook test",
1407
- "enter ParameterList",
1408
- "enter Parameter",
1409
- "leave Parameter",
1410
- "leave ParameterList",
1411
- "leave hook test",
1412
- "leave XWebHooks",
1413
- "leave DefinitionRoot",
1414
- ]
1415
- `);
1416
- });
1417
- });
1418
-
1419
- describe('ignoreNextRules', () => {
1420
- it('should correctly skip top level', async () => {
1421
- const calls: string[] = [];
1422
-
1423
- const testRuleSet: Oas3RuleSet = {
1424
- skip: jest.fn(() => {
1425
- return {
1426
- Operation: {
1427
- enter: jest.fn((op, ctx) => {
1428
- if (op.operationId === 'get') {
1429
- ctx.ignoreNextVisitorsOnNode();
1430
- calls.push(`enter and skip operation ${op.operationId}`);
1431
- } else {
1432
- calls.push(`enter and not skip operation ${op.operationId}`);
1433
- }
1434
- }),
1435
- leave: jest.fn((op) => {
1436
- if (op.operationId === 'get') {
1437
- calls.push(`leave skipped operation ${op.operationId}`);
1438
- } else {
1439
- calls.push(`leave not skipped operation ${op.operationId}`);
1440
- }
1441
- }),
1442
- },
1443
- };
1444
- }),
1445
- test: jest.fn(() => {
1446
- return {
1447
- Operation: {
1448
- enter: jest.fn((op) => calls.push(`enter operation ${op.operationId}`)),
1449
- leave: jest.fn((op) => calls.push(`leave operation ${op.operationId}`)),
1450
- },
1451
- };
1452
- }),
1453
- };
1454
-
1455
- const document = parseYamlToDocument(
1456
- outdent`
1457
- openapi: 3.0.0
1458
- paths:
1459
- /pet:
1460
- get:
1461
- operationId: get
1462
- put:
1463
- operationId: put
1464
- `,
1465
- '',
1466
- );
1467
-
1468
- await lintDocument({
1469
- externalRefResolver: new BaseResolver(),
1470
- document,
1471
- config: makeConfigForRuleset(testRuleSet),
1472
- });
1473
-
1474
- expect(calls).toMatchInlineSnapshot(`
1475
- Array [
1476
- "enter and skip operation get",
1477
- "leave skipped operation get",
1478
- "enter and not skip operation put",
1479
- "enter operation put",
1480
- "leave not skipped operation put",
1481
- "leave operation put",
1482
- ]
1483
- `);
1484
- });
1485
- });