@redocly/openapi-core 1.19.0 → 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 (338) hide show
  1. package/CHANGELOG.md +12 -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 +5 -1
  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 +5 -1
  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 +5 -1
  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 +17 -13
  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 +16 -12
  13. package/lib/benchmark/utils.d.ts +3 -3
  14. package/lib/benchmark/utils.js +3 -3
  15. package/lib/config/all.js +4 -1
  16. package/lib/config/builtIn.js +15 -20
  17. package/lib/config/config-resolvers.d.ts +1 -1
  18. package/lib/config/config-resolvers.js +66 -24
  19. package/lib/config/config.d.ts +3 -2
  20. package/lib/config/load.d.ts +1 -1
  21. package/lib/config/minimal.js +4 -0
  22. package/lib/config/recommended-strict.js +5 -1
  23. package/lib/config/recommended.js +5 -1
  24. package/lib/config/types.d.ts +9 -2
  25. package/lib/config/utils.d.ts +3 -1
  26. package/lib/config/utils.js +8 -0
  27. package/lib/decorators/common/filters/filter-helper.d.ts +1 -1
  28. package/lib/decorators/common/filters/filter-in.d.ts +1 -1
  29. package/lib/decorators/common/filters/filter-out.d.ts +1 -1
  30. package/lib/decorators/common/info-description-override.d.ts +1 -1
  31. package/lib/decorators/common/info-override.d.ts +1 -1
  32. package/lib/decorators/common/media-type-examples-override.d.ts +1 -1
  33. package/lib/decorators/common/operation-description-override.d.ts +1 -1
  34. package/lib/decorators/common/registry-dependencies.d.ts +1 -1
  35. package/lib/decorators/common/remove-x-internal.d.ts +1 -1
  36. package/lib/decorators/common/tag-description-override.d.ts +1 -1
  37. package/lib/decorators/oas2/index.d.ts +1 -1
  38. package/lib/decorators/oas3/index.d.ts +1 -1
  39. package/lib/format/codeframes.d.ts +1 -1
  40. package/lib/format/format.d.ts +1 -1
  41. package/lib/format/format.js +1 -1
  42. package/lib/js-yaml/index.d.ts +1 -1
  43. package/lib/lint.d.ts +1 -1
  44. package/lib/logger.js +2 -2
  45. package/lib/oas-types.d.ts +2 -2
  46. package/lib/redocly/domains.d.ts +1 -1
  47. package/lib/redocly/index.d.ts +1 -1
  48. package/lib/ref-utils.d.ts +2 -2
  49. package/lib/ref-utils.js +1 -0
  50. package/lib/resolve.d.ts +2 -2
  51. package/lib/rules/ajv.d.ts +1 -1
  52. package/lib/rules/arazzo/index.js +2 -0
  53. package/lib/rules/async2/channels-kebab-case.d.ts +1 -1
  54. package/lib/rules/async2/index.js +2 -0
  55. package/lib/rules/async2/no-channel-trailing-slash.d.ts +1 -1
  56. package/lib/rules/async3/channels-kebab-case.d.ts +1 -1
  57. package/lib/rules/async3/index.js +2 -0
  58. package/lib/rules/async3/no-channel-trailing-slash.d.ts +1 -1
  59. package/lib/rules/common/assertions/asserts.d.ts +2 -2
  60. package/lib/rules/common/assertions/index.d.ts +1 -2
  61. package/lib/rules/common/assertions/utils.d.ts +1 -1
  62. package/lib/rules/common/info-contact.d.ts +1 -1
  63. package/lib/rules/common/info-license-strict.d.ts +2 -0
  64. package/lib/rules/common/info-license-strict.js +26 -0
  65. package/lib/rules/common/info-license-url.d.ts +1 -1
  66. package/lib/rules/common/info-license.d.ts +1 -1
  67. package/lib/rules/common/no-ambiguous-paths.d.ts +1 -1
  68. package/lib/rules/common/no-enum-type-mismatch.d.ts +1 -1
  69. package/lib/rules/common/no-http-verbs-in-paths.d.ts +1 -1
  70. package/lib/rules/common/no-identical-paths.d.ts +1 -1
  71. package/lib/rules/common/no-path-trailing-slash.d.ts +1 -1
  72. package/lib/rules/common/no-required-schema-properties-undefined.d.ts +1 -1
  73. package/lib/rules/common/operation-2xx-response.d.ts +1 -1
  74. package/lib/rules/common/operation-4xx-response.d.ts +1 -1
  75. package/lib/rules/common/operation-description.d.ts +1 -1
  76. package/lib/rules/common/operation-operationId-unique.d.ts +1 -1
  77. package/lib/rules/common/operation-operationId-url-safe.d.ts +1 -1
  78. package/lib/rules/common/operation-operationId-url-safe.js +1 -0
  79. package/lib/rules/common/operation-operationId.d.ts +1 -1
  80. package/lib/rules/common/operation-parameters-unique.d.ts +1 -1
  81. package/lib/rules/common/operation-singular-tag.d.ts +1 -1
  82. package/lib/rules/common/operation-summary.d.ts +1 -1
  83. package/lib/rules/common/operation-tag-defined.d.ts +1 -1
  84. package/lib/rules/common/parameter-description.d.ts +1 -1
  85. package/lib/rules/common/path-declaration-must-exist.d.ts +1 -1
  86. package/lib/rules/common/path-excludes-patterns.d.ts +1 -1
  87. package/lib/rules/common/path-http-verbs-order.d.ts +1 -1
  88. package/lib/rules/common/path-not-include-query.d.ts +1 -1
  89. package/lib/rules/common/path-params-defined.d.ts +1 -1
  90. package/lib/rules/common/path-segment-plural.d.ts +1 -1
  91. package/lib/rules/common/paths-kebab-case.d.ts +1 -1
  92. package/lib/rules/common/required-string-property-missing-min-length.d.ts +1 -1
  93. package/lib/rules/common/response-contains-header.d.ts +1 -1
  94. package/lib/rules/common/security-defined.d.ts +1 -1
  95. package/lib/rules/common/spec-strict-refs.d.ts +1 -1
  96. package/lib/rules/common/tag-description.d.ts +1 -1
  97. package/lib/rules/common/tags-alphabetical.d.ts +1 -1
  98. package/lib/rules/no-unresolved-refs.d.ts +3 -3
  99. package/lib/rules/oas2/boolean-parameter-prefixes.d.ts +1 -1
  100. package/lib/rules/oas2/index.d.ts +1 -1
  101. package/lib/rules/oas2/index.js +2 -0
  102. package/lib/rules/oas2/response-contains-property.d.ts +1 -1
  103. package/lib/rules/oas3/array-parameter-serialization.d.ts +1 -1
  104. package/lib/rules/oas3/boolean-parameter-prefixes.d.ts +1 -1
  105. package/lib/rules/oas3/component-name-unique.d.ts +1 -1
  106. package/lib/rules/oas3/index.d.ts +1 -1
  107. package/lib/rules/oas3/index.js +2 -0
  108. package/lib/rules/oas3/no-empty-servers.d.ts +1 -1
  109. package/lib/rules/oas3/no-example-value-and-externalValue.d.ts +1 -1
  110. package/lib/rules/oas3/no-invalid-media-type-examples.d.ts +1 -1
  111. package/lib/rules/oas3/no-server-example.com.d.ts +1 -1
  112. package/lib/rules/oas3/no-server-example.com.js +1 -0
  113. package/lib/rules/oas3/no-server-trailing-slash.d.ts +1 -1
  114. package/lib/rules/oas3/no-server-variables-empty-enum.d.ts +1 -1
  115. package/lib/rules/oas3/no-undefined-server-variable.d.ts +1 -1
  116. package/lib/rules/oas3/no-unused-components.d.ts +1 -1
  117. package/lib/rules/oas3/response-contains-property.d.ts +1 -1
  118. package/lib/rules/oas3/spec-components-invalid-map-name.d.ts +1 -1
  119. package/lib/rules/other/stats.d.ts +3 -3
  120. package/lib/rules/other/stats.js +5 -3
  121. package/lib/rules/spot/parameters-no-body-inside-in.d.ts +2 -0
  122. package/lib/rules/spot/parameters-no-body-inside-in.js +18 -0
  123. package/lib/rules/utils.d.ts +4 -2
  124. package/lib/rules/utils.js +27 -1
  125. package/lib/types/arazzo.d.ts +1 -2275
  126. package/lib/types/arazzo.js +246 -309
  127. package/lib/types/asyncapi2.d.ts +1 -1
  128. package/lib/types/asyncapi2.js +3 -1
  129. package/lib/types/asyncapi3.d.ts +1 -1
  130. package/lib/types/json-schema-adapter.d.ts +1 -1
  131. package/lib/types/oas3.d.ts +4 -0
  132. package/lib/types/oas3.js +9 -9
  133. package/lib/types/oas3_1.d.ts +3 -0
  134. package/lib/types/oas3_1.js +8 -8
  135. package/lib/types/redocly-yaml.d.ts +6 -6
  136. package/lib/types/redocly-yaml.js +4 -1
  137. package/lib/typings/arazzo.d.ts +145 -27
  138. package/lib/typings/common.d.ts +1 -1
  139. package/lib/typings/swagger.d.ts +2 -2
  140. package/lib/visitors.d.ts +18 -1
  141. package/lib/walk.d.ts +3 -3
  142. package/package.json +2 -2
  143. package/src/__tests__/bundle.test.ts +4 -4
  144. package/src/__tests__/lint.test.ts +29 -21
  145. package/src/__tests__/walk.test.ts +25 -25
  146. package/src/benchmark/benches/lint-with-many-rules.bench.ts +7 -1
  147. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +7 -1
  148. package/src/benchmark/benches/lint-with-no-rules.bench.ts +8 -1
  149. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +18 -13
  150. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +17 -11
  151. package/src/benchmark/fork.js +4 -0
  152. package/src/benchmark/utils.ts +6 -5
  153. package/src/bundle.ts +2 -1
  154. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +10 -2
  155. package/src/config/__tests__/config-resolvers.test.ts +82 -0
  156. package/src/config/__tests__/fixtures/resolve-config/local-config-with-commonjs-export-function.yaml +2 -0
  157. package/src/config/__tests__/fixtures/resolve-config/local-config-with-esm.yaml +2 -0
  158. package/src/config/__tests__/fixtures/resolve-config/plugin-esm.mjs +10 -0
  159. package/src/config/__tests__/fixtures/resolve-config/plugin-with-export-function.cjs +10 -0
  160. package/src/config/__tests__/resolve-plugins.test.ts +4 -1
  161. package/src/config/all.ts +4 -1
  162. package/src/config/builtIn.ts +5 -10
  163. package/src/config/config-resolvers.ts +77 -19
  164. package/src/config/config.ts +7 -8
  165. package/src/config/load.ts +2 -2
  166. package/src/config/minimal.ts +4 -0
  167. package/src/config/recommended-strict.ts +5 -1
  168. package/src/config/recommended.ts +5 -1
  169. package/src/config/types.ts +19 -3
  170. package/src/config/utils.ts +13 -2
  171. package/src/decorators/__tests__/filter-in.test.ts +29 -26
  172. package/src/decorators/__tests__/filter-out.test.ts +32 -23
  173. package/src/decorators/__tests__/media-type-examples-override.test.ts +45 -45
  174. package/src/decorators/__tests__/remove-x-internal.test.ts +8 -5
  175. package/src/decorators/common/filters/filter-helper.ts +2 -1
  176. package/src/decorators/common/filters/filter-in.ts +2 -1
  177. package/src/decorators/common/filters/filter-out.ts +2 -1
  178. package/src/decorators/common/info-description-override.ts +3 -2
  179. package/src/decorators/common/info-override.ts +1 -1
  180. package/src/decorators/common/media-type-examples-override.ts +4 -3
  181. package/src/decorators/common/operation-description-override.ts +5 -4
  182. package/src/decorators/common/registry-dependencies.ts +2 -2
  183. package/src/decorators/common/remove-x-internal.ts +3 -2
  184. package/src/decorators/common/tag-description-override.ts +3 -2
  185. package/src/decorators/oas2/__tests__/remove-unused-components.test.ts +3 -3
  186. package/src/decorators/oas2/index.ts +2 -1
  187. package/src/decorators/oas2/remove-unused-components.ts +1 -1
  188. package/src/decorators/oas3/__tests__/remove-unused-components.test.ts +4 -4
  189. package/src/decorators/oas3/index.ts +2 -1
  190. package/src/decorators/oas3/remove-unused-components.ts +1 -1
  191. package/src/format/codeframes.ts +2 -1
  192. package/src/format/format.ts +9 -4
  193. package/src/js-yaml/index.ts +3 -1
  194. package/src/lint.ts +2 -1
  195. package/src/logger.ts +2 -2
  196. package/src/oas-types.ts +14 -13
  197. package/src/redocly/domains.ts +1 -1
  198. package/src/redocly/index.ts +3 -3
  199. package/src/redocly/registry-api.ts +5 -3
  200. package/src/ref-utils.ts +4 -2
  201. package/src/resolve.ts +6 -4
  202. package/src/rules/__tests__/no-unresolved-refs.test.ts +21 -7
  203. package/src/rules/ajv.ts +2 -1
  204. package/src/rules/arazzo/__tests__/parameters-no-body-inside-in.test.ts +76 -0
  205. package/src/rules/arazzo/index.ts +5 -2
  206. package/src/rules/async2/__tests__/channels-kebab-case.test.ts +9 -5
  207. package/src/rules/async2/__tests__/no-channel-trailing-slash.test.ts +3 -3
  208. package/src/rules/async2/channels-kebab-case.ts +2 -2
  209. package/src/rules/async2/index.ts +4 -1
  210. package/src/rules/async2/no-channel-trailing-slash.ts +2 -2
  211. package/src/rules/async3/__tests__/channels-kebab-case.test.ts +9 -5
  212. package/src/rules/async3/__tests__/no-channel-trailing-slash.test.ts +3 -3
  213. package/src/rules/async3/channels-kebab-case.ts +3 -3
  214. package/src/rules/async3/index.ts +4 -1
  215. package/src/rules/async3/no-channel-trailing-slash.ts +3 -3
  216. package/src/rules/common/__tests__/info-license-strict.test.ts +141 -0
  217. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  218. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  219. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  220. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +5 -5
  221. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  222. package/src/rules/common/__tests__/no-invalid-parameter-examples.test.ts +1 -1
  223. package/src/rules/common/__tests__/no-invalid-schema-examples.test.ts +1 -1
  224. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +4 -4
  225. package/src/rules/common/__tests__/no-required-schema-properties-undefined.test.ts +11 -11
  226. package/src/rules/common/__tests__/operation-2xx-response.test.ts +8 -6
  227. package/src/rules/common/__tests__/operation-4xx-response.test.ts +9 -7
  228. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  229. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  230. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  231. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  232. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  233. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  234. package/src/rules/common/__tests__/path-params-defined.test.ts +5 -5
  235. package/src/rules/common/__tests__/paths-kebab-case.test.ts +6 -4
  236. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
  237. package/src/rules/common/__tests__/security-defined.test.ts +14 -8
  238. package/src/rules/common/__tests__/spec-strict-refs.test.ts +1 -1
  239. package/src/rules/common/__tests__/spec.test.ts +10 -10
  240. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  241. package/src/rules/common/__tests__/tags-alphabetical.test.ts +6 -4
  242. package/src/rules/common/assertions/asserts.ts +5 -9
  243. package/src/rules/common/assertions/index.ts +1 -2
  244. package/src/rules/common/assertions/utils.ts +4 -2
  245. package/src/rules/common/info-contact.ts +2 -1
  246. package/src/rules/common/info-license-strict.ts +24 -0
  247. package/src/rules/common/info-license-url.ts +2 -1
  248. package/src/rules/common/info-license.ts +2 -1
  249. package/src/rules/common/no-ambiguous-paths.ts +4 -4
  250. package/src/rules/common/no-enum-type-mismatch.ts +5 -4
  251. package/src/rules/common/no-http-verbs-in-paths.ts +5 -4
  252. package/src/rules/common/no-identical-paths.ts +4 -4
  253. package/src/rules/common/no-invalid-parameter-examples.ts +3 -2
  254. package/src/rules/common/no-path-trailing-slash.ts +2 -2
  255. package/src/rules/common/no-required-schema-properties-undefined.ts +5 -4
  256. package/src/rules/common/operation-2xx-response.ts +3 -2
  257. package/src/rules/common/operation-4xx-response.ts +3 -2
  258. package/src/rules/common/operation-description.ts +5 -4
  259. package/src/rules/common/operation-operationId-unique.ts +4 -4
  260. package/src/rules/common/operation-operationId-url-safe.ts +5 -4
  261. package/src/rules/common/operation-operationId.ts +5 -4
  262. package/src/rules/common/operation-parameters-unique.ts +4 -4
  263. package/src/rules/common/operation-singular-tag.ts +4 -4
  264. package/src/rules/common/operation-summary.ts +5 -4
  265. package/src/rules/common/operation-tag-defined.ts +4 -4
  266. package/src/rules/common/parameter-description.ts +4 -4
  267. package/src/rules/common/path-declaration-must-exist.ts +2 -2
  268. package/src/rules/common/path-excludes-patterns.ts +4 -4
  269. package/src/rules/common/path-http-verbs-order.ts +4 -4
  270. package/src/rules/common/path-not-include-query.ts +2 -2
  271. package/src/rules/common/path-params-defined.ts +4 -4
  272. package/src/rules/common/path-segment-plural.ts +3 -2
  273. package/src/rules/common/paths-kebab-case.ts +2 -2
  274. package/src/rules/common/required-string-property-missing-min-length.ts +4 -4
  275. package/src/rules/common/response-contains-header.ts +5 -4
  276. package/src/rules/common/scalar-property-missing-example.ts +2 -1
  277. package/src/rules/common/security-defined.ts +5 -5
  278. package/src/rules/common/spec-strict-refs.ts +2 -1
  279. package/src/rules/common/spec.ts +3 -2
  280. package/src/rules/common/tag-description.ts +2 -1
  281. package/src/rules/common/tags-alphabetical.ts +4 -4
  282. package/src/rules/no-unresolved-refs.ts +4 -3
  283. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +7 -5
  284. package/src/rules/oas2/__tests__/response-contains-header.test.ts +14 -8
  285. package/src/rules/oas2/__tests__/response-contains-property.test.ts +14 -8
  286. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +3 -1
  287. package/src/rules/oas2/boolean-parameter-prefixes.ts +1 -1
  288. package/src/rules/oas2/index.ts +4 -2
  289. package/src/rules/oas2/request-mime-type.ts +2 -1
  290. package/src/rules/oas2/response-contains-property.ts +3 -2
  291. package/src/rules/oas2/response-mime-type.ts +2 -1
  292. package/src/rules/oas3/__tests__/array-parameter-serialization.test.ts +18 -6
  293. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +7 -5
  294. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +6 -6
  295. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  296. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +34 -24
  297. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +3 -3
  298. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  299. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  300. package/src/rules/oas3/__tests__/operation-4xx-problem-details-rfc7807.test.ts +3 -3
  301. package/src/rules/oas3/__tests__/response-contains-header.test.ts +34 -22
  302. package/src/rules/oas3/__tests__/response-contains-property.test.ts +34 -20
  303. package/src/rules/oas3/__tests__/spec/spec.test.ts +12 -3
  304. package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +9 -3
  305. package/src/rules/oas3/__tests__/utils/lint-document-for-test.ts +1 -1
  306. package/src/rules/oas3/array-parameter-serialization.ts +3 -2
  307. package/src/rules/oas3/boolean-parameter-prefixes.ts +1 -1
  308. package/src/rules/oas3/component-name-unique.ts +3 -3
  309. package/src/rules/oas3/index.ts +3 -1
  310. package/src/rules/oas3/no-empty-servers.ts +1 -1
  311. package/src/rules/oas3/no-example-value-and-externalValue.ts +1 -1
  312. package/src/rules/oas3/no-invalid-media-type-examples.ts +6 -4
  313. package/src/rules/oas3/no-server-example.com.ts +2 -1
  314. package/src/rules/oas3/no-server-trailing-slash.ts +1 -1
  315. package/src/rules/oas3/no-server-variables-empty-enum.ts +2 -2
  316. package/src/rules/oas3/no-undefined-server-variable.ts +1 -1
  317. package/src/rules/oas3/no-unused-components.ts +2 -2
  318. package/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +2 -1
  319. package/src/rules/oas3/request-mime-type.ts +2 -1
  320. package/src/rules/oas3/response-contains-property.ts +3 -2
  321. package/src/rules/oas3/response-mime-type.ts +2 -1
  322. package/src/rules/oas3/spec-components-invalid-map-name.ts +3 -3
  323. package/src/rules/other/stats.ts +8 -6
  324. package/src/rules/spot/parameters-no-body-inside-in.ts +17 -0
  325. package/src/rules/utils.ts +41 -4
  326. package/src/types/arazzo.ts +257 -334
  327. package/src/types/asyncapi2.ts +4 -1
  328. package/src/types/asyncapi3.ts +3 -1
  329. package/src/types/json-schema-adapter.ts +2 -2
  330. package/src/types/oas3.ts +4 -4
  331. package/src/types/oas3_1.ts +3 -3
  332. package/src/types/redocly-yaml.ts +7 -4
  333. package/src/typings/arazzo.ts +169 -41
  334. package/src/typings/common.ts +1 -0
  335. package/src/typings/swagger.ts +2 -2
  336. package/src/visitors.ts +40 -1
  337. package/src/walk.ts +3 -3
  338. package/tsconfig.tsbuildinfo +1 -1
