@redocly/openapi-core 1.0.0-beta.108 → 1.0.0-beta.109

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 (132) hide show
  1. package/lib/benchmark/benches/resolve-with-no-external.bench.js +1 -1
  2. package/lib/bundle.d.ts +1 -1
  3. package/lib/bundle.js +4 -4
  4. package/lib/config/all.js +3 -1
  5. package/lib/config/config-resolvers.js +1 -1
  6. package/lib/config/minimal.js +3 -1
  7. package/lib/config/recommended.js +3 -1
  8. package/lib/config/rules.js +1 -1
  9. package/lib/config/types.d.ts +7 -0
  10. package/lib/config/utils.d.ts +2 -2
  11. package/lib/config/utils.js +42 -4
  12. package/lib/decorators/common/registry-dependencies.js +1 -1
  13. package/lib/format/format.d.ts +1 -1
  14. package/lib/format/format.js +22 -1
  15. package/lib/lint.js +2 -2
  16. package/lib/redocly/registry-api.d.ts +0 -1
  17. package/lib/redocly/registry-api.js +5 -4
  18. package/lib/resolve.js +3 -1
  19. package/lib/rules/common/no-ambiguous-paths.js +1 -1
  20. package/lib/rules/common/no-identical-paths.js +1 -1
  21. package/lib/rules/common/operation-2xx-response.js +1 -1
  22. package/lib/rules/common/operation-4xx-response.js +1 -1
  23. package/lib/rules/common/operation-operationId.js +1 -1
  24. package/lib/rules/common/operation-tag-defined.js +1 -1
  25. package/lib/rules/common/path-not-include-query.js +1 -1
  26. package/lib/rules/common/security-defined.d.ts +2 -0
  27. package/lib/rules/common/{operation-security-defined.js → security-defined.js} +18 -4
  28. package/lib/rules/common/spec.js +12 -1
  29. package/lib/rules/common/tags-alphabetical.js +1 -1
  30. package/lib/rules/oas2/index.d.ts +1 -1
  31. package/lib/rules/oas2/index.js +2 -2
  32. package/lib/rules/oas2/remove-unused-components.js +1 -1
  33. package/lib/rules/oas2/request-mime-type.js +1 -1
  34. package/lib/rules/oas2/response-mime-type.js +1 -1
  35. package/lib/rules/oas3/index.js +6 -2
  36. package/lib/rules/oas3/no-empty-servers.js +1 -1
  37. package/lib/rules/oas3/no-server-variables-empty-enum.js +1 -1
  38. package/lib/rules/oas3/no-unused-components.js +1 -1
  39. package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.d.ts +5 -0
  40. package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.js +36 -0
  41. package/lib/rules/oas3/remove-unused-components.js +1 -1
  42. package/lib/rules/oas3/request-mime-type.js +1 -1
  43. package/lib/rules/oas3/response-mime-type.js +1 -1
  44. package/lib/rules/oas3/spec-components-invalid-map-name.d.ts +2 -0
  45. package/lib/rules/oas3/spec-components-invalid-map-name.js +46 -0
  46. package/lib/rules/other/stats.d.ts +2 -2
  47. package/lib/rules/other/stats.js +2 -2
  48. package/lib/types/oas2.js +5 -5
  49. package/lib/types/oas3.js +27 -20
  50. package/lib/types/oas3_1.js +3 -3
  51. package/lib/types/redocly-yaml.js +46 -55
  52. package/lib/utils.d.ts +3 -3
  53. package/lib/utils.js +5 -5
  54. package/lib/visitors.d.ts +11 -11
  55. package/lib/visitors.js +13 -1
  56. package/package.json +1 -1
  57. package/src/__tests__/__snapshots__/bundle.test.ts.snap +3 -3
  58. package/src/__tests__/fixtures/extension.js +3 -3
  59. package/src/__tests__/format.test.ts +76 -0
  60. package/src/__tests__/lint.test.ts +106 -131
  61. package/src/__tests__/resolve-http.test.ts +1 -1
  62. package/src/__tests__/resolve.test.ts +9 -9
  63. package/src/__tests__/walk.test.ts +78 -10
  64. package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
  65. package/src/bundle.ts +4 -4
  66. package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +6 -2
  67. package/src/config/__tests__/fixtures/plugin-config.yaml +2 -3
  68. package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +11 -12
  69. package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +7 -8
  70. package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +18 -19
  71. package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +9 -10
  72. package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +3 -4
  73. package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +4 -5
  74. package/src/config/__tests__/load.test.ts +12 -15
  75. package/src/config/__tests__/utils.test.ts +64 -4
  76. package/src/config/all.ts +3 -1
  77. package/src/config/config-resolvers.ts +2 -2
  78. package/src/config/load.ts +3 -2
  79. package/src/config/minimal.ts +3 -1
  80. package/src/config/recommended.ts +3 -1
  81. package/src/config/rules.ts +2 -2
  82. package/src/config/types.ts +11 -0
  83. package/src/config/utils.ts +102 -13
  84. package/src/decorators/common/registry-dependencies.ts +1 -1
  85. package/src/format/format.ts +32 -2
  86. package/src/lint.ts +2 -2
  87. package/src/redocly/registry-api.ts +5 -4
  88. package/src/resolve.ts +3 -1
  89. package/src/rules/__tests__/utils.test.ts +1 -1
  90. package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +1 -0
  91. package/src/rules/common/__tests__/operation-2xx-response.test.ts +1 -1
  92. package/src/rules/common/__tests__/operation-4xx-response.test.ts +26 -3
  93. package/src/rules/common/__tests__/security-defined.test.ts +175 -0
  94. package/src/rules/common/__tests__/spec.test.ts +79 -0
  95. package/src/rules/common/assertions/__tests__/utils.test.ts +2 -2
  96. package/src/rules/common/no-ambiguous-paths.ts +1 -1
  97. package/src/rules/common/no-identical-paths.ts +1 -1
  98. package/src/rules/common/operation-2xx-response.ts +1 -1
  99. package/src/rules/common/operation-4xx-response.ts +1 -1
  100. package/src/rules/common/operation-operationId.ts +1 -1
  101. package/src/rules/common/operation-tag-defined.ts +1 -1
  102. package/src/rules/common/path-not-include-query.ts +1 -1
  103. package/src/rules/common/{operation-security-defined.ts → security-defined.ts} +19 -4
  104. package/src/rules/common/spec.ts +15 -1
  105. package/src/rules/common/tags-alphabetical.ts +1 -1
  106. package/src/rules/oas2/index.ts +2 -2
  107. package/src/rules/oas2/remove-unused-components.ts +1 -1
  108. package/src/rules/oas2/request-mime-type.ts +1 -1
  109. package/src/rules/oas2/response-mime-type.ts +1 -1
  110. package/src/rules/oas3/__tests__/operation-4xx-problem-details-rfc7807.test.ts +145 -0
  111. package/src/rules/oas3/__tests__/spec/spec.test.ts +10 -0
  112. package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +217 -0
  113. package/src/rules/oas3/index.ts +6 -2
  114. package/src/rules/oas3/no-empty-servers.ts +1 -1
  115. package/src/rules/oas3/no-server-variables-empty-enum.ts +1 -1
  116. package/src/rules/oas3/no-unused-components.ts +1 -1
  117. package/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +36 -0
  118. package/src/rules/oas3/remove-unused-components.ts +1 -1
  119. package/src/rules/oas3/request-mime-type.ts +1 -1
  120. package/src/rules/oas3/response-mime-type.ts +1 -1
  121. package/src/rules/oas3/spec-components-invalid-map-name.ts +53 -0
  122. package/src/rules/other/stats.ts +2 -2
  123. package/src/types/index.ts +2 -2
  124. package/src/types/oas2.ts +5 -5
  125. package/src/types/oas3.ts +27 -20
  126. package/src/types/oas3_1.ts +3 -3
  127. package/src/types/redocly-yaml.ts +52 -40
  128. package/src/utils.ts +11 -7
  129. package/src/visitors.ts +29 -13
  130. package/tsconfig.tsbuildinfo +1 -1
  131. package/lib/rules/common/operation-security-defined.d.ts +0 -2
  132. package/src/rules/common/__tests__/operation-security-defined.test.ts +0 -69
