@redocly/openapi-core 1.0.0-beta.93 → 1.0.0-beta.96

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 (127) hide show
  1. package/README.md +1 -1
  2. package/__tests__/bundle.test.ts +6 -6
  3. package/__tests__/fixtures/extension.js +1 -1
  4. package/__tests__/login.test.ts +2 -2
  5. package/__tests__/normalizeVisitors.test.ts +1 -1
  6. package/__tests__/ref-utils.test.ts +1 -1
  7. package/__tests__/utils.ts +30 -18
  8. package/__tests__/walk.test.ts +6 -6
  9. package/lib/benchmark/benches/recommended-oas3.bench.js +2 -3
  10. package/lib/benchmark/utils.d.ts +2 -1
  11. package/lib/benchmark/utils.js +10 -7
  12. package/lib/bundle.d.ts +2 -2
  13. package/lib/config/all.d.ts +2 -2
  14. package/lib/config/builtIn.d.ts +1 -1
  15. package/lib/config/config-resolvers.d.ts +16 -0
  16. package/lib/config/config-resolvers.js +213 -0
  17. package/lib/config/config.d.ts +14 -129
  18. package/lib/config/config.js +17 -234
  19. package/lib/config/index.d.ts +7 -0
  20. package/lib/config/index.js +19 -0
  21. package/lib/config/load.d.ts +2 -1
  22. package/lib/config/load.js +20 -13
  23. package/lib/config/minimal.d.ts +2 -2
  24. package/lib/config/recommended.d.ts +2 -2
  25. package/lib/config/types.d.ts +113 -0
  26. package/lib/config/types.js +2 -0
  27. package/lib/config/utils.d.ts +13 -0
  28. package/lib/config/utils.js +160 -0
  29. package/lib/format/format.d.ts +1 -1
  30. package/lib/format/format.js +28 -0
  31. package/lib/index.d.ts +1 -2
  32. package/lib/index.js +5 -6
  33. package/lib/lint.d.ts +1 -1
  34. package/lib/lint.js +5 -7
  35. package/lib/redocly/index.d.ts +1 -1
  36. package/lib/redocly/index.js +1 -1
  37. package/lib/redocly/redocly-client-types.d.ts +1 -1
  38. package/lib/redocly/registry-api.d.ts +1 -1
  39. package/lib/resolve.d.ts +1 -1
  40. package/lib/resolve.js +1 -2
  41. package/lib/rules/common/assertions/index.js +1 -1
  42. package/lib/rules/common/assertions/utils.d.ts +1 -1
  43. package/lib/rules/common/assertions/utils.js +6 -2
  44. package/lib/types/index.js +2 -2
  45. package/lib/types/oas3_1.js +31 -5
  46. package/lib/utils.d.ts +4 -1
  47. package/lib/utils.js +18 -1
  48. package/package.json +7 -4
  49. package/src/__tests__/lint.test.ts +1 -1
  50. package/src/benchmark/benches/recommended-oas3.bench.ts +2 -3
  51. package/src/benchmark/benchmark.js +1 -1
  52. package/src/benchmark/utils.ts +13 -8
  53. package/src/bundle.ts +2 -1
  54. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +140 -0
  55. package/src/config/__tests__/config-resolvers.test.ts +398 -0
  56. package/src/config/__tests__/config.test.ts +244 -0
  57. package/src/config/__tests__/fixtures/plugin.js +1 -1
  58. package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +7 -0
  59. package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +67 -0
  60. package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +8 -0
  61. package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +12 -0
  62. package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +10 -0
  63. package/src/config/__tests__/fixtures/resolve-config/plugin.js +66 -0
  64. package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +4 -0
  65. package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +5 -0
  66. package/src/config/__tests__/load.test.ts +8 -1
  67. package/src/config/all.ts +3 -2
  68. package/src/config/builtIn.ts +2 -1
  69. package/src/config/config-resolvers.ts +304 -0
  70. package/src/config/config.ts +40 -457
  71. package/src/config/index.ts +7 -0
  72. package/src/config/load.ts +37 -31
  73. package/src/config/minimal.ts +2 -2
  74. package/src/config/recommended.ts +2 -2
  75. package/src/config/types.ts +168 -0
  76. package/src/config/utils.ts +208 -0
  77. package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
  78. package/src/format/format.ts +36 -6
  79. package/src/index.ts +6 -2
  80. package/src/lint.ts +4 -5
  81. package/src/redocly/__tests__/redocly-client.test.ts +7 -0
  82. package/src/redocly/index.ts +4 -2
  83. package/src/redocly/redocly-client-types.ts +1 -1
  84. package/src/redocly/registry-api.ts +3 -1
  85. package/src/resolve.ts +2 -4
  86. package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
  87. package/src/rules/common/__tests__/info-description.test.ts +3 -3
  88. package/src/rules/common/__tests__/info-license.test.ts +2 -2
  89. package/src/rules/common/__tests__/license-url.test.ts +2 -2
  90. package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
  91. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +5 -5
  92. package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
  93. package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
  94. package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
  95. package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
  96. package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
  97. package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
  98. package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
  99. package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
  100. package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
  101. package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
  102. package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
  103. package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
  104. package/src/rules/common/__tests__/paths-kebab-case.test.ts +3 -3
  105. package/src/rules/common/__tests__/spec.test.ts +1 -1
  106. package/src/rules/common/__tests__/tag-description.test.ts +2 -2
  107. package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
  108. package/src/rules/common/assertions/index.ts +1 -1
  109. package/src/rules/common/assertions/utils.ts +5 -2
  110. package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  111. package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +1 -1
  112. package/src/rules/oas2/__tests__/spec/utils.ts +10 -7
  113. package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
  114. package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +6 -6
  115. package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
  116. package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
  117. package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
  118. package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
  119. package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
  120. package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +23 -14
  121. package/src/rules/oas3/__tests__/spec/servers.test.ts +1 -1
  122. package/src/rules/oas3/__tests__/spec/spec.test.ts +4 -4
  123. package/src/rules/oas3/__tests__/spec/utils.ts +10 -7
  124. package/src/types/index.ts +2 -2
  125. package/src/types/oas3_1.ts +32 -7
  126. package/src/utils.ts +18 -2
  127. package/tsconfig.tsbuildinfo +1 -1