@@ -2,16 +2,11 @@ import recommended from './recommended';
2
2
  import recommendedStrict from './recommended-strict';
3
3
  import all from './all';
4
4
  import minimal from './minimal';
5
- import { rules as oas3Rules } from '../rules/oas3';
6
- import { rules as oas2Rules } from '../rules/oas2';
7
- import { rules as async2Rules } from '../rules/async2';
8
- import { rules as async3Rules } from '../rules/async3';
9
- import { rules as arazzoRules } from '../rules/arazzo';
10
- import { preprocessors as oas3Preprocessors } from '../rules/oas3';
11
- import { preprocessors as oas2Preprocessors } from '../rules/oas2';
12
- import { preprocessors as async2Preprocessors } from '../rules/async2';
13
- import { preprocessors as async3Preprocessors } from '../rules/async3';
14
- import { preprocessors as arazzoPreprocessors } from '../rules/arazzo';
5
+ import { rules as oas3Rules, preprocessors as oas3Preprocessors } from '../rules/oas3';
6
+ import { rules as oas2Rules, preprocessors as oas2Preprocessors } from '../rules/oas2';
7
+ import { rules as async2Rules, preprocessors as async2Preprocessors } from '../rules/async2';
8
+ import { rules as async3Rules, preprocessors as async3Preprocessors } from '../rules/async3';
9
+ import { rules as arazzoRules, preprocessors as arazzoPreprocessors } from '../rules/arazzo';
15
10
  import { decorators as oas3Decorators } from '../decorators/oas3';
