@redocly/openapi-core 1.0.0 → 1.0.2

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 (275) hide show
  1. package/CHANGELOG.md +9 -0
  2. package/__tests__/utils.ts +88 -0
  3. package/lib/config/all.js +0 -1
  4. package/lib/config/minimal.js +0 -1
  5. package/lib/config/recommended.js +0 -1
  6. package/package.json +1 -1
  7. package/src/__tests__/__snapshots__/bundle.test.ts.snap +437 -0
  8. package/src/__tests__/bundle.test.ts +236 -0
  9. package/src/__tests__/codeframes.test.ts +530 -0
  10. package/src/__tests__/fixtures/.redocly.lint-ignore.yaml +5 -0
  11. package/src/__tests__/fixtures/extension.js +24 -0
  12. package/src/__tests__/fixtures/refs/definitions.yaml +3 -0
  13. package/src/__tests__/fixtures/refs/examples.yaml +8 -0
  14. package/src/__tests__/fixtures/refs/external-request-body.yaml +13 -0
  15. package/src/__tests__/fixtures/refs/externalref.yaml +35 -0
  16. package/src/__tests__/fixtures/refs/hosted.yaml +35 -0
  17. package/src/__tests__/fixtures/refs/openapi-with-external-refs-conflicting-names.yaml +21 -0
  18. package/src/__tests__/fixtures/refs/openapi-with-external-refs.yaml +33 -0
  19. package/src/__tests__/fixtures/refs/openapi-with-url-refs.yaml +18 -0
  20. package/src/__tests__/fixtures/refs/param-b.yaml +1 -0
  21. package/src/__tests__/fixtures/refs/param-c.yaml +1 -0
  22. package/src/__tests__/fixtures/refs/rename.yaml +1 -0
  23. package/src/__tests__/fixtures/refs/requestBody.yaml +9 -0
  24. package/src/__tests__/fixtures/refs/schema-a.yaml +1 -0
  25. package/src/__tests__/fixtures/refs/simple.yaml +1 -0
  26. package/src/__tests__/fixtures/refs/vendor.schema.yaml +20 -0
  27. package/src/__tests__/fixtures/resolve/External.yaml +10 -0
  28. package/src/__tests__/fixtures/resolve/External2.yaml +4 -0
  29. package/src/__tests__/fixtures/resolve/description.md +3 -0
  30. package/src/__tests__/fixtures/resolve/externalInfo.yaml +4 -0
  31. package/src/__tests__/fixtures/resolve/externalLicense.yaml +1 -0
  32. package/src/__tests__/fixtures/resolve/openapi-with-back.yaml +13 -0
  33. package/src/__tests__/fixtures/resolve/openapi-with-md-description.yaml +5 -0
  34. package/src/__tests__/fixtures/resolve/openapi.yaml +28 -0
  35. package/src/__tests__/fixtures/resolve/schemas/type-a.yaml +10 -0
  36. package/src/__tests__/fixtures/resolve/schemas/type-b.yaml +6 -0
  37. package/src/__tests__/fixtures/resolve/transitive/a.yaml +1 -0
  38. package/src/__tests__/fixtures/resolve/transitive/components.yaml +5 -0
  39. package/src/__tests__/fixtures/resolve/transitive/schemas.yaml +3 -0
  40. package/src/__tests__/format.test.ts +76 -0
  41. package/src/__tests__/js-yaml.test.ts +73 -0
  42. package/src/__tests__/lint.test.ts +392 -0
  43. package/src/__tests__/logger-browser.test.ts +53 -0
  44. package/src/__tests__/logger.test.ts +47 -0
  45. package/src/__tests__/login.test.ts +17 -0
  46. package/src/__tests__/normalizeVisitors.test.ts +151 -0
  47. package/src/__tests__/output-browser.test.ts +18 -0
  48. package/src/__tests__/output.test.ts +15 -0
  49. package/src/__tests__/ref-utils.test.ts +120 -0
  50. package/src/__tests__/resolve-http.test.ts +77 -0
  51. package/src/__tests__/resolve.test.ts +431 -0
  52. package/src/__tests__/utils-browser.test.ts +11 -0
  53. package/src/__tests__/utils.test.ts +144 -0
  54. package/src/__tests__/walk.test.ts +1545 -0
  55. package/src/benchmark/benches/lint-with-many-rules.bench.ts +35 -0
  56. package/src/benchmark/benches/lint-with-nested-rule.bench.ts +39 -0
  57. package/src/benchmark/benches/lint-with-no-rules.bench.ts +20 -0
  58. package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +35 -0
  59. package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +32 -0
  60. package/src/benchmark/benches/rebilly.yaml +32275 -0
  61. package/src/benchmark/benches/recommended-oas3.bench.ts +22 -0
  62. package/src/benchmark/benches/resolve-with-no-external.bench.ts +23 -0
  63. package/src/benchmark/benchmark.js +311 -0
  64. package/src/benchmark/colors.js +29 -0
  65. package/src/benchmark/fork.js +83 -0
  66. package/src/benchmark/utils.ts +36 -0
  67. package/src/bundle.ts +417 -0
  68. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +164 -0
  69. package/src/config/__tests__/__snapshots__/config.test.ts.snap +144 -0
  70. package/src/config/__tests__/config-resolvers.test.ts +491 -0
  71. package/src/config/__tests__/config.test.ts +312 -0
  72. package/src/config/__tests__/fixtures/ingore-file.ts +8 -0
  73. package/src/config/__tests__/fixtures/load-redocly.yaml +2 -0
  74. package/src/config/__tests__/fixtures/plugin-config.yaml +2 -0
  75. package/src/config/__tests__/fixtures/plugin.js +56 -0
  76. package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +11 -0
  77. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +69 -0
  78. package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +7 -0
  79. package/src/config/__tests__/fixtures/resolve-config/local-config-with-custom-function.yaml +17 -0
  80. package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +18 -0
  81. package/src/config/__tests__/fixtures/resolve-config/local-config-with-wrong-custom-function.yaml +15 -0
  82. package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +9 -0
  83. package/src/config/__tests__/fixtures/resolve-config/plugin.js +80 -0
  84. package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +3 -0
  85. package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +4 -0
  86. package/src/config/__tests__/load.test.ts +167 -0
  87. package/src/config/__tests__/resolve-plugins.test.ts +27 -0
  88. package/src/config/__tests__/utils.test.ts +204 -0
  89. package/src/config/all.ts +74 -0
  90. package/src/config/builtIn.ts +37 -0
  91. package/src/config/config-resolvers.ts +474 -0
  92. package/src/config/config.ts +332 -0
  93. package/src/config/index.ts +7 -0
  94. package/src/config/load.ts +144 -0
  95. package/src/config/minimal.ts +61 -0
  96. package/src/config/recommended.ts +61 -0
  97. package/src/config/rules.ts +54 -0
  98. package/src/config/types.ts +231 -0
  99. package/src/config/utils.ts +349 -0
  100. package/src/decorators/__tests__/filter-in.test.ts +310 -0
  101. package/src/decorators/__tests__/filter-out.test.ts +335 -0
  102. package/src/decorators/__tests__/media-type-examples-override.test.ts +665 -0
  103. package/src/decorators/__tests__/remove-x-internal.test.ts +316 -0
  104. package/src/decorators/__tests__/resources/request.yaml +3 -0
  105. package/src/decorators/__tests__/resources/response.yaml +3 -0
  106. package/src/decorators/common/filters/filter-helper.ts +72 -0
  107. package/src/decorators/common/filters/filter-in.ts +18 -0
  108. package/src/decorators/common/filters/filter-out.ts +18 -0
  109. package/src/decorators/common/info-description-override.ts +24 -0
  110. package/src/decorators/common/info-override.ts +15 -0
  111. package/src/decorators/common/media-type-examples-override.ts +79 -0
  112. package/src/decorators/common/operation-description-override.ts +30 -0
  113. package/src/decorators/common/registry-dependencies.ts +25 -0
  114. package/src/decorators/common/remove-x-internal.ts +59 -0
  115. package/src/decorators/common/tag-description-override.ts +25 -0
  116. package/src/decorators/oas2/index.ts +20 -0
  117. package/src/decorators/oas3/index.ts +22 -0
  118. package/src/env.ts +5 -0
  119. package/src/format/codeframes.ts +216 -0
  120. package/src/format/format.ts +375 -0
  121. package/src/index.ts +71 -0
  122. package/src/js-yaml/index.ts +14 -0
  123. package/src/lint.ts +148 -0
  124. package/src/logger.ts +34 -0
  125. package/src/oas-types.ts +57 -0
  126. package/src/output.ts +7 -0
  127. package/src/redocly/__tests__/redocly-client.test.ts +146 -0
  128. package/src/redocly/index.ts +187 -0
  129. package/src/redocly/redocly-client-types.ts +10 -0
  130. package/src/redocly/registry-api-types.ts +32 -0
  131. package/src/redocly/registry-api.ts +150 -0
  132. package/src/ref-utils.ts +85 -0
  133. package/src/resolve.ts +417 -0
  134. package/src/rules/__tests__/fixtures/code-sample.php +9 -0
  135. package/src/rules/__tests__/fixtures/invalid-yaml.yaml +1 -0
  136. package/src/rules/__tests__/fixtures/ref.yaml +1 -0
  137. package/src/rules/__tests__/no-unresolved-refs.test.ts +257 -0
  138. package/src/rules/__tests__/utils.test.ts +160 -0
  139. package/src/rules/ajv.ts +102 -0
  140. package/src/rules/common/__tests__/info-license.test.ts +62 -0
  141. package/src/rules/common/__tests__/license-url.test.ts +63 -0
  142. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +96 -0
  143. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +210 -0
  144. package/src/rules/common/__tests__/no-identical-paths.test.ts +58 -0
  145. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +85 -0
  146. package/src/rules/common/__tests__/operation-2xx-response.test.ts +192 -0
  147. package/src/rules/common/__tests__/operation-4xx-response.test.ts +231 -0
  148. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +76 -0
  149. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +45 -0
  150. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +167 -0
  151. package/src/rules/common/__tests__/operation-singular-tag.test.ts +72 -0
  152. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +95 -0
  153. package/src/rules/common/__tests__/path-not-include-query.test.ts +64 -0
  154. package/src/rules/common/__tests__/path-params-defined.test.ts +202 -0
  155. package/src/rules/common/__tests__/paths-kebab-case.test.ts +108 -0
  156. package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +264 -0
  157. package/src/rules/common/__tests__/security-defined.test.ts +175 -0
  158. package/src/rules/common/__tests__/spec-strict-refs.test.ts +69 -0
  159. package/src/rules/common/__tests__/spec.test.ts +610 -0
  160. package/src/rules/common/__tests__/tag-description.test.ts +65 -0
  161. package/src/rules/common/__tests__/tags-alphabetical.test.ts +64 -0
  162. package/src/rules/common/assertions/__tests__/asserts.test.ts +869 -0
  163. package/src/rules/common/assertions/__tests__/index.test.ts +100 -0
  164. package/src/rules/common/assertions/__tests__/utils.test.ts +236 -0
  165. package/src/rules/common/assertions/asserts.ts +357 -0
  166. package/src/rules/common/assertions/index.ts +53 -0
  167. package/src/rules/common/assertions/utils.ts +331 -0
  168. package/src/rules/common/info-contact.ts +15 -0
  169. package/src/rules/common/info-license-url.ts +10 -0
  170. package/src/rules/common/info-license.ts +15 -0
  171. package/src/rules/common/no-ambiguous-paths.ts +50 -0
  172. package/src/rules/common/no-enum-type-mismatch.ts +52 -0
  173. package/src/rules/common/no-http-verbs-in-paths.ts +36 -0
  174. package/src/rules/common/no-identical-paths.ts +24 -0
  175. package/src/rules/common/no-invalid-parameter-examples.ts +36 -0
  176. package/src/rules/common/no-invalid-schema-examples.ts +27 -0
  177. package/src/rules/common/no-path-trailing-slash.ts +15 -0
  178. package/src/rules/common/operation-2xx-response.ts +24 -0
  179. package/src/rules/common/operation-4xx-response.ts +24 -0
  180. package/src/rules/common/operation-description.ts +13 -0
  181. package/src/rules/common/operation-operationId-unique.ts +21 -0
  182. package/src/rules/common/operation-operationId-url-safe.ts +19 -0
  183. package/src/rules/common/operation-operationId.ts +17 -0
  184. package/src/rules/common/operation-parameters-unique.ts +48 -0
  185. package/src/rules/common/operation-singular-tag.ts +17 -0
  186. package/src/rules/common/operation-summary.ts +13 -0
  187. package/src/rules/common/operation-tag-defined.ts +26 -0
  188. package/src/rules/common/parameter-description.ts +22 -0
  189. package/src/rules/common/path-declaration-must-exist.ts +15 -0
  190. package/src/rules/common/path-excludes-patterns.ts +23 -0
  191. package/src/rules/common/path-http-verbs-order.ts +30 -0
  192. package/src/rules/common/path-not-include-query.ts +17 -0
  193. package/src/rules/common/path-params-defined.ts +65 -0
  194. package/src/rules/common/path-segment-plural.ts +31 -0
  195. package/src/rules/common/paths-kebab-case.ts +19 -0
  196. package/src/rules/common/required-string-property-missing-min-length.ts +44 -0
  197. package/src/rules/common/response-contains-header.ts +35 -0
  198. package/src/rules/common/scalar-property-missing-example.ts +58 -0
  199. package/src/rules/common/security-defined.ts +65 -0
  200. package/src/rules/common/spec-strict-refs.ts +30 -0
  201. package/src/rules/common/spec.ts +175 -0
  202. package/src/rules/common/tag-description.ts +10 -0
  203. package/src/rules/common/tags-alphabetical.ts +20 -0
  204. package/src/rules/no-unresolved-refs.ts +51 -0
  205. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +110 -0
  206. package/src/rules/oas2/__tests__/response-contains-header.test.ts +174 -0
  207. package/src/rules/oas2/__tests__/response-contains-property.test.ts +155 -0
  208. package/src/rules/oas2/__tests__/spec/fixtures/description.md +1 -0
  209. package/src/rules/oas2/__tests__/spec/info.test.ts +355 -0
  210. package/src/rules/oas2/__tests__/spec/operation.test.ts +123 -0
  211. package/src/rules/oas2/__tests__/spec/paths.test.ts +245 -0
  212. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +35 -0
  213. package/src/rules/oas2/__tests__/spec/utils.ts +32 -0
  214. package/src/rules/oas2/boolean-parameter-prefixes.ts +26 -0
  215. package/src/rules/oas2/index.ts +91 -0
  216. package/src/rules/oas2/remove-unused-components.ts +81 -0
  217. package/src/rules/oas2/request-mime-type.ts +16 -0
  218. package/src/rules/oas2/response-contains-property.ts +36 -0
  219. package/src/rules/oas2/response-mime-type.ts +16 -0
  220. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +111 -0
  221. package/src/rules/oas3/__tests__/component-name-unique.test.ts +823 -0
  222. package/src/rules/oas3/__tests__/fixtures/common.yaml +11 -0
  223. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +205 -0
  224. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +65 -0
  225. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +473 -0
  226. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +60 -0
  227. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +79 -0
  228. package/src/rules/oas3/__tests__/no-unused-components.test.ts +131 -0
  229. package/src/rules/oas3/__tests__/operation-4xx-problem-details-rfc7807.test.ts +145 -0
  230. package/src/rules/oas3/__tests__/response-contains-header.test.ts +389 -0
  231. package/src/rules/oas3/__tests__/response-contains-property.test.ts +403 -0
  232. package/src/rules/oas3/__tests__/spec/callbacks.test.ts +41 -0
  233. package/src/rules/oas3/__tests__/spec/fixtures/description.md +1 -0
  234. package/src/rules/oas3/__tests__/spec/info.test.ts +391 -0
  235. package/src/rules/oas3/__tests__/spec/operation.test.ts +253 -0
  236. package/src/rules/oas3/__tests__/spec/paths.test.ts +284 -0
  237. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +77 -0
  238. package/src/rules/oas3/__tests__/spec/servers.test.ts +505 -0
  239. package/src/rules/oas3/__tests__/spec/spec.test.ts +298 -0
  240. package/src/rules/oas3/__tests__/spec/utils.ts +32 -0
  241. package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +276 -0
  242. package/src/rules/oas3/__tests__/utils/lint-document-for-test.ts +23 -0
  243. package/src/rules/oas3/boolean-parameter-prefixes.ts +28 -0
  244. package/src/rules/oas3/component-name-unique.ts +158 -0
  245. package/src/rules/oas3/index.ts +113 -0
  246. package/src/rules/oas3/no-empty-servers.ts +22 -0
  247. package/src/rules/oas3/no-example-value-and-externalValue.ts +14 -0
  248. package/src/rules/oas3/no-invalid-media-type-examples.ts +49 -0
  249. package/src/rules/oas3/no-server-example.com.ts +14 -0
  250. package/src/rules/oas3/no-server-trailing-slash.ts +15 -0
  251. package/src/rules/oas3/no-server-variables-empty-enum.ts +66 -0
  252. package/src/rules/oas3/no-undefined-server-variable.ts +30 -0
  253. package/src/rules/oas3/no-unused-components.ts +75 -0
  254. package/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +35 -0
  255. package/src/rules/oas3/remove-unused-components.ts +95 -0
  256. package/src/rules/oas3/request-mime-type.ts +30 -0
  257. package/src/rules/oas3/response-contains-property.ts +38 -0
  258. package/src/rules/oas3/response-mime-type.ts +30 -0
  259. package/src/rules/oas3/spec-components-invalid-map-name.ts +69 -0
  260. package/src/rules/other/stats.ts +73 -0
  261. package/src/rules/utils.ts +193 -0
  262. package/src/types/config-external-schemas.ts +917 -0
  263. package/src/types/index.ts +149 -0
  264. package/src/types/oas2.ts +478 -0
  265. package/src/types/oas3.ts +597 -0
  266. package/src/types/oas3_1.ts +258 -0
  267. package/src/types/redocly-yaml.ts +1040 -0
  268. package/src/typings/common.ts +17 -0
  269. package/src/typings/openapi.ts +298 -0
  270. package/src/typings/swagger.ts +236 -0
  271. package/src/utils.ts +276 -0
  272. package/src/visitors.ts +491 -0
  273. package/src/walk.ts +439 -0
  274. package/tsconfig.json +8 -0
  275. package/tsconfig.tsbuildinfo +1 -0