@@ -0,0 +1,398 @@
1
+ import { resolveLint, resolveApis, resolveConfig } from '../config-resolvers';
2
+ const path = require('path');
3
+
4
+ import type { LintRawConfig, RawConfig } from '../types';
5
+
6
+ const configPath = path.join(__dirname, 'fixtures/resolve-config/.redocly.yaml');
7
+ const baseLintConfig: LintRawConfig = {
8
+ rules: {
9
+ 'operation-2xx-response': 'warn',
10
+ },
11
+ };
12
+
13
+ const minimalLintPreset = resolveLint({
14
+ lintConfig: { ...baseLintConfig, extends: ['minimal'] },
15
+ });
16
+
17
+ const recommendedLintPreset = resolveLint({
18
+ lintConfig: { ...baseLintConfig, extends: ['recommended'] },
19
+ });
20
+
21
+ const removeAbsolutePath = (item: string) =>
22
+ item.match(/^.*\/packages\/core\/src\/config\/__tests__\/fixtures\/(.*)$/)![1];
23
+
24
+ describe('resolveLint', () => {
25
+ it('should return the config with no recommended', async () => {
26
+ const lint = await resolveLint({ lintConfig: baseLintConfig });
27
+ expect(lint.plugins?.length).toEqual(1);
28
+ expect(lint.plugins?.[0].id).toEqual('');
29
+ expect(lint.rules).toEqual({
30
+ 'operation-2xx-response': 'warn',
31
+ });
32
+ });
33
+
34
+ it('should return the config with correct order by preset', async () => {
35
+ expect(
36
+ await resolveLint({
37
+ lintConfig: { ...baseLintConfig, extends: ['minimal', 'recommended'] },
38
+ }),
39
+ ).toEqual(await recommendedLintPreset);
40
+ expect(
41
+ await resolveLint({
42
+ lintConfig: { ...baseLintConfig, extends: ['recommended', 'minimal'] },
43
+ }),
44
+ ).toEqual(await minimalLintPreset);
45
+ });
46
+
47
+ it('should return the same lintConfig when extends is empty array', async () => {
48
+ const configWithEmptyExtends = await resolveLint({
49
+ lintConfig: { ...baseLintConfig, extends: [] },
50
+ });
51
+ expect(configWithEmptyExtends.plugins?.length).toEqual(1);
52
+ expect(configWithEmptyExtends.plugins?.[0].id).toEqual('');
53
+ expect(configWithEmptyExtends.rules).toEqual({
54
+ 'operation-2xx-response': 'warn',
55
+ });
56
+ });
57
+
58
+ it('should resolve extends with local file config', async () => {
59
+ const config = {
60
+ ...baseLintConfig,
61
+ extends: ['local-config.yaml'],
62
+ };
63
+
64
+ const { plugins, ...lint } = await resolveLint({
65
+ lintConfig: config,
66
+ configPath,
67
+ });
68
+
69
+ expect(lint?.rules?.['operation-2xx-response']).toEqual('warn');
70
+ expect(plugins).toBeDefined();
71
+ expect(plugins?.length).toBe(2);
72
+
73
+ expect(lint.extendPaths!.map(removeAbsolutePath)).toEqual([
74
+ 'resolve-config/.redocly.yaml',
75
+ 'resolve-config/local-config.yaml',
76
+ 'resolve-config/.redocly.yaml',
77
+ ]);
78
+ expect(lint.pluginPaths!.map(removeAbsolutePath)).toEqual(['resolve-config/plugin.js']);
79
+
80
+ expect(lint.rules).toEqual({
81
+ 'boolean-parameter-prefixes': 'error',
82
+ 'local/operation-id-not-test': 'error',
83
+ 'no-invalid-media-type-examples': 'error',
84
+ 'operation-2xx-response': 'warn',
85
+ 'operation-description': 'error',
86
+ 'path-http-verbs-order': 'error',
87
+ });
88
+ });
89
+
90
+ // TODO: fix circular test
91
+ it.skip('should throw circular error', () => {
92
+ const config = {
93
+ ...baseLintConfig,
94
+ extends: ['local-config-with-circular.yaml'],
95
+ };
96
+ expect(() => {
97
+ resolveLint({ lintConfig: config, configPath });
98
+ }).toThrow('Circular dependency in config file');
99
+ });
100
+
101
+ it('should resolve extends with local file config witch contains path to nested config', async () => {
102
+ const lintConfig = {
103
+ extends: ['local-config-with-file.yaml'],
104
+ };
105
+ const { plugins, ...lint } = await resolveLint({
106
+ lintConfig,
107
+ configPath,
108
+ });
109
+
110
+ expect(lint?.rules?.['no-invalid-media-type-examples']).toEqual('warn');
111
+ expect(lint?.rules?.['operation-4xx-response']).toEqual('off');
112
+ expect(lint?.rules?.['operation-2xx-response']).toEqual('error');
113
+ expect(plugins).toBeDefined();
114
+ expect(plugins?.length).toBe(3);
115
+
116
+ expect(lint.extendPaths!.map(removeAbsolutePath)).toEqual([
117
+ 'resolve-config/.redocly.yaml',
118
+ 'resolve-config/local-config-with-file.yaml',
119
+ 'resolve-config/api/nested-config.yaml',
120
+ 'resolve-config/.redocly.yaml',
121
+ ]);
122
+ expect(lint.pluginPaths!.map(removeAbsolutePath)).toEqual([
123
+ 'resolve-config/api/plugin.js',
124
+ 'resolve-config/plugin.js',
125
+ 'resolve-config/api/plugin.js',
126
+ ]);
127
+
128
+ delete lint.extendPaths;
129
+ delete lint.pluginPaths;
130
+ expect(lint).toMatchSnapshot();
131
+ });
132
+
133
+ it('should resolve extends with url file config witch contains path to nested config', async () => {
134
+ const lintConfig = {
135
+ // This points to ./fixtures/resolve-remote-configs/remote-config.yaml
136
+ extends: [
137
+ 'https://raw.githubusercontent.com/Redocly/openapi-cli/master/packages/core/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml',
138
+ ],
139
+ };
140
+
141
+ const { plugins, ...lint } = await resolveLint({
142
+ lintConfig,
143
+ configPath,
144
+ });
145
+
146
+ expect(lint?.rules?.['operation-4xx-response']).toEqual('error');
147
+ expect(lint?.rules?.['operation-2xx-response']).toEqual('error');
148
+ expect(Object.keys(lint.rules || {}).length).toBe(2);
149
+
150
+ expect(lint.extendPaths!.map(removeAbsolutePath)).toEqual([
151
+ 'resolve-config/.redocly.yaml',
152
+ 'resolve-config/.redocly.yaml',
153
+ ]);
154
+ expect(lint.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
155
+ });
156
+ });
157
+
158
+ describe('resolveApis', () => {
159
+ it('should resolve apis lintConfig and merge minimal extends', async () => {
160
+ const rawConfig: RawConfig = {
161
+ apis: {
162
+ petstore: {
163
+ root: 'some/path',
164
+ lint: {},
165
+ },
166
+ },
167
+ lint: {
168
+ extends: ['minimal'],
169
+ },
170
+ };
171
+ const apisResult = await resolveApis({ rawConfig });
172
+ expect(apisResult['petstore'].lint).toEqual(await minimalLintPreset);
173
+ });
174
+
175
+ it('should not merge recommended extends by default by every level', async () => {
176
+ const rawConfig: RawConfig = {
177
+ apis: {
178
+ petstore: {
179
+ root: 'some/path',
180
+ lint: {},
181
+ },
182
+ },
183
+ lint: {},
184
+ };
185
+
186
+ const apisResult = await resolveApis({ rawConfig, configPath });
187
+
188
+ expect(apisResult['petstore'].lint.extendPaths!.map(removeAbsolutePath)).toEqual([
189
+ 'resolve-config/.redocly.yaml',
190
+ ]);
191
+ expect(apisResult['petstore'].lint.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
192
+
193
+ expect(apisResult['petstore'].lint.rules).toEqual({});
194
+ //@ts-ignore
195
+ expect(apisResult['petstore'].lint.plugins.length).toEqual(1);
196
+ //@ts-ignore
197
+ expect(apisResult['petstore'].lint.plugins[0].id).toEqual('');
198
+ });
199
+
200
+ it('should resolve apis lintConfig when it contains file and not set recommended', async () => {
201
+ const rawConfig: RawConfig = {
202
+ apis: {
203
+ petstore: {
204
+ root: 'some/path',
205
+ lint: {
206
+ rules: {
207
+ 'operation-4xx-response': 'error',
208
+ },
209
+ },
210
+ },
211
+ },
212
+ lint: {
213
+ rules: {
214
+ 'operation-2xx-response': 'warn',
215
+ },
216
+ },
217
+ };
218
+
219
+ const apisResult = await resolveApis({ rawConfig, configPath });
220
+ expect(apisResult['petstore'].lint.rules).toEqual({
221
+ 'operation-2xx-response': 'warn',
222
+ 'operation-4xx-response': 'error',
223
+ });
224
+ //@ts-ignore
225
+ expect(apisResult['petstore'].lint.plugins.length).toEqual(1);
226
+ //@ts-ignore
227
+ expect(apisResult['petstore'].lint.plugins[0].id).toEqual('');
228
+
229
+ expect(apisResult['petstore'].lint.extendPaths!.map(removeAbsolutePath)).toEqual([
230
+ 'resolve-config/.redocly.yaml',
231
+ ]);
232
+ expect(apisResult['petstore'].lint.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
233
+ });
234
+
235
+ it('should resolve apis lintConfig when it contains file', async () => {
236
+ const rawConfig: RawConfig = {
237
+ apis: {
238
+ petstore: {
239
+ root: 'some/path',
240
+ lint: {
241
+ extends: ['local-config.yaml'],
242
+ rules: {
243
+ 'operation-4xx-response': 'error',
244
+ },
245
+ },
246
+ },
247
+ },
248
+ lint: {
249
+ extends: ['minimal'],
250
+ rules: {
251
+ 'operation-2xx-response': 'warn',
252
+ },
253
+ },
254
+ };
255
+
256
+ const apisResult = await resolveApis({ rawConfig, configPath });
257
+ expect(apisResult['petstore'].lint.rules).toBeDefined();
258
+ expect(apisResult['petstore'].lint.rules?.['operation-2xx-response']).toEqual('warn'); // think about prioritize in merge ???
259
+ expect(apisResult['petstore'].lint.rules?.['operation-4xx-response']).toEqual('error');
260
+ expect(apisResult['petstore'].lint.rules?.['local/operation-id-not-test']).toEqual('error');
261
+ //@ts-ignore
262
+ expect(apisResult['petstore'].lint.plugins.length).toEqual(2);
263
+
264
+ expect(apisResult['petstore'].lint.extendPaths!.map(removeAbsolutePath)).toEqual([
265
+ 'resolve-config/.redocly.yaml',
266
+ 'resolve-config/local-config.yaml',
267
+ 'resolve-config/.redocly.yaml',
268
+ ]);
269
+ expect(apisResult['petstore'].lint.pluginPaths!.map(removeAbsolutePath)).toEqual([
270
+ 'resolve-config/plugin.js',
271
+ ]);
272
+ });
273
+ });
274
+
275
+ describe('resolveConfig', () => {
276
+ it('should add recommended to top level by default', async () => {
277
+ const rawConfig: RawConfig = {
278
+ apis: {
279
+ petstore: {
280
+ root: 'some/path',
281
+ lint: {
282
+ rules: {
283
+ 'operation-4xx-response': 'error',
284
+ },
285
+ },
286
+ },
287
+ },
288
+ lint: {
289
+ rules: {
290
+ 'operation-2xx-response': 'warn',
291
+ },
292
+ },
293
+ };
294
+
295
+ const { apis } = await resolveConfig(rawConfig, configPath);
296
+ //@ts-ignore
297
+ expect(apis['petstore'].lint.plugins.length).toEqual(1);
298
+ //@ts-ignore
299
+ expect(apis['petstore'].lint.plugins[0].id).toEqual('');
300
+
301
+ expect(apis['petstore'].lint.extendPaths!.map(removeAbsolutePath)).toEqual([
302
+ 'resolve-config/.redocly.yaml',
303
+ ]);
304
+ expect(apis['petstore'].lint.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
305
+
306
+ expect(apis['petstore'].lint.rules).toEqual({
307
+ ...(await recommendedLintPreset).rules,
308
+ 'operation-2xx-response': 'warn',
309
+ 'operation-4xx-response': 'error',
310
+ });
311
+ });
312
+
313
+ it('should not add recommended to top level by default when apis have extends file', async () => {
314
+ const rawConfig: RawConfig = {
315
+ apis: {
316
+ petstore: {
317
+ root: 'some/path',
318
+ lint: {
319
+ extends: ['local-config.yaml'],
320
+ rules: {
321
+ 'operation-4xx-response': 'error',
322
+ },
323
+ },
324
+ },
325
+ },
326
+ lint: {
327
+ rules: {
328
+ 'operation-2xx-response': 'warn',
329
+ },
330
+ },
331
+ };
332
+
333
+ const { apis } = await resolveConfig(rawConfig, configPath);
334
+ expect(apis['petstore'].lint.rules).toBeDefined();
335
+ expect(Object.keys(apis['petstore'].lint.rules || {}).length).toEqual(7);
336
+ expect(apis['petstore'].lint.rules?.['operation-2xx-response']).toEqual('warn');
337
+ expect(apis['petstore'].lint.rules?.['operation-4xx-response']).toEqual('error');
338
+ expect(apis['petstore'].lint.rules?.['operation-description']).toEqual('error'); // from extends file config
339
+ //@ts-ignore
340
+ expect(apis['petstore'].lint.plugins.length).toEqual(2);
341
+
342
+ expect(apis['petstore'].lint.extendPaths!.map(removeAbsolutePath)).toEqual([
343
+ 'resolve-config/.redocly.yaml',
344
+ 'resolve-config/local-config.yaml',
345
+ 'resolve-config/.redocly.yaml',
346
+ ]);
347
+ expect(apis['petstore'].lint.pluginPaths!.map(removeAbsolutePath)).toEqual([
348
+ 'resolve-config/plugin.js',
349
+ ]);
350
+
351
+ expect(apis['petstore'].lint.recommendedFallback).toBe(false);
352
+ });
353
+
354
+ it('should ignore minimal from the root and read local file', async () => {
355
+ const rawConfig: RawConfig = {
356
+ apis: {
357
+ petstore: {
358
+ root: 'some/path',
359
+ lint: {
360
+ extends: ['recommended', 'local-config.yaml'],
361
+ rules: {
362
+ 'operation-4xx-response': 'error',
363
+ },
364
+ },
365
+ },
366
+ },
367
+ lint: {
368
+ extends: ['minimal'],
369
+ rules: {
370
+ 'operation-2xx-response': 'warn',
371
+ },
372
+ },
373
+ };
374
+
375
+ const { apis } = await resolveConfig(rawConfig, configPath);
376
+ expect(apis['petstore'].lint.rules).toBeDefined();
377
+ expect(apis['petstore'].lint.rules?.['operation-2xx-response']).toEqual('warn');
378
+ expect(apis['petstore'].lint.rules?.['operation-4xx-response']).toEqual('error');
379
+ expect(apis['petstore'].lint.rules?.['operation-description']).toEqual('error'); // from extends file config
380
+ //@ts-ignore
381
+ expect(apis['petstore'].lint.plugins.length).toEqual(2);
382
+ //@ts-ignore
383
+ delete apis['petstore'].lint.plugins;
384
+
385
+ expect(apis['petstore'].lint.extendPaths!.map(removeAbsolutePath)).toEqual([
386
+ 'resolve-config/.redocly.yaml',
387
+ 'resolve-config/local-config.yaml',
388
+ 'resolve-config/.redocly.yaml',
389
+ ]);
390
+ expect(apis['petstore'].lint.pluginPaths!.map(removeAbsolutePath)).toEqual([
391
+ 'resolve-config/plugin.js',
392
+ ]);
393
+
394
+ delete apis['petstore'].lint.extendPaths;
395
+ delete apis['petstore'].lint.pluginPaths;
396
+ expect(apis['petstore'].lint).toMatchSnapshot();
397
+ });
398
+ });
@@ -0,0 +1,244 @@
1
+ import { Config } from '../config';
2
+ import { getMergedConfig } from '../utils';
3
+
4
+ const testConfig: Config = {
5
+ rawConfig: {
6
+ apis: {
7
+ 'test@v1': {
8
+ root: 'resources/pets.yaml',
9
+ lint: { rules: { 'operation-summary': 'warn' } },
10
+ },
11
+ },
12
+ organization: 'redocly-test',
13
+ lint: {
14
+ rules: { 'operation-summary': 'error', 'no-empty-servers': 'error' },
15
+ plugins: [],
16
+ },
17
+ },
18
+ configFile: 'redocly.yaml',
19
+ apis: {
20
+ 'test@v1': {
21
+ root: 'resources/pets.yaml',
22
+ lint: { rules: { 'operation-summary': 'warn' } },
23
+ },
24
+ },
25
+ // @ts-ignore
26
+ lint: {
27
+ rawConfig: {
28
+ rules: { 'operation-summary': 'error', 'no-empty-servers': 'error' },
29
+ plugins: [],
30
+ },
31
+ configFile: 'redocly.yaml',
32
+ ignore: {},
33
+ _usedRules: new Set(),
34
+ _usedVersions: new Set(),
35
+ recommendedFallback: false,
36
+ plugins: [],
37
+ doNotResolveExamples: false,
38
+ rules: {
39
+ oas2: { 'operation-summary': 'error', 'no-empty-servers': 'error' },
40
+ oas3_0: { 'operation-summary': 'error', 'no-empty-servers': 'error' },
41
+ oas3_1: { 'operation-summary': 'error', 'no-empty-servers': 'error' },
42
+ },
43
+ preprocessors: { oas2: {}, oas3_0: {}, oas3_1: {} },
44
+ decorators: { oas2: {}, oas3_0: {}, oas3_1: {} },
45
+ },
46
+ 'features.openapi': {},
47
+ 'features.mockServer': {},
48
+ resolve: { http: { headers: [] } },
49
+ organization: 'redocly-test',
50
+ };
51
+
52
+ describe('getMergedConfig', () => {
53
+ it('should get lint defined in "apis" section', () => {
54
+ expect(getMergedConfig(testConfig, 'test@v1')).toMatchInlineSnapshot(`
55
+ Config {
56
+ "apis": Object {
57
+ "test@v1": Object {
58
+ "lint": Object {
59
+ "rules": Object {
60
+ "operation-summary": "warn",
61
+ },
62
+ },
63
+ "root": "resources/pets.yaml",
64
+ },
65
+ },
66
+ "configFile": "redocly.yaml",
67
+ "features.mockServer": Object {},
68
+ "features.openapi": Object {},
69
+ "lint": LintConfig {
70
+ "_usedRules": Set {},
71
+ "_usedVersions": Set {},
72
+ "configFile": "redocly.yaml",
73
+ "decorators": Object {
74
+ "oas2": Object {},
75
+ "oas3_0": Object {},
76
+ "oas3_1": Object {},
77
+ },
78
+ "doNotResolveExamples": false,
79
+ "extendPaths": Array [],
80
+ "ignore": Object {},
81
+ "pluginPaths": Array [],
82
+ "plugins": Array [],
83
+ "preprocessors": Object {
84
+ "oas2": Object {},
85
+ "oas3_0": Object {},
86
+ "oas3_1": Object {},
87
+ },
88
+ "rawConfig": Object {
89
+ "extendPaths": Array [],
90
+ "pluginPaths": Array [],
91
+ "rules": Object {
92
+ "operation-summary": "warn",
93
+ },
94
+ },
95
+ "recommendedFallback": false,
96
+ "rules": Object {
97
+ "oas2": Object {
98
+ "operation-summary": "warn",
99
+ },
100
+ "oas3_0": Object {
101
+ "operation-summary": "warn",
102
+ },
103
+ "oas3_1": Object {
104
+ "operation-summary": "warn",
105
+ },
106
+ },
107
+ },
108
+ "organization": "redocly-test",
109
+ "rawConfig": Object {
110
+ "apis": Object {
111
+ "test@v1": Object {
112
+ "lint": Object {
113
+ "rules": Object {
114
+ "operation-summary": "warn",
115
+ },
116
+ },
117
+ "root": "resources/pets.yaml",
118
+ },
119
+ },
120
+ "features.mockServer": Object {},
121
+ "features.openapi": Object {},
122
+ "lint": Object {
123
+ "extendPaths": Array [],
124
+ "pluginPaths": Array [],
125
+ "rules": Object {
126
+ "operation-summary": "warn",
127
+ },
128
+ },
129
+ "organization": "redocly-test",
130
+ },
131
+ "region": undefined,
132
+ "resolve": Object {
133
+ "http": Object {
134
+ "customFetch": undefined,
135
+ "headers": Array [],
136
+ },
137
+ },
138
+ }
139
+ `);
140
+ });
141
+ it('should take into account a config file', () => {
142
+ const result = getMergedConfig(testConfig, 'test@v1');
143
+ expect(result.configFile).toEqual('redocly.yaml');
144
+ expect(result.lint.configFile).toEqual('redocly.yaml');
145
+ });
146
+ it('should return the same config when there is no alias provided', () => {
147
+ expect(getMergedConfig(testConfig)).toEqual(testConfig);
148
+ });
149
+ it('should handle wrong alias - return the same lint, empty features', () => {
150
+ expect(getMergedConfig(testConfig, 'wrong-alias')).toMatchInlineSnapshot(`
151
+ Config {
152
+ "apis": Object {
153
+ "test@v1": Object {
154
+ "lint": Object {
155
+ "rules": Object {
156
+ "operation-summary": "warn",
157
+ },
158
+ },
159
+ "root": "resources/pets.yaml",
160
+ },
161
+ },
162
+ "configFile": "redocly.yaml",
163
+ "features.mockServer": Object {},
164
+ "features.openapi": Object {},
165
+ "lint": LintConfig {
166
+ "_usedRules": Set {},
167
+ "_usedVersions": Set {},
168
+ "configFile": "redocly.yaml",
169
+ "decorators": Object {
170
+ "oas2": Object {},
171
+ "oas3_0": Object {},
172
+ "oas3_1": Object {},
173
+ },
174
+ "doNotResolveExamples": false,
175
+ "extendPaths": Array [],
176
+ "ignore": Object {},
177
+ "pluginPaths": Array [],
178
+ "plugins": Array [],
179
+ "preprocessors": Object {
180
+ "oas2": Object {},
181
+ "oas3_0": Object {},
182
+ "oas3_1": Object {},
183
+ },
184
+ "rawConfig": Object {
185
+ "extendPaths": Array [],
186
+ "pluginPaths": Array [],
187
+ "plugins": Array [],
188
+ "rules": Object {
189
+ "no-empty-servers": "error",
190
+ "operation-summary": "error",
191
+ },
192
+ },
193
+ "recommendedFallback": false,
194
+ "rules": Object {
195
+ "oas2": Object {
196
+ "no-empty-servers": "error",
197
+ "operation-summary": "error",
198
+ },
199
+ "oas3_0": Object {
200
+ "no-empty-servers": "error",
201
+ "operation-summary": "error",
202
+ },
203
+ "oas3_1": Object {
204
+ "no-empty-servers": "error",
205
+ "operation-summary": "error",
206
+ },
207
+ },
208
+ },
209
+ "organization": "redocly-test",
210
+ "rawConfig": Object {
211
+ "apis": Object {
212
+ "test@v1": Object {
213
+ "lint": Object {
214
+ "rules": Object {
215
+ "operation-summary": "warn",
216
+ },
217
+ },
218
+ "root": "resources/pets.yaml",
219
+ },
220
+ },
221
+ "features.mockServer": Object {},
222
+ "features.openapi": Object {},
223
+ "lint": Object {
224
+ "extendPaths": Array [],
225
+ "pluginPaths": Array [],
226
+ "plugins": Array [],
227
+ "rules": Object {
228
+ "no-empty-servers": "error",
229
+ "operation-summary": "error",
230
+ },
231
+ },
232
+ "organization": "redocly-test",
233
+ },
234
+ "region": undefined,
235
+ "resolve": Object {
236
+ "http": Object {
237
+ "customFetch": undefined,
238
+ "headers": Array [],
239
+ },
240
+ },
241
+ }
242
+ `);
243
+ });
244
+ });
@@ -21,7 +21,7 @@ const rules = {
21
21
  return {
22
22
  SecurityScheme(scheme, { location, report }) {
23
23
  if (scheme.type === 'openIdConnect') {
24
- if (!scheme.openIdConnectUrl?.endsWith('/.well-known/openid-configuration')) {
24
+ if (!scheme.openIdConnectUrl.endsWith('/.well-known/openid-configuration')) {
25
25
  report({
26
26
  message:
27
27
  'openIdConnectUrl must be a URL that ends with /.well-known/openid-configuration',
@@ -0,0 +1,7 @@
1
+ lint:
2
+ plugins:
3
+ - plugin.js
4
+ rules:
5
+ operation-2xx-response: error
6
+ extends:
7
+ - test-plugin-nested/all