16
11
  import { decorators as oas2Decorators } from '../decorators/oas2';
17
12
  import { decorators as async2Decorators } from '../decorators/async2';
@@ -1,18 +1,20 @@
1
1
  import * as path from 'path';
2
+ import { existsSync } from 'fs';
2
3
  import { isAbsoluteUrl } from '../ref-utils';
3
- import { pickDefined } from '../utils';
4
+ import { pickDefined, isNotString, isString, isDefined, keysOf } from '../utils';
4
5
  import { resolveDocument, BaseResolver } from '../resolve';
5
6
  import { defaultPlugin } from './builtIn';
6
7
  import {
7
8
  getResolveConfig,
8
9
  getUniquePlugins,
10
+ isCommonJsPlugin,
11
+ isDeprecatedPluginFormat,
9
12
  mergeExtends,
10
13
  parsePresetName,
11
14
  prefixRules,
12
15
  transformConfig,
13
16
  } from './utils';
14
17
  import { isBrowser } from '../env';
15
- import { isNotString, isString, isDefined, keysOf } from '../utils';
16
18
  import { Config } from './config';
17
19
  import { colorize, logger } from '../logger';
18
20
  import { asserts, buildAssertCustomFunction } from '../rules/common/assertions/asserts';
@@ -28,12 +30,18 @@ import type {
28
30
  ResolvedStyleguideConfig,
29
31
  RuleConfig,
30
32
  DeprecatedInRawConfig,
33
+ ImportedPlugin,
31
34
  } from './types';