@@ -24,7 +24,7 @@ describe('collect refs', () => {
24
24
  const resolvedRefs = await resolveDocument({
25
25
  rootDocument,
26
26
  externalRefResolver: new BaseResolver(),
27
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
27
+ rootType: normalizeTypes(Oas3Types).Root,
28
28
  });
29
29
 
30
30
  expect(resolvedRefs).toBeDefined();
@@ -63,7 +63,7 @@ describe('collect refs', () => {
63
63
  await resolveDocument({
64
64
  rootDocument,
65
65
  externalRefResolver: new BaseResolver(),
66
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
66
+ rootType: normalizeTypes(Oas3Types).Root,
67
67
  });
68
68
  } catch (e) {
69
69
  expect(e.message).toEqual('Self-referencing circular pointer');
@@ -95,7 +95,7 @@ describe('collect refs', () => {
95
95
  const resolvedRefs = await resolveDocument({
96
96
  rootDocument,
97
97
  externalRefResolver: new BaseResolver(),
98
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
98
+ rootType: normalizeTypes(Oas3Types).Root,
99
99
  });
100
100
 
101
101
  expect(resolvedRefs).toBeDefined();
@@ -132,7 +132,7 @@ describe('collect refs', () => {
132
132
  await resolveDocument({
133
133
  rootDocument,
134
134
  externalRefResolver: new BaseResolver(),
135
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
135
+ rootType: normalizeTypes(Oas3Types).Root,
136
136
  });
137
137
  } catch (e) {
138
138
  expect(e.message).toEqual('Self-referencing circular pointer');
@@ -153,7 +153,7 @@ describe('collect refs', () => {
153
153
  const resolvedRefs = await resolveDocument({
154
154
  rootDocument,
155
155
  externalRefResolver: new BaseResolver(),
156
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
156
+ rootType: normalizeTypes(Oas3Types).Root,
157
157
  });
158
158
 
159
159
  expect(resolvedRefs).toBeDefined();
@@ -187,7 +187,7 @@ describe('collect refs', () => {
187
187
  const resolvedRefs = await resolveDocument({
188
188
  rootDocument: rootDocument as Document,
189
189
  externalRefResolver: externalRefResolver,
190
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
190
+ rootType: normalizeTypes(Oas3Types).Root,
191
191
  });
192
192
 
193
193
  expect(resolvedRefs).toBeDefined();
@@ -263,7 +263,7 @@ describe('collect refs', () => {
263
263
  const resolvedRefs = await resolveDocument({
264
264
  rootDocument: rootDocument as Document,
265
265
  externalRefResolver: externalRefResolver,
266
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
266
+ rootType: normalizeTypes(Oas3Types).Root,
267
267
  });
268
268
 
269
269
  expect(resolvedRefs).toBeDefined();
@@ -358,7 +358,7 @@ describe('collect refs', () => {
358
358
  const resolvedRefs = await resolveDocument({
359
359
  rootDocument: rootDocument as Document,
360
360
  externalRefResolver: externalRefResolver,
361
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
361
+ rootType: normalizeTypes(Oas3Types).Root,
362
362
  });
363
363
 
364
364
  expect(resolvedRefs).toBeDefined();
@@ -392,7 +392,7 @@ describe('collect refs', () => {
392
392
  const resolvedRefs = await resolveDocument({
393
393
  rootDocument,
394
394
  externalRefResolver: new BaseResolver(),
395
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
395
+ rootType: normalizeTypes(Oas3Types).Root,
396
396
  });
397
397
 
398
398
  expect(resolvedRefs).toBeDefined();
@@ -16,7 +16,7 @@ import { Oas3RuleSet } from '../oas-types';
16
16
  describe('walk order', () => {
17
17
  it('should run visitors', async () => {
18
18
  const visitors = {
19
- DefinitionRoot: {
19
+ Root: {
20
20
  enter: jest.fn(),
21
21
  leave: jest.fn(),
22
22
  },
@@ -63,6 +63,74 @@ describe('walk order', () => {
63
63
  }
64
64
  });
65
65
 
66
+ it('should run legacy visitors', async () => {
67
+ const visitors = {
68
+ DefinitionRoot: {
69
+ enter: jest.fn(),
70
+ leave: jest.fn(),
71
+ },
72
+ PathMap: {
73
+ enter: jest.fn(),
74
+ leave: jest.fn(),
75
+ },
76
+ ServerVariableMap: {
77
+ enter: jest.fn(),
78
+ leave: jest.fn(),
79
+ },
80
+ MediaTypeMap: {
81
+ enter: jest.fn(),
82
+ leave: jest.fn(),
83
+ },
84
+ ExampleMap: {
85
+ enter: jest.fn(),
86
+ leave: jest.fn(),
87
+ },
88
+ HeaderMap: {
89
+ enter: jest.fn(),
90
+ leave: jest.fn(),
91
+ },
92
+ };
93
+
94
+ const testRuleSet: Oas3RuleSet = {
95
+ test: jest.fn(() => {
96
+ return visitors;
97
+ }),
98
+ };
99
+
100
+ const document = parseYamlToDocument(
101
+ outdent`
102
+ openapi: 3.0.0
103
+ servers:
104
+ - url: http://{test}.url
105
+ variables:
106
+ test: test
107
+ paths:
108
+ /test-path:
109
+ get:
110
+ responses:
111
+ 200:
112
+ headers: {}
113
+ content:
114
+ application/json:
115
+ schema: {}
116
+ examples: {}
117
+ `,
118
+ ''
119
+ );
120
+
121
+ await lintDocument({
122
+ externalRefResolver: new BaseResolver(),
123
+ document,
124
+ config: makeConfigForRuleset(testRuleSet),
125
+ });
126
+
127
+ expect(testRuleSet.test).toBeCalledTimes(1);
128
+ for (const fns of Object.values(visitors)) {
129
+ expect(fns.enter).toBeCalled();
130
+ expect(fns.leave).toBeCalled();
131
+ }
132
+ });
133
+
66
134
  it('should run nested visitors correctly', async () => {
67
135
  const calls: string[] = [];
68
136
 
@@ -1046,8 +1114,8 @@ describe('walk order', () => {
1046
1114
 
1047
1115
  expect(calls).toMatchInlineSnapshot(`
1048
1116
  Array [
1049
- "enter DefinitionRoot",
1050
- "enter PathMap",
1117
+ "enter Root",
1118
+ "enter PathsMap",
1051
1119
  "enter PathItem",
1052
1120
  "enter ParameterList",
1053
1121
  "enter Parameter",
@@ -1066,7 +1134,7 @@ describe('walk order', () => {
1066
1134
  "leave ParameterList",
1067
1135
  "leave Operation",
1068
1136
  "leave PathItem",
1069
- "leave PathMap",
1137
+ "leave PathsMap",
1070
1138
  "enter Components",
1071
1139
  "enter NamedParameters",
1072
1140
  "leave NamedParameters",
@@ -1075,7 +1143,7 @@ describe('walk order', () => {
1075
1143
  "leave Schema",
1076
1144
  "leave NamedSchemas",
1077
1145
  "leave Components",
1078
- "leave DefinitionRoot",
1146
+ "leave Root",
1079
1147
  ]
1080
1148
  `);
1081
1149
  });
@@ -1378,10 +1446,10 @@ describe('type extensions', () => {
1378
1446
  parameters: listOf('Parameter'),
1379
1447
  },
1380
1448
  },
1381
- DefinitionRoot: {
1382
- ...types.DefinitionRoot,
1449
+ Root: {
1450
+ ...types.Root,
1383
1451
  properties: {
1384
- ...types.DefinitionRoot.properties,
1452
+ ...types.Root.properties,
1385
1453
  'x-webhooks': 'XWebHooks',
1386
1454
  },
1387
1455
  },
@@ -1393,7 +1461,7 @@ describe('type extensions', () => {
1393
1461
 
1394
1462
  expect(calls).toMatchInlineSnapshot(`
1395
1463
  Array [
1396
- "enter DefinitionRoot",
1464
+ "enter Root",
1397
1465
  "enter XWebHooks",
1398
1466
  "enter hook test",
1399
1467
  "enter ParameterList",
@@ -1402,7 +1470,7 @@ describe('type extensions', () => {
1402
1470
  "leave ParameterList",
1403
1471
  "leave hook test",
1404
1472
  "leave XWebHooks",
1405
- "leave DefinitionRoot",
1473
+ "leave Root",
1406
1474
  ]
1407
1475
  `);
1408
1476
  });
@@ -18,6 +18,6 @@ export function measureAsync() {
18
18
  return resolveDocument({
19
19
  rootDocument: rebillyDocument,
20
20
  externalRefResolver,
21
- rootType: normalizeTypes(Oas3Types).DefinitionRoot,
21
+ rootType: normalizeTypes(Oas3Types).Root,
22
22
  });
23
23
  }
package/src/bundle.ts CHANGED
@@ -122,7 +122,7 @@ export async function bundleDocument(opts: {
122
122
 
123
123
  const resolvedRefMap = await resolveDocument({
124
124
  rootDocument: document,
125
- rootType: types.DefinitionRoot,
125
+ rootType: types.Root,
126
126
  externalRefResolver,
127
127
  });
128
128
 
@@ -148,7 +148,7 @@ export async function bundleDocument(opts: {
148
148
 
149
149
  walkDocument({
150
150
  document,
151
- rootType: types.DefinitionRoot as NormalizedNodeType,
151
+ rootType: types.Root as NormalizedNodeType,
152
152
  normalizedVisitors: bundleVisitor,
153
153
  resolvedRefMap,
154
154
  ctx,
@@ -158,7 +158,7 @@ export async function bundleDocument(opts: {
158
158
  bundle: document,
159
159
  problems: ctx.problems.map((problem) => config.addProblemToIgnore(problem)),
160
160
  fileDependencies: externalRefResolver.getFiles(),
161
- rootType: types.DefinitionRoot,
161
+ rootType: types.Root,
162
162
  refTypes: ctx.refTypes,
163
163
  visitorsData: ctx.visitorsData,
164
164
  };
@@ -254,7 +254,7 @@ function makeBundleVisitor(
254
254
  }
255
255
  },
256
256
  },
257
- DefinitionRoot: {
257
+ Root: {
258
258
  enter(root: any) {
259
259
  if (version === OasMajorVersion.Version3) {
260
260
  components = root.components = root.components || {};
@@ -18,6 +18,7 @@ Object {
18
18
  "no-server-variables-empty-enum": "error",
19
19
  "no-undefined-server-variable": "error",
20
20
  "no-unused-components": "warn",
21
+ "spec-components-invalid-map-name": "error",
21
22
  },
22
23
  "oas3_1Decorators": Object {},
23
24
  "oas3_1Preprocessors": Object {},
@@ -30,6 +31,7 @@ Object {
30
31
  "no-server-variables-empty-enum": "error",
31
32
  "no-undefined-server-variable": "error",
32
33
  "no-unused-components": "warn",
34
+ "spec-components-invalid-map-name": "error",
33
35
  },
34
36
  "preprocessors": Object {},
35
37
  "recommendedFallback": false,
@@ -54,7 +56,6 @@ Object {
54
56
  "operation-operationId-unique": "error",
55
57
  "operation-operationId-url-safe": "error",
56
58
  "operation-parameters-unique": "error",
57
- "operation-security-defined": "error",
58
59
  "operation-singular-tag": "off",
59
60
  "operation-summary": "error",
60
61
  "operation-tag-defined": "off",
@@ -64,6 +65,7 @@ Object {
64
65
  "path-not-include-query": "error",
65
66
  "path-parameters-defined": "error",
66
67
  "paths-kebab-case": "off",
68
+ "security-defined": "error",
67
69
  "spec": "error",
68
70
  "tag-description": "warn",
69
71
  "tags-alphabetical": "off",
@@ -89,6 +91,7 @@ Object {
89
91
  "no-server-variables-empty-enum": "error",
90
92
  "no-undefined-server-variable": "error",
91
93
  "no-unused-components": "warn",
94
+ "spec-components-invalid-map-name": "error",
92
95
  },
93
96
  "oas3_1Decorators": Object {},
94
97
  "oas3_1Preprocessors": Object {},
@@ -101,6 +104,7 @@ Object {
101
104
  "no-server-variables-empty-enum": "error",
102
105
  "no-undefined-server-variable": "error",
103
106
  "no-unused-components": "warn",
107
+ "spec-components-invalid-map-name": "error",
104
108
  },
105
109
  "preprocessors": Object {},
106
110
  "recommendedFallback": undefined,
@@ -142,7 +146,6 @@ Object {
142
146
  "operation-operationId-unique": "error",
143
147
  "operation-operationId-url-safe": "error",
144
148
  "operation-parameters-unique": "error",
145
- "operation-security-defined": "error",
146
149
  "operation-singular-tag": "off",
147
150
  "operation-summary": "error",
148
151
  "operation-tag-defined": "off",
@@ -151,6 +154,7 @@ Object {
151
154
  "path-not-include-query": "error",
152
155
  "path-parameters-defined": "error",
153
156
  "paths-kebab-case": "off",
157
+ "security-defined": "error",
154
158
  "spec": "error",
155
159
  "tag-description": "warn",
156
160
  "tags-alphabetical": "off",
@@ -1,3 +1,2 @@
1
- lint:
2
- plugins:
3
- - './plugin.js'
1
+ plugins:
2
+ - './plugin.js'
@@ -1,12 +1,11 @@
1
- lint:
2
- plugins:
3
- - plugin.js
4
- rules:
5
- operation-2xx-response: error
6
- assert/path-item-get-defined:
7
- subject: PathItem
8
- property: get
9
- message: Every path item must have a GET operation.
10
- defined: true
11
- extends:
12
- - test-plugin-nested/all
1
+ plugins:
2
+ - plugin.js
3
+ rules:
4
+ operation-2xx-response: error
5
+ assert/path-item-get-defined:
6
+ subject: PathItem
7
+ property: get
8
+ message: Every path item must have a GET operation.
9
+ defined: true
10
+ extends:
11
+ - test-plugin-nested/all
@@ -1,8 +1,7 @@
1
- lint:
2
- extends:
3
- - local-config-with-circular.yaml
4
- rules:
5
- no-invalid-media-type-examples: error
6
- operation-description: error
7
- path-http-verbs-order: error
8
- operation-2xx-response: off
1
+ extends:
2
+ - local-config-with-circular.yaml
3
+ rules:
4
+ no-invalid-media-type-examples: error
5
+ operation-description: error
6
+ path-http-verbs-order: error
7
+ operation-2xx-response: off
@@ -1,19 +1,18 @@
1
- lint:
2
- rules:
3
- no-invalid-media-type-examples: warn
4
- operation-4xx-response: off
5
- assert/tag-description:
6
- subject: Tag
7
- property: description
8
- message: Tag description must be at least 13 characters and end with a full stop.
9
- severity: error
10
- minLength: 13
11
- pattern: /\.$/
12
- plugins:
13
- - plugin.js
14
- - api/plugin.js
15
- extends:
16
- - recommended
17
- - api/nested-config.yaml
18
- - test-plugin-nested/all
19
- - test-plugin/all
1
+ rules:
2
+ no-invalid-media-type-examples: warn
3
+ operation-4xx-response: off
4
+ assert/tag-description:
5
+ subject: Tag
6
+ property: description
7
+ message: Tag description must be at least 13 characters and end with a full stop.
8
+ severity: error
9
+ minLength: 13
10
+ pattern: /\.$/
11
+ plugins:
12
+ - plugin.js
13
+ - api/plugin.js
14
+ extends:
15
+ - recommended
16
+ - api/nested-config.yaml
17
+ - test-plugin-nested/all
18
+ - test-plugin/all
@@ -1,10 +1,9 @@
1
- lint:
2
- plugins:
3
- - plugin.js
4
- extends:
5
- - test-plugin/all
6
- rules:
7
- no-invalid-media-type-examples: error
8
- operation-description: error
9
- path-http-verbs-order: error
10
- operation-2xx-response: off
1
+ plugins:
2
+ - plugin.js
3
+ extends:
4
+ - test-plugin/all
5
+ rules:
6
+ no-invalid-media-type-examples: error
7
+ operation-description: error
8
+ path-http-verbs-order: error
9
+ operation-2xx-response: off
@@ -1,4 +1,3 @@
1
- lint:
2
- rules:
3
- operation-2xx-response: off
4
- operation-4xx-response: error
1
+ rules:
2
+ operation-2xx-response: off
3
+ operation-4xx-response: error
@@ -1,5 +1,4 @@
1
- lint:
2
- extends:
3
- - nested-remote-config.yaml
4
- rules:
5
- operation-2xx-response: error
1
+ extends:
2
+ - nested-remote-config.yaml
3
+ rules:
4
+ operation-2xx-response: error
@@ -1,6 +1,6 @@
1
1
  import { loadConfig, findConfig, getConfig, createConfig } from '../load';
2
2
  import { RedoclyClient } from '../../redocly';
3
- import { RuleConfig, RawConfig } from './../types';
3
+ import { RuleConfig, FlatRawConfig } from './../types';
4
4
  import { Config } from '../config';
5
5
 
6
6
  const fs = require('fs');
@@ -93,11 +93,10 @@ describe('getConfig', () => {
93
93
  describe('createConfig', () => {
94
94
  it('should create config from string', async () => {
95
95
  const config = await createConfig(`
96
- styleguide:
97
- extends:
98
- - recommended
99
- rules:
100
- info-license: off
96
+ extends:
97
+ - recommended
98
+ rules:
99
+ info-license: off
101
100
  `);
102
101
 
103
102
  verifyExtendedConfig(config, {
@@ -107,21 +106,19 @@ describe('createConfig', () => {
107
106
  });
108
107
 
109
108
  it('should create config from object', async () => {
110
- const rawConfig: RawConfig = {
111
- styleguide: {
112
- extends: ['minimal'],
113
- rules: {
114
- 'info-license': 'off',
115
- 'tag-description': 'off',
116
- 'operation-2xx-response': 'off',
117
- },
109
+ const rawConfig: FlatRawConfig = {
110
+ extends: ['minimal'],
111
+ rules: {
112
+ 'info-license': 'off',
113
+ 'tag-description': 'off',
114
+ 'operation-2xx-response': 'off',
118
115
  },
119
116
  };
120
117
  const config = await createConfig(rawConfig);
121
118
 
122
119
  verifyExtendedConfig(config, {
123
120
  extendsRuleSet: 'minimal',
124
- overridesRules: rawConfig.styleguide!.rules as Record<string, RuleConfig>,
121
+ overridesRules: rawConfig.rules as Record<string, RuleConfig>,
125
122
  });
126
123
  });
127
124
  });
@@ -1,4 +1,4 @@
1
- import { DeprecatedInRawConfig, RawConfig } from '../types';
1
+ import { DeprecatedInRawConfig, RawConfig, FlatRawConfig } from '../types';
2
2
  import * as utils from '../utils';
3
3
 
4
4
  const makeTestRawConfig = (
@@ -22,8 +22,54 @@ const makeTestRawConfig = (
22
22
  },
23
23
  });
24
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
+ 'features.openapi': {
45
+ disableSidebar: true,
46
+ },
47
+ };
48
+
49
+ const flatTestConfig: FlatRawConfig = {
50
+ apis: {
51
+ 'test@v1': {
52
+ root: 'root.yaml',
53
+ extends: ['recommended'],
54
+ rules: { 'operation-2xx-response': 'error' },
55
+ },
56
+ },
57
+ plugins: ['test-plugin'],
58
+ extends: ['minimal'],
59
+ rules: {
60
+ 'operation-4xx-response': 'warn',
61
+ },
62
+ resolve: {
63
+ http: { headers: [{ matches: '*', name: 'all', envVariable: 'all' }] },
64
+ doNotResolveExamples: true,
65
+ },
66
+ 'features.openapi': {
67
+ disableSidebar: true,
68
+ },
69
+ };
70
+
25
71
  describe('transformConfig', () => {
26
- it('should work for new syntax', () => {
72
+ it('should work for the `styleguide` syntax', () => {
27
73
  const transformedRawConfig: RawConfig = utils.transformConfig(
28
74
  makeTestRawConfig('styleguide', 'styleguide')
29
75
  );
@@ -73,11 +119,25 @@ describe('transformConfig', () => {
73
119
  }
74
120
  `);
75
121
  });
76
- it('should throw an error if both new and old syntax used together', () => {
122
+ it('should throw an error if both `styleguide` and `lint` syntaxes used together', () => {
77
123
  const testRawConfig = makeTestRawConfig('styleguide', 'lint');
78
124
  testRawConfig.apiDefinitions = { legacyApiDefinition: 'file.yaml' };
79
125
  expect(() => utils.transformConfig(testRawConfig)).toThrowError(
80
- `Do not use 'apiDefinitions' field. Use 'apis' instead.`
126
+ `Do not use 'apiDefinitions' field. Use 'apis' instead. `
127
+ );
128
+ });
129
+ it('should transform flatten config into styleguide', () => {
130
+ expect(utils.transformConfig(flatTestConfig)).toEqual({
131
+ ...rawTestConfig,
132
+ resolve: { ...rawTestConfig.resolve, doNotResolveExamples: true },
133
+ });
134
+ });
135
+ it('should transform styleguide config into styleguide identically', () => {
136
+ expect(utils.transformConfig(rawTestConfig)).toEqual(rawTestConfig);
137
+ });
138
+ it('should fail when there is a mixed config', () => {
139
+ expect(() => utils.transformConfig({ ...rawTestConfig, extends: ['recommended'] })).toThrow(
140
+ `Do not use 'lint', 'styleguide' and flat syntax together. \nSee more about the configuration in the docs: https://redocly.com/docs/cli/configuration/ \n`
81
141
  );
82
142
  });
83
143
  });
package/src/config/all.ts CHANGED
@@ -26,7 +26,7 @@ export default {
26
26
  'operation-operationId-url-safe': 'error',
27
27
  'operation-parameters-unique': 'error',
28
28
  'operation-tag-defined': 'error',
29
- 'operation-security-defined': 'error',
29
+ 'security-defined': 'error',
30
30
  'operation-singular-tag': 'error',
31
31
  'no-unresolved-refs': 'error',
32
32
  'no-enum-type-mismatch': 'error',
@@ -52,6 +52,7 @@ export default {
52
52
  'no-unused-components': 'error',
53
53
  'no-undefined-server-variable': 'error',
54
54
  'no-server-variables-empty-enum': 'error',
55
+ 'operation-4xx-problem-details-rfc7807': 'error',
55
56
  },
56
57
  oas3_1Rules: {
57
58
  'no-server-example.com': 'error',
@@ -61,5 +62,6 @@ export default {
61
62
  'no-unused-components': 'error',
62
63
  'no-undefined-server-variable': 'error',
63
64
  'no-server-variables-empty-enum': 'error',
65
+ 'operation-4xx-problem-details-rfc7807': 'error',
64
66
  },
65
67
  } as PluginStyleguideConfig;
@@ -21,7 +21,7 @@ import type {
21
21
  DeprecatedInRawConfig,
22
22
  } from './types';
23
23
  import { isBrowser } from '../env';
24
- import { isNotString, isString, notUndefined, parseYaml } from '../utils';
24
+ import { isNotString, isString, isDefined, parseYaml } from '../utils';
25
25
  import { Config } from './config';
26
26
  import { colorize, logger } from '../logger';
27
27
 
@@ -177,7 +177,7 @@ export function resolvePlugins(
177
177
 
178
178
  return plugin;
179
179
  })
180
- .filter(notUndefined);
180
+ .filter(isDefined);
181
181
  }
182
182
 
183
183
  export async function resolveApis({
@@ -7,7 +7,7 @@ import { Config, DOMAINS } from './config';
7
7
  import { transformConfig } from './utils';
8
8
  import { resolveConfig } from './config-resolvers';
9
9
 
10
- import type { DeprecatedInRawConfig, RawConfig, Region } from './types';
10
+ import type { DeprecatedInRawConfig, FlatRawConfig, RawConfig, Region } from './types';
11
11
  import { RegionalTokenWithValidity } from '../redocly/redocly-client-types';
12
12
 
13
13
  async function addConfigMetadata({
@@ -102,7 +102,8 @@ export function findConfig(dir?: string): string | undefined {
102
102
  export async function getConfig(configPath: string | undefined = findConfig()): Promise<RawConfig> {
103
103
  if (!configPath || !doesYamlFileExist(configPath)) return {};
104
104
  try {
105
- const rawConfig = (await loadYaml<RawConfig & DeprecatedInRawConfig>(configPath)) || {};
105
+ const rawConfig =
106
+ (await loadYaml<RawConfig & DeprecatedInRawConfig & FlatRawConfig>(configPath)) || {};
106
107
  return transformConfig(rawConfig);
107
108
  } catch (e) {
108
109
  throw new Error(`Error parsing config file at '${configPath}': ${e.message}`);