@@ -0,0 +1,167 @@
1
+ import { loadConfig, findConfig, getConfig, createConfig } from '../load';
2
+ import { RedoclyClient } from '../../redocly';
3
+ import { RuleConfig, FlatRawConfig } from './../types';
4
+ import { Config } from '../config';
5
+
6
+ const fs = require('fs');
7
+ const path = require('path');
8
+
9
+ describe('loadConfig', () => {
10
+ it('should resolve config http header by US region', async () => {
11
+ jest
12
+ .spyOn(RedoclyClient.prototype, 'getTokens')
13
+ .mockImplementation(() =>
14
+ Promise.resolve([{ region: 'us', token: 'accessToken', valid: true }])
15
+ );
16
+ const config = await loadConfig();
17
+ expect(config.resolve.http.headers).toStrictEqual([
18
+ {
19
+ matches: 'https://api.redocly.com/registry/**',
20
+ name: 'Authorization',
21
+ envVariable: undefined,
22
+ value: 'accessToken',
23
+ },
24
+ {
25
+ matches: 'https://api.redoc.ly/registry/**',
26
+ name: 'Authorization',
27
+ envVariable: undefined,
28
+ value: 'accessToken',
29
+ },
30
+ ]);
31
+ });
32
+
33
+ it('should resolve config http header by EU region', async () => {
34
+ jest
35
+ .spyOn(RedoclyClient.prototype, 'getTokens')
36
+ .mockImplementation(() =>
37
+ Promise.resolve([{ region: 'eu', token: 'accessToken', valid: true }])
38
+ );
39
+ const config = await loadConfig();
40
+ expect(config.resolve.http.headers).toStrictEqual([
41
+ {
42
+ matches: 'https://api.eu.redocly.com/registry/**',
43
+ name: 'Authorization',
44
+ envVariable: undefined,
45
+ value: 'accessToken',
46
+ },
47
+ ]);
48
+ });
49
+
50
+ it('should call callback if such passed', async () => {
51
+ const mockFn = jest.fn();
52
+ await loadConfig({
53
+ configPath: path.join(__dirname, './fixtures/load-redocly.yaml'),
54
+ processRawConfig: mockFn,
55
+ });
56
+ expect(mockFn).toHaveBeenCalled();
57
+ });
58
+ });
59
+
60
+ describe('findConfig', () => {
61
+ it('should find redocly.yaml', async () => {
62
+ jest.spyOn(fs, 'existsSync').mockImplementation((name) => name === 'redocly.yaml');
63
+ const configName = findConfig();
64
+ expect(configName).toStrictEqual('redocly.yaml');
65
+ });
66
+ it('should find .redocly.yaml', async () => {
67
+ jest.spyOn(fs, 'existsSync').mockImplementation((name) => name === '.redocly.yaml');
68
+ const configName = findConfig();
69
+ expect(configName).toStrictEqual('.redocly.yaml');
70
+ });
71
+ it('should throw an error when found multiple config files', async () => {
72
+ jest
73
+ .spyOn(fs, 'existsSync')
74
+ .mockImplementation((name) => name === 'redocly.yaml' || name === '.redocly.yaml');
75
+ expect(findConfig).toThrow(`
76
+ Multiple configuration files are not allowed.
77
+ Found the following files: redocly.yaml, .redocly.yaml.
78
+ Please use 'redocly.yaml' instead.
79
+ `);
80
+ });
81
+ it('should find a nested config ', async () => {
82
+ jest.spyOn(fs, 'existsSync').mockImplementation((name) => name === 'dir/redocly.yaml');
83
+ jest.spyOn(path, 'resolve').mockImplementationOnce((dir, name) => `${dir}/${name}`);
84
+ const configName = findConfig('dir');
85
+ expect(configName).toStrictEqual('dir/redocly.yaml');
86
+ });
87
+ });
88
+
89
+ describe('getConfig', () => {
90
+ jest.spyOn(fs, 'hasOwnProperty').mockImplementation(() => false);
91
+ it('should return empty object if there is no configPath and config file is not found', () => {
92
+ expect(getConfig()).toEqual(Promise.resolve({}));
93
+ });
94
+ });
95
+
96
+ describe('createConfig', () => {
97
+ it('should create config from string', async () => {
98
+ const config = await createConfig(`
99
+ extends:
100
+ - recommended
101
+ rules:
102
+ info-license: off
103
+ `);
104
+
105
+ verifyExtendedConfig(config, {
106
+ extendsRuleSet: 'recommended',
107
+ overridesRules: { 'info-license': 'off' },
108
+ });
109
+ });
110
+
111
+ it('should create config from object', async () => {
112
+ const rawConfig: FlatRawConfig = {
113
+ extends: ['minimal'],
114
+ rules: {
115
+ 'info-license': 'off',
116
+ 'tag-description': 'off',
117
+ 'operation-2xx-response': 'off',
118
+ },
119
+ };
120
+ const config = await createConfig(rawConfig);
121
+
122
+ verifyExtendedConfig(config, {
123
+ extendsRuleSet: 'minimal',
124
+ overridesRules: rawConfig.rules as Record<string, RuleConfig>,
125
+ });
126
+ });
127
+ });
128
+
129
+ function verifyExtendedConfig(
130
+ config: Config,
131
+ {
132
+ extendsRuleSet,
133
+ overridesRules,
134
+ }: { extendsRuleSet: string; overridesRules: Record<string, RuleConfig> }
135
+ ) {
136
+ const defaultPlugin = config.styleguide.plugins.find((plugin) => plugin.id === '');
137
+ expect(defaultPlugin).toBeDefined();
138
+
139
+ const recommendedRules = defaultPlugin?.configs?.[extendsRuleSet];
140
+ expect(recommendedRules).toBeDefined();
141
+
142
+ verifyOasRules(config.styleguide.rules.oas2, overridesRules, recommendedRules?.rules || {});
143
+ verifyOasRules(
144
+ config.styleguide.rules.oas3_0,
145
+ overridesRules,
146
+ Object.assign({}, recommendedRules?.rules, recommendedRules?.oas3_0Rules)
147
+ );
148
+ verifyOasRules(
149
+ config.styleguide.rules.oas3_1,
150
+ overridesRules,
151
+ Object.assign({}, recommendedRules?.rules, recommendedRules?.oas3_1Rules)
152
+ );
153
+ }
154
+
155
+ function verifyOasRules(
156
+ finalRuleset: Record<string, RuleConfig>,
157
+ overridesRules: Record<string, RuleConfig>,
158
+ defaultRuleset: Record<string, RuleConfig>
159
+ ) {
160
+ Object.entries(finalRuleset).forEach(([ruleName, ruleValue]) => {
161
+ if (ruleName in overridesRules) {
162
+ expect(ruleValue).toBe(overridesRules[ruleName]);
163
+ } else {
164
+ expect(ruleValue).toBe(defaultRuleset[ruleName]);
165
+ }
166
+ });
167
+ }
@@ -0,0 +1,27 @@
1
+ import * as path from 'path';
2
+ import { loadConfig } from '../load';
3
+
4
+ describe('resolving a plugin', () => {
5
+ const configPath = path.join(__dirname, 'fixtures/plugin-config.yaml');
6
+
7
+ it('should prefix rule names with the plugin id', async () => {
8
+ const config = await loadConfig({ configPath });
9
+ const plugin = config.styleguide.plugins[0];
10
+
11
+ expect(plugin.rules?.oas3).toHaveProperty('test-plugin/openid-connect-url-well-known');
12
+ });
13
+
14
+ it('should prefix preprocessor names with the plugin id', async () => {
15
+ const config = await loadConfig({ configPath });
16
+ const plugin = config.styleguide.plugins[0];
17
+
18
+ expect(plugin.preprocessors?.oas2).toHaveProperty('test-plugin/description-preprocessor');
19
+ });
20
+
21
+ it('should prefix decorator names with the plugin id', async () => {
22
+ const config = await loadConfig({ configPath });
23
+ const plugin = config.styleguide.plugins[0];
24
+
25
+ expect(plugin.decorators?.oas3).toHaveProperty('test-plugin/inject-x-stats');
26
+ });
27
+ });
@@ -0,0 +1,204 @@
1
+ import type { DeprecatedInRawConfig, RawConfig, FlatRawConfig } from '../types';
2
+ import * as utils from '../utils';
3
+
4
+ const makeTestRawConfig = (
5
+ apiStyleguideName: string,
6
+ rootStyleguideName: string
7
+ ): RawConfig & DeprecatedInRawConfig => ({
8
+ apis: {
9
+ 'test@v1': {
10
+ root: 'root.yaml',
11
+ [apiStyleguideName]: {
12
+ rules: {
13
+ 'operation-2xx-response': 'error',
14
+ },
15
+ },
16
+ },
17
+ },
18
+ [rootStyleguideName]: {
19
+ rules: {
20
+ 'operation-4xx-response': 'warn',
21
+ },
22
+ },
23
+ });
24
+
25
+ const rawTestConfig: RawConfig = {
26
+ apis: {
27
+ 'test@v1': {
28
+ root: 'root.yaml',
29
+ styleguide: {
30
+ extends: ['recommended'],
31
+ rules: { 'operation-2xx-response': 'error' },
32
+ },
33
+ },
34
+ },
35
+ styleguide: {
36
+ plugins: ['test-plugin'],
37
+ extends: ['minimal'],
38
+ rules: { 'operation-4xx-response': 'warn' },
39
+ doNotResolveExamples: true,
40
+ },
41
+ resolve: {
42
+ http: { headers: [{ matches: '*', name: 'all', envVariable: 'all' }] },
43
+ },
44
+ theme: {
45
+ openapi: {
46
+ disableSidebar: true,
47
+ },
48
+ },
49
+ };
50
+
51
+ const flatTestConfig: FlatRawConfig = {
52
+ apis: {
53
+ 'test@v1': {
54
+ root: 'root.yaml',
55
+ extends: ['recommended'],
56
+ rules: { 'operation-2xx-response': 'error' },
57
+ },
58
+ },
59
+ plugins: ['test-plugin'],
60
+ extends: ['minimal'],
61
+ rules: {
62
+ 'operation-4xx-response': 'warn',
63
+ },
64
+ resolve: {
65
+ http: { headers: [{ matches: '*', name: 'all', envVariable: 'all' }] },
66
+ doNotResolveExamples: true,
67
+ },
68
+ theme: {
69
+ openapi: {
70
+ disableSidebar: true,
71
+ },
72
+ },
73
+ };
74
+
75
+ describe('transformConfig', () => {
76
+ it('should work for the `styleguide` syntax', () => {
77
+ const transformedRawConfig: RawConfig = utils.transformConfig(
78
+ makeTestRawConfig('styleguide', 'styleguide')
79
+ );
80
+ expect(transformedRawConfig).toMatchInlineSnapshot(`
81
+ Object {
82
+ "apis": Object {
83
+ "test@v1": Object {
84
+ "root": "root.yaml",
85
+ "styleguide": Object {
86
+ "rules": Object {
87
+ "operation-2xx-response": "error",
88
+ },
89
+ },
90
+ },
91
+ },
92
+ "styleguide": Object {
93
+ "rules": Object {
94
+ "operation-4xx-response": "warn",
95
+ },
96
+ },
97
+ "theme": Object {
98
+ "mockServer": Object {},
99
+ "openapi": Object {},
100
+ },
101
+ }
102
+ `);
103
+ });
104
+ it('should be equal for both `lint` and `styleguide` names', () => {
105
+ expect(utils.transformConfig(makeTestRawConfig('lint', 'styleguide'))).toEqual(
106
+ utils.transformConfig(makeTestRawConfig('styleguide', 'lint'))
107
+ );
108
+ });
109
+ it('should work for `apiDefinitions`', () => {
110
+ const testRawConfig = makeTestRawConfig('styleguide', 'lint');
111
+ testRawConfig.apis = undefined;
112
+ testRawConfig.apiDefinitions = { legacyApiDefinition: 'file.yaml' };
113
+ expect(utils.transformConfig(testRawConfig)).toMatchInlineSnapshot(`
114
+ Object {
115
+ "apis": Object {
116
+ "legacyApiDefinition": Object {
117
+ "root": "file.yaml",
118
+ },
119
+ },
120
+ "styleguide": Object {
121
+ "rules": Object {
122
+ "operation-4xx-response": "warn",
123
+ },
124
+ },
125
+ "theme": Object {
126
+ "mockServer": Object {},
127
+ "openapi": Object {},
128
+ },
129
+ }
130
+ `);
131
+ });
132
+ it('should throw an error if both `styleguide` and `lint` syntaxes used together', () => {
133
+ const testRawConfig = makeTestRawConfig('styleguide', 'lint');
134
+ testRawConfig.apiDefinitions = { legacyApiDefinition: 'file.yaml' };
135
+ expect(() => utils.transformConfig(testRawConfig)).toThrowError(
136
+ `Do not use 'apiDefinitions' field. Use 'apis' instead. `
137
+ );
138
+ });
139
+ it('should transform flatten config into styleguide', () => {
140
+ expect(utils.transformConfig(flatTestConfig)).toEqual({
141
+ ...rawTestConfig,
142
+ resolve: { ...rawTestConfig.resolve, doNotResolveExamples: true },
143
+ });
144
+ });
145
+ it('should transform styleguide config into styleguide identically', () => {
146
+ expect(utils.transformConfig(rawTestConfig)).toEqual(rawTestConfig);
147
+ });
148
+ it('should fail when there is a mixed config', () => {
149
+ expect(() => utils.transformConfig({ ...rawTestConfig, extends: ['recommended'] })).toThrow(
150
+ `Do not use 'lint', 'styleguide' and flat syntax together. \nSee more about the configuration in the docs: https://redocly.com/docs/cli/configuration/ \n`
151
+ );
152
+ });
153
+ it('should throw an error if both `features.openapi` and `theme` syntaxes used together', () => {
154
+ const testRawConfig: RawConfig & DeprecatedInRawConfig = {
155
+ apis: {
156
+ 'test@v1': {
157
+ root: 'root.yaml',
158
+ styleguide: {
159
+ extends: ['recommended'],
160
+ rules: { 'operation-2xx-response': 'error' },
161
+ },
162
+ },
163
+ },
164
+ 'features.openapi': {
165
+ disableSidebar: true,
166
+ },
167
+ theme: {
168
+ openapi: {
169
+ disableSidebar: true,
170
+ },
171
+ },
172
+ };
173
+ expect(() => utils.transformConfig(testRawConfig)).toThrowError(
174
+ `Do not use 'features.openapi' field. Use 'theme.openapi' instead. `
175
+ );
176
+ });
177
+ it('should transform referenceDocs config into theme.openapi', () => {
178
+ const testRawConfig: RawConfig & DeprecatedInRawConfig = {
179
+ referenceDocs: {
180
+ disableSidebar: true,
181
+ },
182
+ };
183
+ expect(utils.transformConfig(testRawConfig)).toEqual({
184
+ apis: undefined,
185
+ styleguide: undefined,
186
+ theme: { mockServer: {}, openapi: { disableSidebar: true } },
187
+ });
188
+ });
189
+ it('should transform "features.openapi" config into theme.openapi', () => {
190
+ const testRawConfig: RawConfig & DeprecatedInRawConfig = {
191
+ 'features.openapi': {
192
+ disableSidebar: true,
193
+ },
194
+ };
195
+ expect(utils.transformConfig(testRawConfig)).toEqual({
196
+ apis: undefined,
197
+ 'features.openapi': {
198
+ disableSidebar: true,
199
+ },
200
+ styleguide: undefined,
201
+ theme: { mockServer: {}, openapi: { disableSidebar: true } },
202
+ });
203
+ });
204
+ });
@@ -0,0 +1,74 @@
1
+ import type { PluginStyleguideConfig } from './types';
2
+
3
+ export default {
4
+ rules: {
5
+ 'info-contact': 'error',
6
+ 'info-license': 'error',
7
+ 'info-license-url': 'error',
8
+ 'tag-description': 'error',
9
+ 'tags-alphabetical': 'error',
10
+ 'parameter-description': 'error',
11
+ 'no-identical-paths': 'error',
12
+ 'no-ambiguous-paths': 'error',
13
+ 'no-path-trailing-slash': 'error',
14
+ 'path-segment-plural': 'error',
15
+ 'path-declaration-must-exist': 'error',
16
+ 'path-not-include-query': 'error',
17
+ 'path-parameters-defined': 'error',
18
+ 'operation-description': 'error',
19
+ 'operation-2xx-response': 'error',
20
+ 'operation-4xx-response': 'error',
21
+ 'operation-operationId': 'error',
22
+ 'operation-summary': 'error',
23
+ 'operation-operationId-unique': 'error',
24
+ 'operation-operationId-url-safe': 'error',
25
+ 'operation-parameters-unique': 'error',
26
+ 'operation-tag-defined': 'error',
27
+ 'security-defined': 'error',
28
+ 'operation-singular-tag': 'error',
29
+ 'no-unresolved-refs': 'error',
30
+ 'no-enum-type-mismatch': 'error',
31
+ 'boolean-parameter-prefixes': 'error',
32
+ 'paths-kebab-case': 'error',
33
+ 'no-http-verbs-in-paths': 'error',
34
+ 'path-excludes-patterns': {
35
+ severity: 'error',
36
+ patterns: [],
37
+ },
38
+ 'request-mime-type': {
39
+ severity: 'error',
40
+ allowedValues: ['application/json'],
41
+ },
42
+ 'response-mime-type': {
43
+ severity: 'error',
44
+ allowedValues: ['application/json'],
45
+ },
46
+ spec: 'error',
47
+ 'no-invalid-schema-examples': 'error',
48
+ 'no-invalid-parameter-examples': 'error',
49
+ 'scalar-property-missing-example': 'error',
50
+ 'spec-strict-refs': 'error',
51
+ 'component-name-unique': 'error',
52
+ },
53
+ oas3_0Rules: {
54
+ 'no-invalid-media-type-examples': 'error',
55
+ 'no-server-example.com': 'error',
56
+ 'no-server-trailing-slash': 'error',
57
+ 'no-empty-servers': 'error',
58
+ 'no-example-value-and-externalValue': 'error',
59
+ 'no-unused-components': 'error',
60
+ 'no-undefined-server-variable': 'error',
61
+ 'no-server-variables-empty-enum': 'error',
62
+ 'operation-4xx-problem-details-rfc7807': 'error',
63
+ },
64
+ oas3_1Rules: {
65
+ 'no-server-example.com': 'error',
66
+ 'no-server-trailing-slash': 'error',
67
+ 'no-empty-servers': 'error',
68
+ 'no-example-value-and-externalValue': 'error',
69
+ 'no-unused-components': 'error',
70
+ 'no-undefined-server-variable': 'error',
71
+ 'no-server-variables-empty-enum': 'error',
72
+ 'operation-4xx-problem-details-rfc7807': 'error',
73
+ },
74
+ } as PluginStyleguideConfig;
@@ -0,0 +1,37 @@
1
+ import recommended from './recommended';
2
+ import all from './all';
3
+ import minimal from './minimal';
4
+ import { rules as oas3Rules } from '../rules/oas3';
5
+ import { rules as oas2Rules } from '../rules/oas2';
6
+ import { preprocessors as oas3Preprocessors } from '../rules/oas3';
7
+ import { preprocessors as oas2Preprocessors } from '../rules/oas2';
8
+ import { decorators as oas3Decorators } from '../decorators/oas3';
9
+ import { decorators as oas2Decorators } from '../decorators/oas2';
10
+
11
+ import type { CustomRulesConfig, StyleguideRawConfig, Plugin } from './types';
12
+
13
+ export const builtInConfigs: Record<string, StyleguideRawConfig> = {
14
+ recommended,
15
+ minimal,
16
+ all,
17
+ 'redocly-registry': {
18
+ decorators: { 'registry-dependencies': 'on' },
19
+ },
20
+ };
21
+
22
+ export const defaultPlugin: Plugin = {
23
+ id: '', // default plugin doesn't have id
24
+ rules: {
25
+ oas3: oas3Rules,
26
+ oas2: oas2Rules,
27
+ } as CustomRulesConfig,
28
+ preprocessors: {
29
+ oas3: oas3Preprocessors,
30
+ oas2: oas2Preprocessors,
31
+ },
32
+ decorators: {
33
+ oas3: oas3Decorators,
34
+ oas2: oas2Decorators,
35
+ },
36
+ configs: builtInConfigs,
37
+ };