@redocly/openapi-core 1.0.0-beta.106 → 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.
- package/lib/benchmark/benches/lint-with-top-level-rule-report.bench.js +0 -1
- package/lib/benchmark/benches/resolve-with-no-external.bench.js +1 -1
- package/lib/bundle.d.ts +1 -1
- package/lib/bundle.js +9 -6
- package/lib/config/all.js +5 -3
- package/lib/config/config-resolvers.js +32 -14
- package/lib/config/config.d.ts +3 -5
- package/lib/config/config.js +7 -4
- package/lib/config/load.d.ts +7 -0
- package/lib/config/load.js +14 -6
- package/lib/config/minimal.js +7 -4
- package/lib/config/recommended.js +7 -4
- package/lib/config/rules.d.ts +1 -1
- package/lib/config/rules.js +1 -1
- package/lib/config/types.d.ts +7 -0
- package/lib/config/utils.d.ts +2 -2
- package/lib/config/utils.js +49 -11
- package/lib/decorators/common/registry-dependencies.js +2 -2
- package/lib/env.d.ts +3 -0
- package/lib/env.js +8 -0
- package/lib/format/codeframes.js +16 -10
- package/lib/format/format.d.ts +1 -1
- package/lib/format/format.js +49 -26
- package/lib/index.d.ts +5 -5
- package/lib/index.js +3 -1
- package/lib/js-yaml/index.js +1 -0
- package/lib/lint.js +2 -2
- package/lib/logger.d.ts +10 -0
- package/lib/logger.js +31 -0
- package/lib/output.d.ts +3 -0
- package/lib/output.js +9 -0
- package/lib/redocly/index.js +10 -9
- package/lib/redocly/registry-api-types.d.ts +28 -30
- package/lib/redocly/registry-api.d.ts +3 -3
- package/lib/redocly/registry-api.js +7 -1
- package/lib/ref-utils.js +2 -1
- package/lib/resolve.d.ts +1 -1
- package/lib/resolve.js +4 -2
- package/lib/rules/ajv.d.ts +1 -1
- package/lib/rules/ajv.js +7 -7
- package/lib/rules/common/assertions/asserts.js +4 -4
- package/lib/rules/common/assertions/index.js +1 -1
- package/lib/rules/common/no-ambiguous-paths.js +1 -1
- package/lib/rules/common/no-identical-paths.js +1 -1
- package/lib/rules/common/no-invalid-parameter-examples.js +3 -3
- package/lib/rules/common/no-invalid-schema-examples.js +3 -3
- package/lib/rules/common/operation-2xx-response.js +1 -1
- package/lib/rules/common/operation-4xx-response.js +1 -1
- package/lib/rules/common/operation-operationId.js +1 -1
- package/lib/rules/common/operation-tag-defined.js +1 -1
- package/lib/rules/common/path-not-include-query.js +1 -1
- package/lib/rules/common/security-defined.d.ts +2 -0
- package/lib/rules/common/{operation-security-defined.js → security-defined.js} +19 -5
- package/lib/rules/common/spec.js +14 -3
- package/lib/rules/common/tags-alphabetical.js +1 -1
- package/lib/rules/oas2/index.d.ts +1 -1
- package/lib/rules/oas2/index.js +2 -2
- package/lib/rules/oas2/remove-unused-components.js +3 -3
- package/lib/rules/oas2/request-mime-type.js +1 -1
- package/lib/rules/oas2/response-mime-type.js +1 -1
- package/lib/rules/oas3/index.js +8 -4
- package/lib/rules/oas3/no-empty-servers.js +1 -1
- package/lib/rules/oas3/no-invalid-media-type-examples.js +2 -2
- package/lib/rules/oas3/no-server-variables-empty-enum.d.ts +2 -0
- package/lib/rules/oas3/{no-servers-empty-enum.js → no-server-variables-empty-enum.js} +5 -5
- package/lib/rules/oas3/no-unused-components.js +2 -2
- package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.d.ts +5 -0
- package/lib/rules/oas3/operation-4xx-problem-details-rfc7807.js +36 -0
- package/lib/rules/oas3/remove-unused-components.js +4 -4
- package/lib/rules/oas3/request-mime-type.js +1 -1
- package/lib/rules/oas3/response-mime-type.js +1 -1
- package/lib/rules/oas3/spec-components-invalid-map-name.d.ts +2 -0
- package/lib/rules/oas3/spec-components-invalid-map-name.js +46 -0
- package/lib/rules/other/stats.d.ts +2 -2
- package/lib/rules/other/stats.js +2 -2
- package/lib/rules/utils.d.ts +3 -2
- package/lib/rules/utils.js +16 -4
- package/lib/types/oas2.js +5 -5
- package/lib/types/oas3.js +27 -20
- package/lib/types/oas3_1.js +3 -3
- package/lib/types/redocly-yaml.js +47 -56
- package/lib/utils.d.ts +6 -1
- package/lib/utils.js +24 -7
- package/lib/visitors.d.ts +12 -12
- package/lib/visitors.js +15 -3
- package/lib/walk.d.ts +2 -1
- package/lib/walk.js +6 -3
- package/package.json +2 -2
- package/src/__tests__/__snapshots__/bundle.test.ts.snap +3 -3
- package/src/__tests__/fixtures/extension.js +3 -3
- package/src/__tests__/format.test.ts +76 -0
- package/src/__tests__/lint.test.ts +106 -131
- package/src/__tests__/logger-browser.test.ts +53 -0
- package/src/__tests__/logger.test.ts +47 -0
- package/src/__tests__/output-browser.test.ts +18 -0
- package/src/__tests__/output.test.ts +15 -0
- package/src/__tests__/resolve-http.test.ts +1 -1
- package/src/__tests__/resolve.test.ts +9 -9
- package/src/__tests__/utils-browser.test.ts +11 -0
- package/src/__tests__/utils.test.ts +7 -0
- package/src/__tests__/walk.test.ts +78 -10
- package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +0 -1
- package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
- package/src/bundle.ts +10 -7
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +12 -6
- package/src/config/__tests__/config.test.ts +35 -0
- package/src/config/__tests__/fixtures/plugin-config.yaml +2 -3
- package/src/config/__tests__/fixtures/resolve-config/api/nested-config.yaml +11 -12
- package/src/config/__tests__/fixtures/resolve-config/local-config-with-circular.yaml +7 -8
- package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +18 -19
- package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +9 -10
- package/src/config/__tests__/fixtures/resolve-remote-configs/nested-remote-config.yaml +3 -4
- package/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml +4 -5
- package/src/config/__tests__/load.test.ts +76 -1
- package/src/config/__tests__/utils.test.ts +64 -4
- package/src/config/all.ts +5 -3
- package/src/config/config-resolvers.ts +45 -19
- package/src/config/config.ts +10 -8
- package/src/config/load.ts +31 -7
- package/src/config/minimal.ts +7 -4
- package/src/config/recommended.ts +7 -4
- package/src/config/rules.ts +2 -2
- package/src/config/types.ts +11 -0
- package/src/config/utils.ts +115 -25
- package/src/decorators/common/registry-dependencies.ts +2 -2
- package/src/env.ts +5 -0
- package/src/format/codeframes.ts +15 -9
- package/src/format/format.ts +59 -34
- package/src/index.ts +6 -4
- package/src/js-yaml/index.ts +1 -0
- package/src/lint.ts +2 -2
- package/src/logger.ts +34 -0
- package/src/output.ts +7 -0
- package/src/redocly/index.ts +7 -4
- package/src/redocly/registry-api-types.ts +27 -29
- package/src/redocly/registry-api.ts +18 -7
- package/src/ref-utils.ts +2 -1
- package/src/resolve.ts +7 -5
- package/src/rules/__tests__/utils.test.ts +39 -1
- package/src/rules/ajv.ts +7 -7
- package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +1 -0
- package/src/rules/common/__tests__/operation-2xx-response.test.ts +1 -1
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +26 -3
- package/src/rules/common/__tests__/security-defined.test.ts +175 -0
- package/src/rules/common/__tests__/spec.test.ts +79 -0
- package/src/rules/common/assertions/__tests__/utils.test.ts +2 -2
- package/src/rules/common/assertions/asserts.ts +4 -4
- package/src/rules/common/assertions/index.ts +1 -1
- package/src/rules/common/no-ambiguous-paths.ts +1 -1
- package/src/rules/common/no-identical-paths.ts +1 -1
- package/src/rules/common/no-invalid-parameter-examples.ts +4 -4
- package/src/rules/common/no-invalid-schema-examples.ts +4 -4
- package/src/rules/common/operation-2xx-response.ts +1 -1
- package/src/rules/common/operation-4xx-response.ts +1 -1
- package/src/rules/common/operation-operationId.ts +1 -1
- package/src/rules/common/operation-tag-defined.ts +1 -1
- package/src/rules/common/path-not-include-query.ts +1 -1
- package/src/rules/common/{operation-security-defined.ts → security-defined.ts} +20 -5
- package/src/rules/common/spec.ts +17 -3
- package/src/rules/common/tags-alphabetical.ts +1 -1
- package/src/rules/oas2/index.ts +2 -2
- package/src/rules/oas2/remove-unused-components.ts +3 -3
- package/src/rules/oas2/request-mime-type.ts +1 -1
- package/src/rules/oas2/response-mime-type.ts +1 -1
- package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +16 -16
- package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +5 -5
- package/src/rules/oas3/__tests__/operation-4xx-problem-details-rfc7807.test.ts +145 -0
- package/src/rules/oas3/__tests__/spec/spec.test.ts +10 -0
- package/src/rules/oas3/__tests__/spec-components-invalid-map-name.test.ts +217 -0
- package/src/rules/oas3/index.ts +8 -4
- package/src/rules/oas3/no-empty-servers.ts +1 -1
- package/src/rules/oas3/no-invalid-media-type-examples.ts +3 -3
- package/src/rules/oas3/{no-servers-empty-enum.ts → no-server-variables-empty-enum.ts} +3 -3
- package/src/rules/oas3/no-unused-components.ts +2 -2
- package/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +36 -0
- package/src/rules/oas3/remove-unused-components.ts +5 -5
- package/src/rules/oas3/request-mime-type.ts +1 -1
- package/src/rules/oas3/response-mime-type.ts +1 -1
- package/src/rules/oas3/spec-components-invalid-map-name.ts +53 -0
- package/src/rules/other/stats.ts +2 -2
- package/src/rules/utils.ts +17 -3
- package/src/types/index.ts +2 -2
- package/src/types/oas2.ts +5 -5
- package/src/types/oas3.ts +27 -20
- package/src/types/oas3_1.ts +3 -3
- package/src/types/redocly-yaml.ts +53 -41
- package/src/utils.ts +31 -4
- package/src/visitors.ts +34 -18
- package/src/walk.ts +15 -11
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/rules/common/operation-security-defined.d.ts +0 -2
- package/lib/rules/oas3/no-servers-empty-enum.d.ts +0 -2
- package/src/rules/common/__tests__/operation-security-defined.test.ts +0 -69
package/src/rules/common/spec.ts
CHANGED
|
@@ -6,13 +6,18 @@ import { isPlainObject } from '../../utils';
|
|
|
6
6
|
|
|
7
7
|
export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
8
8
|
return {
|
|
9
|
-
any(
|
|
9
|
+
any(
|
|
10
|
+
node: any,
|
|
11
|
+
{ report, type, location, rawLocation, key, resolve, ignoreNextVisitorsOnNode }
|
|
12
|
+
) {
|
|
10
13
|
const nodeType = oasTypeOf(node);
|
|
14
|
+
const refLocation = rawLocation !== location ? rawLocation : undefined;
|
|
11
15
|
|
|
12
16
|
if (type.items) {
|
|
13
17
|
if (nodeType !== 'array') {
|
|
14
18
|
report({
|
|
15
19
|
message: `Expected type \`${type.name}\` (array) but got \`${nodeType}\``,
|
|
20
|
+
from: refLocation,
|
|
16
21
|
});
|
|
17
22
|
ignoreNextVisitorsOnNode();
|
|
18
23
|
}
|
|
@@ -20,6 +25,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
20
25
|
} else if (nodeType !== 'object') {
|
|
21
26
|
report({
|
|
22
27
|
message: `Expected type \`${type.name}\` (object) but got \`${nodeType}\``,
|
|
28
|
+
from: refLocation,
|
|
23
29
|
});
|
|
24
30
|
ignoreNextVisitorsOnNode();
|
|
25
31
|
return;
|
|
@@ -28,10 +34,11 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
28
34
|
const required =
|
|
29
35
|
typeof type.required === 'function' ? type.required(node, key) : type.required;
|
|
30
36
|
|
|
31
|
-
for (
|
|
37
|
+
for (const propName of required || []) {
|
|
32
38
|
if (!(node as object).hasOwnProperty(propName)) {
|
|
33
39
|
report({
|
|
34
40
|
message: `The field \`${propName}\` must be present on this level.`,
|
|
41
|
+
from: refLocation,
|
|
35
42
|
location: [{ reportOnKey: true }],
|
|
36
43
|
});
|
|
37
44
|
}
|
|
@@ -49,6 +56,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
49
56
|
}
|
|
50
57
|
report({
|
|
51
58
|
message: `The field \`${propName}\` is not allowed here.`,
|
|
59
|
+
from: refLocation,
|
|
52
60
|
location: location.child([propName]).key(),
|
|
53
61
|
});
|
|
54
62
|
}
|
|
@@ -57,7 +65,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
57
65
|
const requiredOneOf = type.requiredOneOf || null;
|
|
58
66
|
if (requiredOneOf) {
|
|
59
67
|
let hasProperty = false;
|
|
60
|
-
for (
|
|
68
|
+
for (const propName of requiredOneOf || []) {
|
|
61
69
|
if ((node as object).hasOwnProperty(propName)) {
|
|
62
70
|
hasProperty = true;
|
|
63
71
|
}
|
|
@@ -67,6 +75,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
67
75
|
message: `Must contain at least one of the following fields: ${type.requiredOneOf?.join(
|
|
68
76
|
', '
|
|
69
77
|
)}.`,
|
|
78
|
+
from: refLocation,
|
|
70
79
|
location: [{ reportOnKey: true }],
|
|
71
80
|
});
|
|
72
81
|
}
|
|
@@ -91,6 +100,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
91
100
|
report({
|
|
92
101
|
message: `Property \`${propName}\` is not expected here.`,
|
|
93
102
|
suggest: getSuggest(propName, Object.keys(type.properties)),
|
|
103
|
+
from: refLocation,
|
|
94
104
|
location: propLocation.key(),
|
|
95
105
|
});
|
|
96
106
|
continue;
|
|
@@ -111,12 +121,14 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
111
121
|
message: `\`${propName}\` can be one of the following only: ${propSchema.enum
|
|
112
122
|
.map((i) => `"${i}"`)
|
|
113
123
|
.join(', ')}.`,
|
|
124
|
+
from: refLocation,
|
|
114
125
|
suggest: getSuggest(propValue, propSchema.enum),
|
|
115
126
|
});
|
|
116
127
|
}
|
|
117
128
|
} else if (propSchema.type && !matchesJsonSchemaType(propValue, propSchema.type, false)) {
|
|
118
129
|
report({
|
|
119
130
|
message: `Expected type \`${propSchema.type}\` but got \`${propValueType}\`.`,
|
|
131
|
+
from: refLocation,
|
|
120
132
|
location: propLocation,
|
|
121
133
|
});
|
|
122
134
|
} else if (propValueType === 'array' && propSchema.items?.type) {
|
|
@@ -126,6 +138,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
126
138
|
if (!matchesJsonSchemaType(item, itemsType, false)) {
|
|
127
139
|
report({
|
|
128
140
|
message: `Expected type \`${itemsType}\` but got \`${oasTypeOf(item)}\`.`,
|
|
141
|
+
from: refLocation,
|
|
129
142
|
location: propLocation.child([i]),
|
|
130
143
|
});
|
|
131
144
|
}
|
|
@@ -136,6 +149,7 @@ export const OasSpec: Oas3Rule | Oas2Rule = () => {
|
|
|
136
149
|
if (propSchema.minimum > node[propName]) {
|
|
137
150
|
report({
|
|
138
151
|
message: `The value of the ${propName} field must be greater than or equal to ${propSchema.minimum}`,
|
|
152
|
+
from: refLocation,
|
|
139
153
|
location: location.child([propName]),
|
|
140
154
|
});
|
|
141
155
|
}
|
|
@@ -5,7 +5,7 @@ import { UserContext } from '../../walk';
|
|
|
5
5
|
|
|
6
6
|
export const TagsAlphabetical: Oas3Rule | Oas2Rule = () => {
|
|
7
7
|
return {
|
|
8
|
-
|
|
8
|
+
Root(root: Oas2Definition | Oas3Definition, { report, location }: UserContext) {
|
|
9
9
|
if (!root.tags) return;
|
|
10
10
|
for (let i = 0; i < root.tags.length - 1; i++) {
|
|
11
11
|
if (root.tags[i].name > root.tags[i + 1].name) {
|
package/src/rules/oas2/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { OperationDescription } from '../common/operation-description';
|
|
|
25
25
|
import { PathNotIncludeQuery } from '../common/path-not-include-query';
|
|
26
26
|
import { ParameterDescription } from '../common/parameter-description';
|
|
27
27
|
import { OperationSingularTag } from '../common/operation-singular-tag';
|
|
28
|
-
import {
|
|
28
|
+
import { SecurityDefined } from '../common/security-defined';
|
|
29
29
|
import { NoUnresolvedRefs } from '../no-unresolved-refs';
|
|
30
30
|
import { PathHttpVerbsOrder } from '../common/path-http-verbs-order';
|
|
31
31
|
import { NoIdenticalPaths } from '../common/no-identical-paths';
|
|
@@ -71,7 +71,7 @@ export const rules = {
|
|
|
71
71
|
'path-params-defined': PathParamsDefined as Oas2Rule,
|
|
72
72
|
'parameter-description': ParameterDescription as Oas2Rule,
|
|
73
73
|
'operation-singular-tag': OperationSingularTag as Oas2Rule,
|
|
74
|
-
'
|
|
74
|
+
'security-defined': SecurityDefined as Oas2Rule,
|
|
75
75
|
'no-unresolved-refs': NoUnresolvedRefs as Oas2Rule,
|
|
76
76
|
'no-identical-paths': NoIdenticalPaths as Oas2Rule,
|
|
77
77
|
'no-ambiguous-paths': NoAmbiguousPaths as Oas2Rule,
|
|
@@ -4,7 +4,7 @@ import { Oas2Components } from '../../typings/swagger';
|
|
|
4
4
|
import { isEmptyObject } from '../../utils';
|
|
5
5
|
|
|
6
6
|
export const RemoveUnusedComponents: Oas2Rule = () => {
|
|
7
|
-
|
|
7
|
+
const components = new Map<
|
|
8
8
|
string,
|
|
9
9
|
{ used: boolean; componentType?: keyof Oas2Components; name: string }
|
|
10
10
|
>();
|
|
@@ -34,12 +34,12 @@ export const RemoveUnusedComponents: Oas2Rule = () => {
|
|
|
34
34
|
}
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
|
-
|
|
37
|
+
Root: {
|
|
38
38
|
leave(root, ctx) {
|
|
39
39
|
const data = ctx.getVisitorData() as { removedCount: number };
|
|
40
40
|
data.removedCount = 0;
|
|
41
41
|
|
|
42
|
-
|
|
42
|
+
const rootComponents = new Set<keyof Oas2Components>();
|
|
43
43
|
components.forEach((usageInfo) => {
|
|
44
44
|
const { used, name, componentType } = usageInfo;
|
|
45
45
|
if (!used && componentType) {
|
|
@@ -5,7 +5,7 @@ import { validateMimeType } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const RequestMimeType: Oas2Rule = ({ allowedValues }) => {
|
|
7
7
|
return {
|
|
8
|
-
|
|
8
|
+
Root(root: Oas2Definition, ctx: UserContext) {
|
|
9
9
|
validateMimeType({ type: 'consumes', value: root }, ctx, allowedValues);
|
|
10
10
|
},
|
|
11
11
|
Operation: {
|
|
@@ -5,7 +5,7 @@ import { validateMimeType } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const ResponseMimeType: Oas2Rule = ({ allowedValues }) => {
|
|
7
7
|
return {
|
|
8
|
-
|
|
8
|
+
Root(root: Oas2Definition, ctx: UserContext) {
|
|
9
9
|
validateMimeType({ type: 'produces', value: root }, ctx, allowedValues);
|
|
10
10
|
},
|
|
11
11
|
Operation: {
|
|
@@ -3,8 +3,8 @@ import { lintDocument } from '../../../lint';
|
|
|
3
3
|
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
4
4
|
import { BaseResolver } from '../../../resolve';
|
|
5
5
|
|
|
6
|
-
describe('Oas3 as3-no-
|
|
7
|
-
it('oas3-no-
|
|
6
|
+
describe('Oas3 as3-no-server-variables-empty-enum', () => {
|
|
7
|
+
it('oas3-no-server-variables-empty-enum: should report on server object with empty enum and unknown enum value', async () => {
|
|
8
8
|
const document = parseYamlToDocument(
|
|
9
9
|
outdent`
|
|
10
10
|
openapi: 3.0.0
|
|
@@ -24,7 +24,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
24
24
|
const results = await lintDocument({
|
|
25
25
|
externalRefResolver: new BaseResolver(),
|
|
26
26
|
document,
|
|
27
|
-
config: await makeConfig({ 'no-
|
|
27
|
+
config: await makeConfig({ 'no-server-variables-empty-enum': 'error' }),
|
|
28
28
|
});
|
|
29
29
|
|
|
30
30
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
@@ -38,7 +38,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
38
38
|
},
|
|
39
39
|
],
|
|
40
40
|
"message": "Server variable with \`enum\` must be a non-empty array.",
|
|
41
|
-
"ruleId": "no-
|
|
41
|
+
"ruleId": "no-server-variables-empty-enum",
|
|
42
42
|
"severity": "error",
|
|
43
43
|
"suggest": Array [],
|
|
44
44
|
},
|
|
@@ -51,7 +51,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
51
51
|
},
|
|
52
52
|
],
|
|
53
53
|
"message": "Server variable define \`enum\` and \`default\`. \`enum\` must include default value",
|
|
54
|
-
"ruleId": "no-
|
|
54
|
+
"ruleId": "no-server-variables-empty-enum",
|
|
55
55
|
"severity": "error",
|
|
56
56
|
"suggest": Array [],
|
|
57
57
|
},
|
|
@@ -59,7 +59,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
59
59
|
`);
|
|
60
60
|
});
|
|
61
61
|
|
|
62
|
-
it('oas3-no-
|
|
62
|
+
it('oas3-no-server-variables-empty-enum: should report on server object with empty enum', async () => {
|
|
63
63
|
const document = parseYamlToDocument(
|
|
64
64
|
outdent`
|
|
65
65
|
openapi: 3.0.0
|
|
@@ -78,7 +78,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
78
78
|
const results = await lintDocument({
|
|
79
79
|
externalRefResolver: new BaseResolver(),
|
|
80
80
|
document,
|
|
81
|
-
config: await makeConfig({ 'no-
|
|
81
|
+
config: await makeConfig({ 'no-server-variables-empty-enum': 'error' }),
|
|
82
82
|
});
|
|
83
83
|
|
|
84
84
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
@@ -92,7 +92,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
92
92
|
},
|
|
93
93
|
],
|
|
94
94
|
"message": "Server variable with \`enum\` must be a non-empty array.",
|
|
95
|
-
"ruleId": "no-
|
|
95
|
+
"ruleId": "no-server-variables-empty-enum",
|
|
96
96
|
"severity": "error",
|
|
97
97
|
"suggest": Array [],
|
|
98
98
|
},
|
|
@@ -100,7 +100,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
100
100
|
`);
|
|
101
101
|
});
|
|
102
102
|
|
|
103
|
-
it('oas3-no-
|
|
103
|
+
it('oas3-no-server-variables-empty-enum: should be success because variables is empty object', async () => {
|
|
104
104
|
const document = parseYamlToDocument(
|
|
105
105
|
outdent`
|
|
106
106
|
openapi: 3.0.0
|
|
@@ -117,13 +117,13 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
117
117
|
const results = await lintDocument({
|
|
118
118
|
externalRefResolver: new BaseResolver(),
|
|
119
119
|
document,
|
|
120
|
-
config: await makeConfig({ 'no-
|
|
120
|
+
config: await makeConfig({ 'no-server-variables-empty-enum': 'error' }),
|
|
121
121
|
});
|
|
122
122
|
|
|
123
123
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`Array []`);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
|
-
it('oas3-no-
|
|
126
|
+
it('oas3-no-server-variables-empty-enum: should be success because variable is empty object', async () => {
|
|
127
127
|
const document = parseYamlToDocument(
|
|
128
128
|
outdent`
|
|
129
129
|
openapi: 3.0.0
|
|
@@ -141,13 +141,13 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
141
141
|
const results = await lintDocument({
|
|
142
142
|
externalRefResolver: new BaseResolver(),
|
|
143
143
|
document,
|
|
144
|
-
config: await makeConfig({ 'no-
|
|
144
|
+
config: await makeConfig({ 'no-server-variables-empty-enum': 'error' }),
|
|
145
145
|
});
|
|
146
146
|
|
|
147
147
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`Array []`);
|
|
148
148
|
});
|
|
149
149
|
|
|
150
|
-
it('oas3-no-
|
|
150
|
+
it('oas3-no-server-variables-empty-enum: should be success because enum contains default value', async () => {
|
|
151
151
|
const document = parseYamlToDocument(
|
|
152
152
|
outdent`
|
|
153
153
|
openapi: 3.0.0
|
|
@@ -168,13 +168,13 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
168
168
|
const results = await lintDocument({
|
|
169
169
|
externalRefResolver: new BaseResolver(),
|
|
170
170
|
document,
|
|
171
|
-
config: await makeConfig({ 'no-
|
|
171
|
+
config: await makeConfig({ 'no-server-variables-empty-enum': 'error' }),
|
|
172
172
|
});
|
|
173
173
|
|
|
174
174
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`Array []`);
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
-
it('oas3-no-
|
|
177
|
+
it('oas3-no-server-variables-empty-enum: should be success because enum contains default value', async () => {
|
|
178
178
|
const document = parseYamlToDocument(
|
|
179
179
|
outdent`
|
|
180
180
|
openapi: 3.0.0
|
|
@@ -197,7 +197,7 @@ describe('Oas3 as3-no-servers-empty-enum', () => {
|
|
|
197
197
|
const results = await lintDocument({
|
|
198
198
|
externalRefResolver: new BaseResolver(),
|
|
199
199
|
document,
|
|
200
|
-
config: await makeConfig({ 'no-
|
|
200
|
+
config: await makeConfig({ 'no-server-variables-empty-enum': 'error' }),
|
|
201
201
|
});
|
|
202
202
|
|
|
203
203
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`Array []`);
|
|
@@ -76,7 +76,7 @@ describe('no-invalid-media-type-examples', () => {
|
|
|
76
76
|
`);
|
|
77
77
|
});
|
|
78
78
|
|
|
79
|
-
it('should report on invalid example with
|
|
79
|
+
it('should report on invalid example with allowAdditionalProperties', async () => {
|
|
80
80
|
const document = parseYamlToDocument(
|
|
81
81
|
outdent`
|
|
82
82
|
openapi: 3.0.0
|
|
@@ -109,7 +109,7 @@ describe('no-invalid-media-type-examples', () => {
|
|
|
109
109
|
config: await makeConfig({
|
|
110
110
|
'no-invalid-media-type-examples': {
|
|
111
111
|
severity: 'error',
|
|
112
|
-
|
|
112
|
+
allowAdditionalProperties: false,
|
|
113
113
|
},
|
|
114
114
|
}),
|
|
115
115
|
});
|
|
@@ -137,7 +137,7 @@ describe('no-invalid-media-type-examples', () => {
|
|
|
137
137
|
`);
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
-
it('should not on invalid example with
|
|
140
|
+
it('should not on invalid example with allowAdditionalProperties', async () => {
|
|
141
141
|
const document = parseYamlToDocument(
|
|
142
142
|
outdent`
|
|
143
143
|
openapi: 3.0.0
|
|
@@ -169,7 +169,7 @@ describe('no-invalid-media-type-examples', () => {
|
|
|
169
169
|
config: await makeConfig({
|
|
170
170
|
'no-invalid-media-type-examples': {
|
|
171
171
|
severity: 'error',
|
|
172
|
-
|
|
172
|
+
allowAdditionalProperties: false,
|
|
173
173
|
},
|
|
174
174
|
}),
|
|
175
175
|
});
|
|
@@ -219,7 +219,7 @@ describe('no-invalid-media-type-examples', () => {
|
|
|
219
219
|
config: await makeConfig({
|
|
220
220
|
'no-invalid-media-type-examples': {
|
|
221
221
|
severity: 'error',
|
|
222
|
-
|
|
222
|
+
allowAdditionalProperties: false,
|
|
223
223
|
},
|
|
224
224
|
}),
|
|
225
225
|
});
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { outdent } from 'outdent';
|
|
2
|
+
import { lintDocument } from '../../../lint';
|
|
3
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../../../__tests__/utils';
|
|
4
|
+
import { BaseResolver } from '../../../resolve';
|
|
5
|
+
|
|
6
|
+
describe('Oas3 operation-4xx-problem-details-rfc7807', () => {
|
|
7
|
+
it('should report `4xx` must have content type `application/problem+json` ', async () => {
|
|
8
|
+
const document = parseYamlToDocument(
|
|
9
|
+
outdent`
|
|
10
|
+
openapi: "3.0.0"
|
|
11
|
+
paths:
|
|
12
|
+
/pets:
|
|
13
|
+
get:
|
|
14
|
+
summary: List all pets
|
|
15
|
+
operationId: listPets
|
|
16
|
+
responses:
|
|
17
|
+
'400':
|
|
18
|
+
description: Test
|
|
19
|
+
content:
|
|
20
|
+
application/json:
|
|
21
|
+
schema:
|
|
22
|
+
type: object
|
|
23
|
+
properties:
|
|
24
|
+
type:
|
|
25
|
+
type: string
|
|
26
|
+
title:
|
|
27
|
+
type: string
|
|
28
|
+
`,
|
|
29
|
+
'foobar.yaml'
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const results = await lintDocument({
|
|
33
|
+
externalRefResolver: new BaseResolver(),
|
|
34
|
+
document,
|
|
35
|
+
config: await makeConfig({ 'operation-4xx-problem-details-rfc7807': 'error' }),
|
|
36
|
+
});
|
|
37
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
38
|
+
Array [
|
|
39
|
+
Object {
|
|
40
|
+
"location": Array [
|
|
41
|
+
Object {
|
|
42
|
+
"pointer": "#/paths/~1pets/get/responses/400",
|
|
43
|
+
"reportOnKey": true,
|
|
44
|
+
"source": "foobar.yaml",
|
|
45
|
+
},
|
|
46
|
+
],
|
|
47
|
+
"message": "Response \`4xx\` must have content-type \`application/problem+json\`.",
|
|
48
|
+
"ruleId": "operation-4xx-problem-details-rfc7807",
|
|
49
|
+
"severity": "error",
|
|
50
|
+
"suggest": Array [],
|
|
51
|
+
},
|
|
52
|
+
]
|
|
53
|
+
`);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should report `application/problem+json` must have `type` property', async () => {
|
|
57
|
+
const document = parseYamlToDocument(
|
|
58
|
+
outdent`
|
|
59
|
+
openapi: "3.0.0"
|
|
60
|
+
paths:
|
|
61
|
+
/pets:
|
|
62
|
+
get:
|
|
63
|
+
summary: List all pets
|
|
64
|
+
operationId: listPets
|
|
65
|
+
responses:
|
|
66
|
+
'400':
|
|
67
|
+
description: Test
|
|
68
|
+
content:
|
|
69
|
+
application/problem+json:
|
|
70
|
+
schema:
|
|
71
|
+
type: object
|
|
72
|
+
properties:
|
|
73
|
+
title:
|
|
74
|
+
type: string
|
|
75
|
+
`,
|
|
76
|
+
'foobar.yaml'
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
const results = await lintDocument({
|
|
80
|
+
externalRefResolver: new BaseResolver(),
|
|
81
|
+
document,
|
|
82
|
+
config: await makeConfig({ 'operation-4xx-problem-details-rfc7807': 'error' }),
|
|
83
|
+
});
|
|
84
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
85
|
+
Array [
|
|
86
|
+
Object {
|
|
87
|
+
"location": Array [
|
|
88
|
+
Object {
|
|
89
|
+
"pointer": "#/paths/~1pets/get/responses/400/content/application~1problem+json/schema/properties/type",
|
|
90
|
+
"reportOnKey": true,
|
|
91
|
+
"source": "foobar.yaml",
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
"message": "SchemaProperties object should contain \`type\` field.",
|
|
95
|
+
"ruleId": "operation-4xx-problem-details-rfc7807",
|
|
96
|
+
"severity": "error",
|
|
97
|
+
"suggest": Array [],
|
|
98
|
+
},
|
|
99
|
+
]
|
|
100
|
+
`);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
it('should report `application/problem+json` must have `schema` property', async () => {
|
|
104
|
+
const document = parseYamlToDocument(
|
|
105
|
+
outdent`
|
|
106
|
+
openapi: "3.0.0"
|
|
107
|
+
paths:
|
|
108
|
+
/pets:
|
|
109
|
+
get:
|
|
110
|
+
summary: List all pets
|
|
111
|
+
operationId: listPets
|
|
112
|
+
responses:
|
|
113
|
+
'400':
|
|
114
|
+
description: Test
|
|
115
|
+
content:
|
|
116
|
+
application/problem+json:
|
|
117
|
+
example: asd
|
|
118
|
+
`,
|
|
119
|
+
'foobar.yaml'
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
const results = await lintDocument({
|
|
123
|
+
externalRefResolver: new BaseResolver(),
|
|
124
|
+
document,
|
|
125
|
+
config: await makeConfig({ 'operation-4xx-problem-details-rfc7807': 'error' }),
|
|
126
|
+
});
|
|
127
|
+
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
128
|
+
Array [
|
|
129
|
+
Object {
|
|
130
|
+
"location": Array [
|
|
131
|
+
Object {
|
|
132
|
+
"pointer": "#/paths/~1pets/get/responses/400/content/application~1problem+json/schema",
|
|
133
|
+
"reportOnKey": true,
|
|
134
|
+
"source": "foobar.yaml",
|
|
135
|
+
},
|
|
136
|
+
],
|
|
137
|
+
"message": "MediaType object should contain \`schema\` field.",
|
|
138
|
+
"ruleId": "operation-4xx-problem-details-rfc7807",
|
|
139
|
+
"severity": "error",
|
|
140
|
+
"suggest": Array [],
|
|
141
|
+
},
|
|
142
|
+
]
|
|
143
|
+
`);
|
|
144
|
+
});
|
|
145
|
+
});
|
|
@@ -47,6 +47,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
47
47
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
48
48
|
Array [
|
|
49
49
|
Object {
|
|
50
|
+
"from": undefined,
|
|
50
51
|
"location": Array [
|
|
51
52
|
Object {
|
|
52
53
|
"pointer": "#/info/contact/url",
|
|
@@ -60,6 +61,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
60
61
|
"suggest": Array [],
|
|
61
62
|
},
|
|
62
63
|
Object {
|
|
64
|
+
"from": undefined,
|
|
63
65
|
"location": Array [
|
|
64
66
|
Object {
|
|
65
67
|
"pointer": "#/info/contact/email",
|
|
@@ -73,6 +75,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
73
75
|
"suggest": Array [],
|
|
74
76
|
},
|
|
75
77
|
Object {
|
|
78
|
+
"from": undefined,
|
|
76
79
|
"location": Array [
|
|
77
80
|
Object {
|
|
78
81
|
"pointer": "#/info/license",
|
|
@@ -103,6 +106,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
103
106
|
"suggest": Array [],
|
|
104
107
|
},
|
|
105
108
|
Object {
|
|
109
|
+
"from": undefined,
|
|
106
110
|
"location": Array [
|
|
107
111
|
Object {
|
|
108
112
|
"pointer": "#/servers/0/variables/a/enum/0",
|
|
@@ -116,6 +120,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
116
120
|
"suggest": Array [],
|
|
117
121
|
},
|
|
118
122
|
Object {
|
|
123
|
+
"from": undefined,
|
|
119
124
|
"location": Array [
|
|
120
125
|
Object {
|
|
121
126
|
"pointer": "#/tags/0",
|
|
@@ -129,6 +134,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
129
134
|
"suggest": Array [],
|
|
130
135
|
},
|
|
131
136
|
Object {
|
|
137
|
+
"from": undefined,
|
|
132
138
|
"location": Array [
|
|
133
139
|
Object {
|
|
134
140
|
"pointer": "#/tags/1",
|
|
@@ -175,6 +181,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
175
181
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
176
182
|
Array [
|
|
177
183
|
Object {
|
|
184
|
+
"from": undefined,
|
|
178
185
|
"location": Array [
|
|
179
186
|
Object {
|
|
180
187
|
"pointer": "#/components1",
|
|
@@ -203,6 +210,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
203
210
|
"suggest": Array [],
|
|
204
211
|
},
|
|
205
212
|
Object {
|
|
213
|
+
"from": undefined,
|
|
206
214
|
"location": Array [
|
|
207
215
|
Object {
|
|
208
216
|
"pointer": "#/info/contact/test",
|
|
@@ -244,6 +252,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
244
252
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
245
253
|
Array [
|
|
246
254
|
Object {
|
|
255
|
+
"from": undefined,
|
|
247
256
|
"location": Array [
|
|
248
257
|
Object {
|
|
249
258
|
"pointer": "#/",
|
|
@@ -270,6 +279,7 @@ describe('Oas3 Structural visitor basic', () => {
|
|
|
270
279
|
"suggest": Array [],
|
|
271
280
|
},
|
|
272
281
|
Object {
|
|
282
|
+
"from": undefined,
|
|
273
283
|
"location": Array [
|
|
274
284
|
Object {
|
|
275
285
|
"pointer": "#/info",
|