32
35
  import type { Assertion, AssertionDefinition, RawAssertion } from '../rules/common/assertions';
33
36
  import type { Asserts, AssertionFn } from '../rules/common/assertions/asserts';
34
37
  import type { BundleOptions } from '../bundle';
35
38
  import type { Document, ResolvedRefMap } from '../resolve';
36
39
 
40
+ const DEFAULT_PROJECT_PLUGIN_PATHS = ['@theme/plugin.js', '@theme/plugin.cjs', '@theme/plugin.mjs'];
41
+
42
+ // Workaround for dynamic imports being transpiled to require by Typescript: https://github.com/microsoft/TypeScript/issues/43329#issuecomment-811606238
43
+ const _importDynamic = new Function('modulePath', 'return import(modulePath)');
44
+
37
45
  export async function resolveConfigFileAndRefs({
38
46
  configPath,
39
47
  externalRefResolver = new BaseResolver(),
@@ -102,14 +110,24 @@ export async function resolveConfig({
102
110
  );
103
111
  }
104
112
 
105
- export function resolvePlugins(
113
+ function getDefaultPluginPath(configPath: string): string | undefined {
114
+ for (const pluginPath of DEFAULT_PROJECT_PLUGIN_PATHS) {
115
+ const absolutePluginPath = path.resolve(path.dirname(configPath), pluginPath);
116
+ if (existsSync(absolutePluginPath)) {
117
+ return pluginPath;
118
+ }
119
+ }
120
+ return undefined;
121
+ }
122
+
123
+ export async function resolvePlugins(
106
124
  plugins: (string | Plugin)[] | null,
107
125
  configPath: string = ''
108
- ): Plugin[] {
126
+ ): Promise<Plugin[]> {
109
127
  if (!plugins) return [];
110
128
 
111
129
  // TODO: implement or reuse Resolver approach so it will work in node and browser envs
112
- const requireFunc = (plugin: string | Plugin): Plugin | undefined => {
130
+ const requireFunc = async (plugin: string | Plugin): Promise<ImportedPlugin | undefined> => {
113
131
  if (isBrowser && isString(plugin)) {
114
132
  logger.error(`Cannot load ${plugin}. Plugins aren't supported in browser yet.`);
115
133
 
@@ -118,14 +136,24 @@ export function resolvePlugins(
118
136
 
119
137
  if (isString(plugin)) {
120
138
  try {
121
- const absoltePluginPath = path.resolve(path.dirname(configPath), plugin);
139
+ const maybeAbsolutePluginPath = path.resolve(path.dirname(configPath), plugin);
140
+
141
+ const absolutePluginPath = existsSync(maybeAbsolutePluginPath)
142
+ ? maybeAbsolutePluginPath
143
+ : // For plugins imported from packages specifically
144
+ require.resolve(plugin);
145
+
122
146
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
123
147
  // @ts-ignore
124
- return typeof __webpack_require__ === 'function'
125
- ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
126
- // @ts-ignore
127
- __non_webpack_require__(absoltePluginPath)
128
- : require(absoltePluginPath);
148
+ if (typeof __webpack_require__ === 'function') {
149
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
150
+ // @ts-ignore
151
+ return __non_webpack_require__(absolutePluginPath);
152
+ } else {
153
+ // you can import both cjs and mjs
154
+ const mod = await _importDynamic(absolutePluginPath);
155
+ return mod.default || mod;
156
+ }
129
157
  } catch (e) {
130
158
  if (e instanceof SyntaxError) {
131
159
  throw e;
@@ -139,19 +167,47 @@ export function resolvePlugins(
139
167
 
140
168
  const seenPluginIds = new Map<string, string>();
141
169
 
142
- return plugins
143
- .map((p) => {
144
- if (isString(p) && isAbsoluteUrl(p)) {
145
- throw new Error(colorize.red(`We don't support remote plugins yet.`));
170
+ /**
171
+ * Include the default plugin automatically if it's not in configuration
172
+ */
173
+ const defaultPluginPath = getDefaultPluginPath(configPath);
174
+ if (defaultPluginPath) {
175
+ plugins.push(defaultPluginPath);
176
+ }
177
+
178
+ const resolvedPlugins: Set<string> = new Set();
179
+
180
+ const instances = await Promise.all(
181
+ plugins.map(async (p) => {
182
+ if (isString(p)) {
183
+ if (isAbsoluteUrl(p)) {
184
+ throw new Error(colorize.red(`We don't support remote plugins yet.`));
185
+ }
186
+ if (resolvedPlugins.has(p)) {
187
+ return;
188
+ }
189
+
190
+ resolvedPlugins.add(p);
146
191
  }
147
192
 
148
- // TODO: resolve npm packages similar to eslint
149
- const pluginModule = requireFunc(p);
193
+ const requiredPlugin: ImportedPlugin | undefined = await requireFunc(p);
194
+
195
+ const pluginCreatorOptions = { contentDir: path.dirname(configPath) };
196
+
197
+ const pluginModule = isDeprecatedPluginFormat(requiredPlugin)
198
+ ? requiredPlugin
199
+ : isCommonJsPlugin(requiredPlugin)
200
+ ? await requiredPlugin(pluginCreatorOptions)
201
+ : await requiredPlugin?.default?.(pluginCreatorOptions);
150
202
 
151
203
  if (!pluginModule) {
152
204
  return;
153
205
  }
154
206
 
207
+ if (isString(p) && pluginModule.id && isDeprecatedPluginFormat(requiredPlugin)) {
208
+ logger.info(`Deprecated plugin format detected: ${pluginModule.id}\n`);
209
+ }
210
+
155
211
  const id = pluginModule.id;
156
212
  if (typeof id !== 'string') {
157
213
  throw new Error(
@@ -267,7 +323,9 @@ export function resolvePlugins(
267
323
 
268
324
  return plugin;
269
325
  })
270
- .filter(isDefined);
326
+ );
327
+
328
+ return instances.filter(isDefined);
271
329
  }
272
330
 
273
331
  export async function resolveApis({
@@ -318,7 +376,7 @@ async function resolveAndMergeNestedStyleguideConfig(
318
376
  throw new Error(`Circular dependency in config file: "${configPath}"`);
319
377
  }
320
378
  const plugins = getUniquePlugins(
321
- resolvePlugins([...(styleguideConfig?.plugins || []), defaultPlugin], configPath)
379
+ await resolvePlugins([...(styleguideConfig?.plugins || []), defaultPlugin], configPath)
322
380
  );
323
381
  const pluginPaths = styleguideConfig?.plugins
324
382
  ?.filter(isString)
@@ -2,18 +2,19 @@ import * as fs from 'fs';
2
2
  import * as path from 'path';
3
3
  import { parseYaml, stringifyYaml } from '../js-yaml';
4
4
  import { slash, doesYamlFileExist } from '../utils';
5
- import { NormalizedProblem } from '../walk';
6
- import {
7
- SpecVersion,
8
- SpecMajorVersion,
5
+ import { SpecVersion, SpecMajorVersion } from '../oas-types';
6
+ import { isBrowser } from '../env';
7
+ import { getResolveConfig } from './utils';
8
+ import { isAbsoluteUrl } from '../ref-utils';
9
+
10
+ import type { NormalizedProblem } from '../walk';
11
+ import type {
9
12
  Oas2RuleSet,
10
13
  Oas3RuleSet,
11
14
  Async2RuleSet,
12
15
  Async3RuleSet,
13
16
  ArazzoRuleSet,
14
17
  } from '../oas-types';
15
- import { isBrowser } from '../env';
16
-
17
18
  import type { NodeType } from '../types';
18
19
  import type {
19
20
  DecoratorConfig,
@@ -29,8 +30,6 @@ import type {
29
30
  Telemetry,
30
31
  ThemeRawConfig,
31
32
  } from './types';
32
- import { getResolveConfig } from './utils';
33
- import { isAbsoluteUrl } from '../ref-utils';
34
33
 
35
34
  export const IGNORE_FILE = '.redocly.lint-ignore.yaml';
36
35
  const IGNORE_BANNER =
@@ -3,17 +3,17 @@ import * as path from 'path';
3
3
  import { RedoclyClient } from '../redocly';
4
4
  import { isEmptyObject } from '../utils';
5
5
  import { parseYaml } from '../js-yaml';
6
- import { Config } from './config';
7
6
  import { ConfigValidationError, transformConfig, deepCloneMapWithJSON } from './utils';
8
7
  import { resolveConfig, resolveConfigFileAndRefs } from './config-resolvers';
9
8
  import { bundleConfig } from '../bundle';
10
9
  import { BaseResolver } from '../resolve';
11
10
  import { isBrowser } from '../env';
11
+ import { DOMAINS } from '../redocly/domains';
12
12
 
13
+ import type { Config } from './config';
13
14
  import type { Document, ResolvedRefMap } from '../resolve';
14
15
  import type { RegionalToken, RegionalTokenWithValidity } from '../redocly/redocly-client-types';
15
16
  import type { RawConfig, RawUniversalConfig, Region } from './types';
16
- import { DOMAINS } from '../redocly/domains';
17
17
 
18
18
  async function addConfigMetadata({
19
19
  rawConfig,
@@ -5,6 +5,7 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
5
5
  'info-contact': 'off',
6
6
  'info-license': 'off',
7
7
  'info-license-url': 'off',
8
+ 'info-license-strict': 'off',
8
9
  'tag-description': 'warn',
9
10
  'tags-alphabetical': 'off',
10
11
  'parameter-description': 'off',
@@ -90,6 +91,7 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
90
91
  async2Rules: {
91
92
  spec: 'error',
92
93
  'info-contact': 'off',
94
+ 'info-license-strict': 'off',
93
95
  'operation-operationId': 'warn',
94
96
  'tag-description': 'warn',
95
97
  'tags-alphabetical': 'off',
@@ -99,6 +101,7 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
99
101
  async3Rules: {
100
102
  spec: 'error',
101
103
  'info-contact': 'off',
104
+ 'info-license-strict': 'off',
102
105
  'operation-operationId': 'warn',
103
106
  'tag-description': 'warn',
104
107
  'tags-alphabetical': 'off',
@@ -107,6 +110,7 @@ const minimal: PluginStyleguideConfig<'built-in'> = {
107
110
  },
108
111
  arazzoRules: {
109
112
  spec: 'error',
113
+ 'parameters-no-body-inside-in': 'off',
110
114
  },
111
115
  };
112
116
 
@@ -4,7 +4,8 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
4
4
  rules: {
5
5
  'info-contact': 'off',
6
6
  'info-license': 'error',
7
- 'info-license-url': 'error',
7
+ 'info-license-url': 'off',
8
+ 'info-license-strict': 'error',
8
9
  'tag-description': 'error',
9
10
  'tags-alphabetical': 'off',
10
11
  'parameter-description': 'off',
@@ -90,6 +91,7 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
90
91
  async2Rules: {
91
92
  spec: 'error',
92
93
  'info-contact': 'off',
94
+ 'info-license-strict': 'error',
93
95
  'operation-operationId': 'error',
94
96
  'tag-description': 'error',
95
97
  'tags-alphabetical': 'off',
@@ -99,6 +101,7 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
99
101
  async3Rules: {
100
102
  spec: 'error',
101
103
  'info-contact': 'off',
104
+ 'info-license-strict': 'error',
102
105
  'operation-operationId': 'error',
103
106
  'tag-description': 'error',
104
107
  'tags-alphabetical': 'off',
@@ -107,6 +110,7 @@ const recommendedStrict: PluginStyleguideConfig<'built-in'> = {
107
110
  },
108
111
  arazzoRules: {
109
112
  spec: 'error',
113
+ 'parameters-no-body-inside-in': 'off',
110
114
  },
111
115
  };
112
116
 
@@ -4,7 +4,8 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
4
4
  rules: {
5
5
  'info-contact': 'off',
6
6
  'info-license': 'warn',
7
- 'info-license-url': 'warn',
7
+ 'info-license-url': 'off',
8
+ 'info-license-strict': 'warn',
8
9
  'tag-description': 'warn',
9
10
  'tags-alphabetical': 'off',
10
11
  'parameter-description': 'off',
@@ -90,6 +91,7 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
90
91
  async2Rules: {
91
92
  spec: 'error',
92
93
  'info-contact': 'off',
94
+ 'info-license-strict': 'warn',
93
95
  'operation-operationId': 'warn',
94
96
  'tag-description': 'warn',
95
97
  'tags-alphabetical': 'off',
@@ -99,6 +101,7 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
99
101
  async3Rules: {
100
102
  spec: 'error',
101
103
  'info-contact': 'off',
104
+ 'info-license-strict': 'warn',
102
105
  'operation-operationId': 'warn',
103
106
  'tag-description': 'warn',
104
107
  'tags-alphabetical': 'off',
@@ -107,6 +110,7 @@ const recommended: PluginStyleguideConfig<'built-in'> = {
107
110
  },
108
111
  arazzoRules: {
109
112
  spec: 'error',
113
+ 'parameters-no-body-inside-in': 'off',
110
114
  },
111
115
  };
112
116
 
@@ -1,3 +1,4 @@
1
+ import type { Location } from '../ref-utils';
1
2
  import type { ProblemSeverity, UserContext } from '../walk';
2
3
  import type {
3
4
  Oas3PreprocessorsSet,
@@ -19,11 +20,9 @@ import type {
19
20
  ArazzoDecoratorsSet,
20
21
  RuleMap,
21
22
  } from '../oas-types';
22
-
23
23
  import type { NodeType } from '../types';
24
- import { Location } from '../ref-utils';
25
24
  import type { SkipFunctionContext } from '../visitors';
26
- import {
25
+ import type {
27
26
  BuiltInAsync2RuleId,
28
27
  BuiltInAsync3RuleId,
29
28
  BuiltInCommonOASRuleId,
@@ -145,6 +144,22 @@ export type Plugin = {
145
144
  assertions?: AssertionsConfig;
146
145
  };
147
146
 
147
+ type PluginCreatorOptions = {
148
+ contentDir: string;
149
+ };
150
+
151
+ export type PluginCreator = (options: PluginCreatorOptions) => Plugin | Promise<Plugin>;
152
+
153
+ export type ImportedPlugin =
154
+ // ES Modules
155
+ | {
156
+ default?: PluginCreator;
157
+ }
158
+ // CommonJS
159
+ | PluginCreator
160
+ // Deprecated format
161
+ | Plugin;
162
+
148
163
  export type PluginStyleguideConfig<T = undefined> = Omit<
149
164
  StyleguideRawConfig<T>,
150
165
  'plugins' | 'extends'
@@ -171,6 +186,7 @@ export type RawResolveConfig = {
171
186
 
172
187
  export type HttpResolveConfig = {
173
188
  headers: ResolveHeader[];
189
+ // eslint-disable-next-line @typescript-eslint/ban-types
174
190
  customFetch?: Function;
175
191
  };
176
192
 
@@ -6,13 +6,15 @@ import {
6
6
  showWarningForDeprecatedField,
7
7
  } from '../utils';
8
8
  import { Config } from './config';
9
+ import { logger, colorize } from '../logger';
10
+
9
11
  import type {
10
12
  Api,
11
13
  DeprecatedInApi,
12
14
  DeprecatedInRawConfig,
15
+ ImportedPlugin,
13
16
  FlatApi,
14
17
  FlatRawConfig,
15
- Plugin,
16
18
  RawConfig,
17
19
  RawResolveConfig,
18
20
  ResolveConfig,
@@ -20,8 +22,9 @@ import type {
20
22
  RulesFields,
21
23
  StyleguideRawConfig,
22
24
  ThemeConfig,
25
+ Plugin,
26
+ PluginCreator,
23
27
  } from './types';
24
- import { logger, colorize } from '../logger';
25
28
 
26
29
  export function parsePresetName(presetName: string): { pluginId: string; configName: string } {
27
30
  if (presetName.indexOf('/') > -1) {
@@ -398,3 +401,11 @@ export class ConfigValidationError extends Error {}
398
401
  export function deepCloneMapWithJSON<K, V>(originalMap: Map<K, V>): Map<K, V> {
399
402
  return new Map(JSON.parse(JSON.stringify([...originalMap])));
400
403
  }
404
+
405
+ export function isDeprecatedPluginFormat(plugin: ImportedPlugin | undefined): plugin is Plugin {
406
+ return plugin !== undefined && typeof plugin === 'object' && 'id' in plugin;
407
+ }
408
+
409
+ export function isCommonJsPlugin(plugin: ImportedPlugin | undefined): plugin is PluginCreator {
410
+ return typeof plugin === 'function';
411
+ }
@@ -56,7 +56,10 @@ describe('oas3 filter-in', () => {
56
56
  const { bundle: res } = await bundleDocument({
57
57
  document: testDocument,
58
58
  externalRefResolver: new BaseResolver(),
59
- config: await makeConfig({}, { 'filter-in': { value: 'public', property: 'x-access' } }),
59
+ config: await makeConfig({
60
+ rules: {},
61
+ decorators: { 'filter-in': { value: 'public', property: 'x-access' } },
62
+ }),
60
63
  });
61
64
  expect(res.parsed).toMatchInlineSnapshot(`
62
65
  openapi: 3.0.0
@@ -76,16 +79,16 @@ describe('oas3 filter-in', () => {
76
79
  const { bundle: res } = await bundleDocument({
77
80
  document: inputDoc,
78
81
  externalRefResolver: new BaseResolver(),
79
- config: await makeConfig(
80
- {},
81
- {
82
+ config: await makeConfig({
83
+ rules: {},
84
+ decorators: {
82
85
  'filter-in': {
83
86
  property: 'x-audience',
84
87
  value: ['Public', 'Protected'],
85
88
  matchStrategy: 'all',
86
89
  },
87
- }
88
- ),
90
+ },
91
+ }),
89
92
  });
90
93
  expect(res.parsed).toMatchInlineSnapshot(`
91
94
  openapi: 3.0.0
@@ -130,16 +133,16 @@ describe('oas3 filter-in', () => {
130
133
  const { bundle: res } = await bundleDocument({
131
134
  document: testDoc,
132
135
  externalRefResolver: new BaseResolver(),
133
- config: await makeConfig(
134
- {},
135
- {
136
+ config: await makeConfig({
137
+ rules: {},
138
+ decorators: {
136
139
  'filter-in': {
137
140
  property: 'x-audience',
138
141
  value: ['Public', 'Global'],
139
142
  matchStrategy: 'any',
140
143
  },
141
- }
142
- ),
144
+ },
145
+ }),
143
146
  });
144
147
  expect(res.parsed).toMatchInlineSnapshot(`
145
148
  openapi: 3.0.0
@@ -171,16 +174,16 @@ describe('oas3 filter-in', () => {
171
174
  const { bundle: res } = await bundleDocument({
172
175
  document: inputDoc,
173
176
  externalRefResolver: new BaseResolver(),
174
- config: await makeConfig(
175
- {},
176
- {
177
+ config: await makeConfig({
178
+ rules: {},
179
+ decorators: {
177
180
  'filter-in': {
178
181
  property: 'x-audience',
179
182
  value: 'non-existing-audience',
180
183
  matchStrategy: 'any',
181
184
  },
182
- }
183
- ),
185
+ },
186
+ }),
184
187
  });
185
188
  expect(res.parsed).toMatchInlineSnapshot(`
186
189
  openapi: 3.0.0
@@ -220,16 +223,16 @@ describe('oas3 filter-in', () => {
220
223
  const { bundle: res } = await bundleDocument({
221
224
  document: testDoc,
222
225
  externalRefResolver: new BaseResolver(),
223
- config: await makeConfig(
224
- {},
225
- {
226
+ config: await makeConfig({
227
+ rules: {},
228
+ decorators: {
226
229
  'filter-in': {
227
230
  property: 'x-audience',
228
231
  value: ['Public', 'Global'],
229
232
  matchStrategy: 'any',
230
233
  },
231
- }
232
- ),
234
+ },
235
+ }),
233
236
  });
234
237
  expect(res.parsed).toMatchInlineSnapshot(`
235
238
  openapi: 3.0.0
@@ -279,16 +282,16 @@ describe('oas2 filter-in', () => {
279
282
  const { bundle: res } = await bundleDocument({
280
283
  document: testDoc,
281
284
  externalRefResolver: new BaseResolver(),
282
- config: await makeConfig(
283
- {},
284
- {
285
+ config: await makeConfig({
286
+ rules: {},
287
+ decorators: {
285
288
  'filter-in': {
286
289
  property: 'x-access',
287
290
  value: ['public', 'global'],
288
291
  matchStrategy: 'any',
289
292
  },
290
- }
291
- ),
293
+ },
294
+ }),
292
295
  });
293
296
  expect(res.parsed).toMatchInlineSnapshot(`
294
297
  swagger: '2.0'