@redocly/openapi-core 1.0.0-beta.108 → 1.0.0-beta.110
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/README.md +2 -2
- package/lib/benchmark/benches/resolve-with-no-external.bench.js +1 -1
- package/lib/bundle.d.ts +1 -1
- package/lib/bundle.js +4 -4
- package/lib/config/all.js +3 -1
- package/lib/config/config-resolvers.js +22 -4
- package/lib/config/config.d.ts +1 -0
- package/lib/config/config.js +1 -0
- package/lib/config/load.d.ts +8 -2
- package/lib/config/load.js +4 -2
- package/lib/config/minimal.js +3 -1
- package/lib/config/recommended.js +3 -1
- package/lib/config/rules.js +1 -1
- package/lib/config/types.d.ts +17 -0
- package/lib/config/utils.d.ts +2 -2
- package/lib/config/utils.js +44 -6
- package/lib/decorators/common/registry-dependencies.js +1 -1
- package/lib/format/format.d.ts +1 -1
- package/lib/format/format.js +22 -1
- package/lib/lint.js +2 -2
- package/lib/redocly/registry-api.d.ts +0 -1
- package/lib/redocly/registry-api.js +5 -4
- package/lib/resolve.js +3 -1
- package/lib/rules/ajv.d.ts +1 -1
- package/lib/rules/ajv.js +5 -5
- package/lib/rules/common/assertions/asserts.d.ts +3 -5
- package/lib/rules/common/assertions/asserts.js +137 -97
- package/lib/rules/common/assertions/index.js +2 -6
- package/lib/rules/common/assertions/utils.d.ts +12 -6
- package/lib/rules/common/assertions/utils.js +33 -20
- package/lib/rules/common/no-ambiguous-paths.js +1 -1
- package/lib/rules/common/no-identical-paths.js +1 -1
- 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} +18 -4
- package/lib/rules/common/spec.js +12 -1
- 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 +1 -1
- 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 +6 -2
- package/lib/rules/oas3/no-empty-servers.js +1 -1
- package/lib/rules/oas3/no-server-variables-empty-enum.js +1 -1
- package/lib/rules/oas3/no-unused-components.js +1 -1
- 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 +1 -1
- 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.js +1 -1
- 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 +60 -54
- package/lib/utils.d.ts +3 -3
- package/lib/utils.js +5 -5
- package/lib/visitors.d.ts +11 -11
- package/lib/visitors.js +13 -1
- package/package.json +3 -5
- 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 +184 -121
- package/src/__tests__/resolve-http.test.ts +1 -1
- package/src/__tests__/resolve.test.ts +9 -9
- package/src/__tests__/walk.test.ts +78 -10
- package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
- package/src/bundle.ts +4 -4
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +6 -2
- package/src/config/__tests__/config-resolvers.test.ts +37 -1
- package/src/config/__tests__/config.test.ts +5 -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-custom-function.yaml +16 -0
- package/src/config/__tests__/fixtures/resolve-config/local-config-with-file.yaml +18 -19
- package/src/config/__tests__/fixtures/resolve-config/local-config-with-wrong-custom-function.yaml +16 -0
- package/src/config/__tests__/fixtures/resolve-config/local-config.yaml +9 -10
- package/src/config/__tests__/fixtures/resolve-config/plugin.js +11 -0
- 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 +13 -16
- package/src/config/__tests__/resolve-plugins.test.ts +3 -3
- package/src/config/__tests__/utils.test.ts +64 -4
- package/src/config/all.ts +3 -1
- package/src/config/config-resolvers.ts +30 -7
- package/src/config/config.ts +2 -0
- package/src/config/load.ts +13 -6
- package/src/config/minimal.ts +3 -1
- package/src/config/recommended.ts +3 -1
- package/src/config/rules.ts +2 -2
- package/src/config/types.ts +24 -0
- package/src/config/utils.ts +103 -13
- package/src/decorators/common/registry-dependencies.ts +1 -1
- package/src/format/format.ts +32 -2
- package/src/lint.ts +2 -2
- package/src/redocly/registry-api.ts +5 -4
- package/src/resolve.ts +3 -1
- package/src/rules/__tests__/utils.test.ts +1 -1
- package/src/rules/ajv.ts +4 -4
- 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__/asserts.test.ts +491 -428
- package/src/rules/common/assertions/__tests__/utils.test.ts +2 -2
- package/src/rules/common/assertions/asserts.ts +155 -97
- package/src/rules/common/assertions/index.ts +2 -11
- package/src/rules/common/assertions/utils.ts +66 -36
- package/src/rules/common/no-ambiguous-paths.ts +1 -1
- package/src/rules/common/no-identical-paths.ts +1 -1
- 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} +19 -4
- package/src/rules/common/spec.ts +15 -1
- 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 +1 -1
- 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-invalid-media-type-examples.test.ts +51 -2
- 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 +6 -2
- package/src/rules/oas3/no-empty-servers.ts +1 -1
- package/src/rules/oas3/no-server-variables-empty-enum.ts +1 -1
- package/src/rules/oas3/no-unused-components.ts +1 -1
- package/src/rules/oas3/operation-4xx-problem-details-rfc7807.ts +36 -0
- package/src/rules/oas3/remove-unused-components.ts +1 -1
- 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 +2 -1
- 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 +66 -38
- package/src/utils.ts +11 -7
- package/src/visitors.ts +29 -13
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/rules/common/operation-security-defined.d.ts +0 -2
- package/src/rules/common/__tests__/operation-security-defined.test.ts +0 -69
package/src/rules/oas3/index.ts
CHANGED
|
@@ -25,7 +25,7 @@ import { NoUnusedComponents } from './no-unused-components';
|
|
|
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 { BooleanParameterPrefixes } from './boolean-parameter-prefixes';
|
|
31
31
|
import { PathsKebabCase } from '../common/paths-kebab-case';
|
|
@@ -48,6 +48,8 @@ import { NoInvalidParameterExamples } from '../common/no-invalid-parameter-examp
|
|
|
48
48
|
import { ResponseContainsHeader } from '../common/response-contains-header';
|
|
49
49
|
import { ResponseContainsProperty } from './response-contains-property';
|
|
50
50
|
import { ScalarPropertyMissingExample } from '../common/scalar-property-missing-example';
|
|
51
|
+
import { SpecComponentsInvalidMapName } from './spec-components-invalid-map-name';
|
|
52
|
+
import { Operation4xxProblemDetailsRfc7807 } from './operation-4xx-problem-details-rfc7807';
|
|
51
53
|
|
|
52
54
|
export const rules = {
|
|
53
55
|
spec: OasSpec,
|
|
@@ -57,6 +59,7 @@ export const rules = {
|
|
|
57
59
|
'info-license-url': InfoLicenseUrl,
|
|
58
60
|
'operation-2xx-response': Operation2xxResponse,
|
|
59
61
|
'operation-4xx-response': Operation4xxResponse,
|
|
62
|
+
'operation-4xx-problem-details-rfc7807': Operation4xxProblemDetailsRfc7807,
|
|
60
63
|
assertions: Assertions,
|
|
61
64
|
'operation-operationId-unique': OperationIdUnique,
|
|
62
65
|
'operation-parameters-unique': OperationParametersUnique,
|
|
@@ -80,7 +83,7 @@ export const rules = {
|
|
|
80
83
|
'path-params-defined': PathParamsDefined,
|
|
81
84
|
'parameter-description': ParameterDescription,
|
|
82
85
|
'operation-singular-tag': OperationSingularTag,
|
|
83
|
-
'
|
|
86
|
+
'security-defined': SecurityDefined,
|
|
84
87
|
'no-unresolved-refs': NoUnresolvedRefs,
|
|
85
88
|
'paths-kebab-case': PathsKebabCase,
|
|
86
89
|
'boolean-parameter-prefixes': BooleanParameterPrefixes,
|
|
@@ -100,6 +103,7 @@ export const rules = {
|
|
|
100
103
|
'response-contains-header': ResponseContainsHeader,
|
|
101
104
|
'response-contains-property': ResponseContainsProperty,
|
|
102
105
|
'scalar-property-missing-example': ScalarPropertyMissingExample,
|
|
106
|
+
'spec-components-invalid-map-name': SpecComponentsInvalidMapName,
|
|
103
107
|
} as Oas3RuleSet;
|
|
104
108
|
|
|
105
109
|
export const preprocessors = {};
|
|
@@ -2,7 +2,7 @@ import { Oas3Rule } from '../../visitors';
|
|
|
2
2
|
|
|
3
3
|
export const NoEmptyServers: Oas3Rule = () => {
|
|
4
4
|
return {
|
|
5
|
-
|
|
5
|
+
Root(root, { report, location }) {
|
|
6
6
|
if (!root.hasOwnProperty('servers')) {
|
|
7
7
|
report({
|
|
8
8
|
message: 'Servers must be present.',
|
|
@@ -8,7 +8,7 @@ enum enumError {
|
|
|
8
8
|
|
|
9
9
|
export const NoServerVariablesEmptyEnum: Oas3Rule = () => {
|
|
10
10
|
return {
|
|
11
|
-
|
|
11
|
+
Root(root, { report, location }) {
|
|
12
12
|
if (!root.servers || root.servers.length === 0) return;
|
|
13
13
|
|
|
14
14
|
const invalidVariables: enumError[] = [];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Oas3MediaType, Oas3Response, Oas3Schema } from 'core/src/typings/openapi';
|
|
2
|
+
import { Oas3Rule } from '../../visitors';
|
|
3
|
+
import { UserContext } from '../../walk';
|
|
4
|
+
import { validateDefinedAndNonEmpty } from '../utils';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Validation according rfc7807 - https://datatracker.ietf.org/doc/html/rfc7807
|
|
8
|
+
*/
|
|
9
|
+
export const Operation4xxProblemDetailsRfc7807: Oas3Rule = () => {
|
|
10
|
+
return {
|
|
11
|
+
Response: {
|
|
12
|
+
skip(_response: Oas3Response, key: string | number) {
|
|
13
|
+
return !/4[Xx0-9]{2}/.test(`${key}`);
|
|
14
|
+
},
|
|
15
|
+
enter(response: Oas3Response, { report, location }: UserContext) {
|
|
16
|
+
if (!response.content || !response.content['application/problem+json'])
|
|
17
|
+
report({
|
|
18
|
+
message: 'Response `4xx` must have content-type `application/problem+json`.',
|
|
19
|
+
location: location.key(),
|
|
20
|
+
});
|
|
21
|
+
},
|
|
22
|
+
MediaType: {
|
|
23
|
+
skip(_response: Oas3MediaType, key: string | number) {
|
|
24
|
+
return key !== 'application/problem+json';
|
|
25
|
+
},
|
|
26
|
+
enter(media: Oas3MediaType, ctx: UserContext) {
|
|
27
|
+
validateDefinedAndNonEmpty('schema', media, ctx);
|
|
28
|
+
},
|
|
29
|
+
SchemaProperties(schema: Oas3Schema, ctx: UserContext) {
|
|
30
|
+
validateDefinedAndNonEmpty('type', schema, ctx);
|
|
31
|
+
validateDefinedAndNonEmpty('title', schema, ctx);
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
@@ -5,7 +5,7 @@ import { validateMimeTypeOAS3 } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const RequestMimeType: Oas3Rule = ({ allowedValues }) => {
|
|
7
7
|
return {
|
|
8
|
-
|
|
8
|
+
PathsMap: {
|
|
9
9
|
RequestBody: {
|
|
10
10
|
leave(requestBody: Oas3RequestBody, ctx: UserContext) {
|
|
11
11
|
validateMimeTypeOAS3({ type: 'consumes', value: requestBody }, ctx, allowedValues);
|
|
@@ -5,7 +5,7 @@ import { validateMimeTypeOAS3 } from '../../utils';
|
|
|
5
5
|
|
|
6
6
|
export const ResponseMimeType: Oas3Rule = ({ allowedValues }) => {
|
|
7
7
|
return {
|
|
8
|
-
|
|
8
|
+
PathsMap: {
|
|
9
9
|
Response: {
|
|
10
10
|
leave(response: Oas3Response, ctx: UserContext) {
|
|
11
11
|
validateMimeTypeOAS3({ type: 'produces', value: response }, ctx, allowedValues);
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { Oas3Rule } from '../../visitors';
|
|
2
|
+
import { Problem, UserContext } from '../../walk';
|
|
3
|
+
import { Location } from '../../ref-utils';
|
|
4
|
+
|
|
5
|
+
export const SpecComponentsInvalidMapName: Oas3Rule = () => {
|
|
6
|
+
const KEYS_REGEX = '^[a-zA-Z0-9\\.\\-_]+$';
|
|
7
|
+
|
|
8
|
+
function validateKey(
|
|
9
|
+
key: string | number,
|
|
10
|
+
report: (problem: Problem) => void,
|
|
11
|
+
location: Location,
|
|
12
|
+
component: string
|
|
13
|
+
) {
|
|
14
|
+
if (!new RegExp(KEYS_REGEX).test(key as string)) {
|
|
15
|
+
report({
|
|
16
|
+
message: `The map key in ${component} "${key}" does not match the regular expression "${KEYS_REGEX}"`,
|
|
17
|
+
location: location.key(),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
return {
|
|
23
|
+
Components: {
|
|
24
|
+
Parameter(_node, { key, report, location }: UserContext) {
|
|
25
|
+
validateKey(key, report, location, 'parameters');
|
|
26
|
+
},
|
|
27
|
+
Response(_node, { key, report, location }: UserContext) {
|
|
28
|
+
validateKey(key, report, location, 'responses');
|
|
29
|
+
},
|
|
30
|
+
Schema(_node, { key, report, location }: UserContext) {
|
|
31
|
+
validateKey(key, report, location, 'schemas');
|
|
32
|
+
},
|
|
33
|
+
Example(_node, { key, report, location }: UserContext) {
|
|
34
|
+
validateKey(key, report, location, 'examples');
|
|
35
|
+
},
|
|
36
|
+
RequestBody(_node, { key, report, location }: UserContext) {
|
|
37
|
+
validateKey(key, report, location, 'requestBodies');
|
|
38
|
+
},
|
|
39
|
+
Header(_node, { key, report, location }: UserContext) {
|
|
40
|
+
validateKey(key, report, location, 'headers');
|
|
41
|
+
},
|
|
42
|
+
SecurityScheme(_node, { key, report, location }: UserContext) {
|
|
43
|
+
validateKey(key, report, location, 'securitySchemas');
|
|
44
|
+
},
|
|
45
|
+
Link(_node, { key, report, location }: UserContext) {
|
|
46
|
+
validateKey(key, report, location, 'links');
|
|
47
|
+
},
|
|
48
|
+
Callback(_node, { key, report, location }: UserContext) {
|
|
49
|
+
validateKey(key, report, location, 'callbacks');
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
};
|
package/src/rules/other/stats.ts
CHANGED
|
@@ -24,7 +24,7 @@ export const Stats = (statsAccumulator: StatsAccumulator) => {
|
|
|
24
24
|
statsAccumulator.links.items!.add(link.operationId);
|
|
25
25
|
},
|
|
26
26
|
},
|
|
27
|
-
|
|
27
|
+
Root: {
|
|
28
28
|
leave() {
|
|
29
29
|
statsAccumulator.parameters.total = statsAccumulator.parameters.items!.size;
|
|
30
30
|
statsAccumulator.refs.total = statsAccumulator.refs.items!.size;
|
|
@@ -41,7 +41,7 @@ export const Stats = (statsAccumulator: StatsAccumulator) => {
|
|
|
41
41
|
},
|
|
42
42
|
},
|
|
43
43
|
},
|
|
44
|
-
|
|
44
|
+
PathsMap: {
|
|
45
45
|
PathItem: {
|
|
46
46
|
leave() {
|
|
47
47
|
statsAccumulator.pathItems.total++;
|
package/src/rules/utils.ts
CHANGED
|
@@ -109,7 +109,8 @@ export function validateExample(
|
|
|
109
109
|
message: `Example value must conform to the schema: ${error.message}.`,
|
|
110
110
|
location: {
|
|
111
111
|
...new Location(dataLoc.source, error.instancePath),
|
|
112
|
-
reportOnKey:
|
|
112
|
+
reportOnKey:
|
|
113
|
+
error.keyword === 'unevaluatedProperties' || error.keyword === 'additionalProperties',
|
|
113
114
|
},
|
|
114
115
|
from: location,
|
|
115
116
|
suggest: error.suggest,
|
package/src/types/index.ts
CHANGED
|
@@ -73,7 +73,7 @@ export function normalizeTypes(
|
|
|
73
73
|
normalizedTypes[typeName] = {
|
|
74
74
|
...types[typeName],
|
|
75
75
|
name: typeName,
|
|
76
|
-
} as
|
|
76
|
+
} as NormalizedNodeType;
|
|
77
77
|
}
|
|
78
78
|
|
|
79
79
|
for (const type of Object.values(normalizedTypes)) {
|
|
@@ -81,7 +81,7 @@ export function normalizeTypes(
|
|
|
81
81
|
}
|
|
82
82
|
return normalizedTypes;
|
|
83
83
|
|
|
84
|
-
function normalizeType(type:
|
|
84
|
+
function normalizeType(type: NormalizedNodeType) {
|
|
85
85
|
if (type.additionalProperties) {
|
|
86
86
|
type.additionalProperties = resolveType(type.additionalProperties);
|
|
87
87
|
}
|
package/src/types/oas2.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { NodeType, listOf, mapOf } from '.';
|
|
|
2
2
|
|
|
3
3
|
const responseCodeRegexp = /^[0-9][0-9Xx]{2}$/;
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const Root: NodeType = {
|
|
6
6
|
properties: {
|
|
7
7
|
swagger: { type: 'string' },
|
|
8
8
|
info: 'Info',
|
|
@@ -11,7 +11,7 @@ const DefinitionRoot: NodeType = {
|
|
|
11
11
|
schemes: { type: 'array', items: { type: 'string' } },
|
|
12
12
|
consumes: { type: 'array', items: { type: 'string' } },
|
|
13
13
|
produces: { type: 'array', items: { type: 'string' } },
|
|
14
|
-
paths: '
|
|
14
|
+
paths: 'PathsMap',
|
|
15
15
|
definitions: 'NamedSchemas',
|
|
16
16
|
parameters: 'NamedParameters',
|
|
17
17
|
responses: 'NamedResponses',
|
|
@@ -51,7 +51,7 @@ const License: NodeType = {
|
|
|
51
51
|
required: ['name'],
|
|
52
52
|
};
|
|
53
53
|
|
|
54
|
-
const
|
|
54
|
+
const PathsMap: NodeType = {
|
|
55
55
|
properties: {},
|
|
56
56
|
additionalProperties: (_value: any, key: string) =>
|
|
57
57
|
key.startsWith('/') ? 'PathItem' : undefined,
|
|
@@ -369,14 +369,14 @@ const SecurityRequirement: NodeType = {
|
|
|
369
369
|
};
|
|
370
370
|
|
|
371
371
|
export const Oas2Types: Record<string, NodeType> = {
|
|
372
|
-
|
|
372
|
+
Root,
|
|
373
373
|
Tag,
|
|
374
374
|
ExternalDocs,
|
|
375
375
|
SecurityRequirement,
|
|
376
376
|
Info,
|
|
377
377
|
Contact,
|
|
378
378
|
License,
|
|
379
|
-
|
|
379
|
+
PathsMap,
|
|
380
380
|
PathItem,
|
|
381
381
|
Parameter,
|
|
382
382
|
ParameterItems,
|
package/src/types/oas3.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { NodeType, listOf, mapOf } from '.';
|
|
|
2
2
|
import { isMappingRef } from '../ref-utils';
|
|
3
3
|
const responseCodeRegexp = /^[0-9][0-9Xx]{2}$/;
|
|
4
4
|
|
|
5
|
-
const
|
|
5
|
+
const Root: NodeType = {
|
|
6
6
|
properties: {
|
|
7
7
|
openapi: null,
|
|
8
8
|
info: 'Info',
|
|
@@ -10,7 +10,7 @@ const DefinitionRoot: NodeType = {
|
|
|
10
10
|
security: listOf('SecurityRequirement'),
|
|
11
11
|
tags: listOf('Tag'),
|
|
12
12
|
externalDocs: 'ExternalDocs',
|
|
13
|
-
paths: '
|
|
13
|
+
paths: 'PathsMap',
|
|
14
14
|
components: 'Components',
|
|
15
15
|
'x-webhooks': 'WebhooksMap',
|
|
16
16
|
},
|
|
@@ -38,7 +38,7 @@ const Server: NodeType = {
|
|
|
38
38
|
properties: {
|
|
39
39
|
url: { type: 'string' },
|
|
40
40
|
description: { type: 'string' },
|
|
41
|
-
variables:
|
|
41
|
+
variables: 'ServerVariablesMap',
|
|
42
42
|
},
|
|
43
43
|
required: ['url'],
|
|
44
44
|
};
|
|
@@ -88,7 +88,7 @@ const License: NodeType = {
|
|
|
88
88
|
required: ['name'],
|
|
89
89
|
};
|
|
90
90
|
|
|
91
|
-
const
|
|
91
|
+
const PathsMap: NodeType = {
|
|
92
92
|
properties: {},
|
|
93
93
|
additionalProperties: (_value: any, key: string) =>
|
|
94
94
|
key.startsWith('/') ? 'PathItem' : undefined,
|
|
@@ -132,8 +132,8 @@ const Parameter: NodeType = {
|
|
|
132
132
|
allowReserved: { type: 'boolean' },
|
|
133
133
|
schema: 'Schema',
|
|
134
134
|
example: { isExample: true },
|
|
135
|
-
examples:
|
|
136
|
-
content: '
|
|
135
|
+
examples: 'ExamplesMap',
|
|
136
|
+
content: 'MediaTypesMap',
|
|
137
137
|
},
|
|
138
138
|
required: ['name', 'in'],
|
|
139
139
|
requiredOneOf: ['schema', 'content'],
|
|
@@ -155,7 +155,7 @@ const Operation: NodeType = {
|
|
|
155
155
|
requestBody: 'RequestBody',
|
|
156
156
|
responses: 'ResponsesMap',
|
|
157
157
|
deprecated: { type: 'boolean' },
|
|
158
|
-
callbacks:
|
|
158
|
+
callbacks: 'CallbacksMap',
|
|
159
159
|
'x-codeSamples': listOf('XCodeSample'),
|
|
160
160
|
'x-code-samples': listOf('XCodeSample'), // deprecated
|
|
161
161
|
'x-hideTryItPanel': { type: 'boolean' },
|
|
@@ -175,12 +175,12 @@ const RequestBody: NodeType = {
|
|
|
175
175
|
properties: {
|
|
176
176
|
description: { type: 'string' },
|
|
177
177
|
required: { type: 'boolean' },
|
|
178
|
-
content: '
|
|
178
|
+
content: 'MediaTypesMap',
|
|
179
179
|
},
|
|
180
180
|
required: ['content'],
|
|
181
181
|
};
|
|
182
182
|
|
|
183
|
-
const
|
|
183
|
+
const MediaTypesMap: NodeType = {
|
|
184
184
|
properties: {},
|
|
185
185
|
additionalProperties: 'MediaType',
|
|
186
186
|
};
|
|
@@ -189,8 +189,8 @@ const MediaType: NodeType = {
|
|
|
189
189
|
properties: {
|
|
190
190
|
schema: 'Schema',
|
|
191
191
|
example: { isExample: true },
|
|
192
|
-
examples:
|
|
193
|
-
encoding:
|
|
192
|
+
examples: 'ExamplesMap',
|
|
193
|
+
encoding: 'EncodingsMap',
|
|
194
194
|
},
|
|
195
195
|
};
|
|
196
196
|
|
|
@@ -206,7 +206,7 @@ const Example: NodeType = {
|
|
|
206
206
|
const Encoding: NodeType = {
|
|
207
207
|
properties: {
|
|
208
208
|
contentType: { type: 'string' },
|
|
209
|
-
headers:
|
|
209
|
+
headers: 'HeadersMap',
|
|
210
210
|
style: {
|
|
211
211
|
enum: ['form', 'simple', 'label', 'matrix', 'spaceDelimited', 'pipeDelimited', 'deepObject'],
|
|
212
212
|
},
|
|
@@ -228,9 +228,10 @@ const Header: NodeType = {
|
|
|
228
228
|
allowReserved: { type: 'boolean' },
|
|
229
229
|
schema: 'Schema',
|
|
230
230
|
example: { isExample: true },
|
|
231
|
-
examples:
|
|
232
|
-
content: '
|
|
231
|
+
examples: 'ExamplesMap',
|
|
232
|
+
content: 'MediaTypesMap',
|
|
233
233
|
},
|
|
234
|
+
requiredOneOf: ['schema', 'content'],
|
|
234
235
|
};
|
|
235
236
|
|
|
236
237
|
const ResponsesMap: NodeType = {
|
|
@@ -242,9 +243,9 @@ const ResponsesMap: NodeType = {
|
|
|
242
243
|
const Response: NodeType = {
|
|
243
244
|
properties: {
|
|
244
245
|
description: { type: 'string' },
|
|
245
|
-
headers:
|
|
246
|
-
content: '
|
|
247
|
-
links:
|
|
246
|
+
headers: 'HeadersMap',
|
|
247
|
+
content: 'MediaTypesMap',
|
|
248
|
+
links: 'LinksMap',
|
|
248
249
|
},
|
|
249
250
|
required: ['description'],
|
|
250
251
|
};
|
|
@@ -459,26 +460,31 @@ const SecurityScheme: NodeType = {
|
|
|
459
460
|
};
|
|
460
461
|
|
|
461
462
|
export const Oas3Types: Record<string, NodeType> = {
|
|
462
|
-
|
|
463
|
+
Root,
|
|
463
464
|
Tag,
|
|
464
465
|
ExternalDocs,
|
|
465
466
|
Server,
|
|
466
467
|
ServerVariable,
|
|
468
|
+
ServerVariablesMap: mapOf('ServerVariable'),
|
|
467
469
|
SecurityRequirement,
|
|
468
470
|
Info,
|
|
469
471
|
Contact,
|
|
470
472
|
License,
|
|
471
|
-
|
|
473
|
+
PathsMap,
|
|
472
474
|
PathItem,
|
|
473
475
|
Parameter,
|
|
474
476
|
Operation,
|
|
475
477
|
Callback: mapOf('PathItem'),
|
|
478
|
+
CallbacksMap: mapOf('Callback'),
|
|
476
479
|
RequestBody,
|
|
477
|
-
|
|
480
|
+
MediaTypesMap,
|
|
478
481
|
MediaType,
|
|
479
482
|
Example,
|
|
483
|
+
ExamplesMap: mapOf('Example'),
|
|
480
484
|
Encoding,
|
|
485
|
+
EncodingsMap: mapOf('Encoding'),
|
|
481
486
|
Header,
|
|
487
|
+
HeadersMap: mapOf('Header'),
|
|
482
488
|
ResponsesMap,
|
|
483
489
|
Response,
|
|
484
490
|
Link,
|
|
@@ -488,6 +494,7 @@ export const Oas3Types: Record<string, NodeType> = {
|
|
|
488
494
|
DiscriminatorMapping,
|
|
489
495
|
Discriminator,
|
|
490
496
|
Components,
|
|
497
|
+
LinksMap: mapOf('Link'),
|
|
491
498
|
NamedSchemas: mapOf('Schema'),
|
|
492
499
|
NamedResponses: mapOf('Response'),
|
|
493
500
|
NamedParameters: mapOf('Parameter'),
|
package/src/types/oas3_1.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { NodeType, listOf, mapOf } from '.';
|
|
2
2
|
import { Oas3Types } from './oas3';
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const Root: NodeType = {
|
|
5
5
|
properties: {
|
|
6
6
|
openapi: null,
|
|
7
7
|
info: 'Info',
|
|
@@ -9,7 +9,7 @@ const DefinitionRoot: NodeType = {
|
|
|
9
9
|
security: listOf('SecurityRequirement'),
|
|
10
10
|
tags: listOf('Tag'),
|
|
11
11
|
externalDocs: 'ExternalDocs',
|
|
12
|
-
paths: '
|
|
12
|
+
paths: 'PathsMap',
|
|
13
13
|
webhooks: 'WebhooksMap',
|
|
14
14
|
components: 'Components',
|
|
15
15
|
jsonSchemaDialect: { type: 'string' },
|
|
@@ -241,7 +241,7 @@ const SecurityScheme: NodeType = {
|
|
|
241
241
|
export const Oas3_1Types: Record<string, NodeType> = {
|
|
242
242
|
...Oas3Types,
|
|
243
243
|
Info,
|
|
244
|
-
|
|
244
|
+
Root,
|
|
245
245
|
Schema,
|
|
246
246
|
License,
|
|
247
247
|
Components,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { NodeType, listOf } from '.';
|
|
2
2
|
import { omitObjectProps, pickObjectProps, isCustomRuleId } from '../utils';
|
|
3
|
+
|
|
3
4
|
const builtInRulesList = [
|
|
4
5
|
'spec',
|
|
5
6
|
'info-description',
|
|
@@ -8,6 +9,7 @@ const builtInRulesList = [
|
|
|
8
9
|
'info-license-url',
|
|
9
10
|
'operation-2xx-response',
|
|
10
11
|
'operation-4xx-response',
|
|
12
|
+
'operation-4xx-problem-details-rfc7807',
|
|
11
13
|
'assertions',
|
|
12
14
|
'operation-operationId-unique',
|
|
13
15
|
'operation-parameters-unique',
|
|
@@ -31,7 +33,7 @@ const builtInRulesList = [
|
|
|
31
33
|
'path-params-defined',
|
|
32
34
|
'parameter-description',
|
|
33
35
|
'operation-singular-tag',
|
|
34
|
-
'
|
|
36
|
+
'security-defined',
|
|
35
37
|
'no-unresolved-refs',
|
|
36
38
|
'paths-kebab-case',
|
|
37
39
|
'boolean-parameter-prefixes',
|
|
@@ -51,31 +53,38 @@ const builtInRulesList = [
|
|
|
51
53
|
'response-contains-header',
|
|
52
54
|
'response-contains-property',
|
|
53
55
|
'scalar-property-missing-example',
|
|
56
|
+
'spec-components-invalid-map-name',
|
|
54
57
|
];
|
|
55
58
|
const nodeTypesList = [
|
|
56
|
-
'
|
|
59
|
+
'Root',
|
|
57
60
|
'Tag',
|
|
58
61
|
'ExternalDocs',
|
|
59
62
|
'Server',
|
|
60
63
|
'ServerVariable',
|
|
64
|
+
'ServerVariablesMap',
|
|
61
65
|
'SecurityRequirement',
|
|
62
66
|
'Info',
|
|
63
67
|
'Contact',
|
|
64
68
|
'License',
|
|
65
|
-
'
|
|
69
|
+
'PathsMap',
|
|
66
70
|
'PathItem',
|
|
67
71
|
'Parameter',
|
|
68
72
|
'Operation',
|
|
69
73
|
'Callback',
|
|
74
|
+
'CallbacksMap',
|
|
70
75
|
'RequestBody',
|
|
71
|
-
'
|
|
76
|
+
'MediaTypesMap',
|
|
72
77
|
'MediaType',
|
|
73
78
|
'Example',
|
|
79
|
+
'ExamplesMap',
|
|
74
80
|
'Encoding',
|
|
81
|
+
'EncodingsMap',
|
|
75
82
|
'Header',
|
|
83
|
+
'HeadersMap',
|
|
76
84
|
'ResponsesMap',
|
|
77
85
|
'Response',
|
|
78
86
|
'Link',
|
|
87
|
+
'LinksMap',
|
|
79
88
|
'Schema',
|
|
80
89
|
'Xml',
|
|
81
90
|
'SchemaProperties',
|
|
@@ -101,6 +110,39 @@ const nodeTypesList = [
|
|
|
101
110
|
'WebhooksMap',
|
|
102
111
|
];
|
|
103
112
|
|
|
113
|
+
const ConfigStyleguide: NodeType = {
|
|
114
|
+
properties: {
|
|
115
|
+
extends: {
|
|
116
|
+
type: 'array',
|
|
117
|
+
items: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
},
|
|
120
|
+
},
|
|
121
|
+
rules: 'Rules',
|
|
122
|
+
oas2Rules: 'Rules',
|
|
123
|
+
oas3_0Rules: 'Rules',
|
|
124
|
+
oas3_1Rules: 'Rules',
|
|
125
|
+
preprocessors: { type: 'object' },
|
|
126
|
+
oas2Preprocessors: { type: 'object' },
|
|
127
|
+
oas3_0Preprocessors: { type: 'object' },
|
|
128
|
+
oas3_1Preprocessors: { type: 'object' },
|
|
129
|
+
decorators: { type: 'object' },
|
|
130
|
+
oas2Decorators: { type: 'object' },
|
|
131
|
+
oas3_0Decorators: { type: 'object' },
|
|
132
|
+
oas3_1Decorators: { type: 'object' },
|
|
133
|
+
},
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
const RootConfigStyleguide: NodeType = {
|
|
137
|
+
properties: {
|
|
138
|
+
plugins: {
|
|
139
|
+
type: 'array',
|
|
140
|
+
items: { type: 'string' },
|
|
141
|
+
},
|
|
142
|
+
...ConfigStyleguide.properties,
|
|
143
|
+
},
|
|
144
|
+
};
|
|
145
|
+
|
|
104
146
|
const ConfigRoot: NodeType = {
|
|
105
147
|
properties: {
|
|
106
148
|
organization: { type: 'string' },
|
|
@@ -110,7 +152,8 @@ const ConfigRoot: NodeType = {
|
|
|
110
152
|
properties: {},
|
|
111
153
|
additionalProperties: { properties: { type: 'string' } },
|
|
112
154
|
}, // deprecated
|
|
113
|
-
|
|
155
|
+
...RootConfigStyleguide.properties,
|
|
156
|
+
styleguide: 'RootConfigStyleguide', // deprecated
|
|
114
157
|
lint: 'RootConfigStyleguide', // deprecated
|
|
115
158
|
'features.openapi': 'ConfigReferenceDocs',
|
|
116
159
|
referenceDocs: 'ConfigReferenceDocs', // deprecated
|
|
@@ -119,6 +162,13 @@ const ConfigRoot: NodeType = {
|
|
|
119
162
|
resolve: {
|
|
120
163
|
properties: {
|
|
121
164
|
http: 'ConfigHTTP',
|
|
165
|
+
doNotResolveExamples: { type: 'boolean' },
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
files: {
|
|
169
|
+
type: 'array',
|
|
170
|
+
items: {
|
|
171
|
+
type: 'string',
|
|
122
172
|
},
|
|
123
173
|
},
|
|
124
174
|
},
|
|
@@ -138,55 +188,29 @@ const ConfigApisProperties: NodeType = {
|
|
|
138
188
|
type: 'string',
|
|
139
189
|
},
|
|
140
190
|
},
|
|
141
|
-
|
|
191
|
+
lint: 'ConfigStyleguide', // deprecated
|
|
192
|
+
styleguide: 'ConfigStyleguide', // deprecated
|
|
193
|
+
...ConfigStyleguide.properties,
|
|
142
194
|
'features.openapi': 'ConfigReferenceDocs',
|
|
143
195
|
'features.mockServer': 'ConfigMockServer',
|
|
144
|
-
|
|
145
|
-
required: ['root'],
|
|
146
|
-
};
|
|
147
|
-
|
|
148
|
-
const ConfigHTTP: NodeType = {
|
|
149
|
-
properties: {
|
|
150
|
-
headers: {
|
|
196
|
+
files: {
|
|
151
197
|
type: 'array',
|
|
152
198
|
items: {
|
|
153
199
|
type: 'string',
|
|
154
200
|
},
|
|
155
201
|
},
|
|
156
202
|
},
|
|
203
|
+
required: ['root'],
|
|
157
204
|
};
|
|
158
205
|
|
|
159
|
-
const
|
|
206
|
+
const ConfigHTTP: NodeType = {
|
|
160
207
|
properties: {
|
|
161
|
-
|
|
208
|
+
headers: {
|
|
162
209
|
type: 'array',
|
|
163
210
|
items: {
|
|
164
211
|
type: 'string',
|
|
165
212
|
},
|
|
166
213
|
},
|
|
167
|
-
doNotResolveExamples: { type: 'boolean' },
|
|
168
|
-
rules: 'Rules',
|
|
169
|
-
oas2Rules: 'Rules',
|
|
170
|
-
oas3_0Rules: 'Rules',
|
|
171
|
-
oas3_1Rules: 'Rules',
|
|
172
|
-
preprocessors: { type: 'object' },
|
|
173
|
-
oas2Preprocessors: { type: 'object' },
|
|
174
|
-
oas3_0Preprocessors: { type: 'object' },
|
|
175
|
-
oas3_1Preprocessors: { type: 'object' },
|
|
176
|
-
decorators: { type: 'object' },
|
|
177
|
-
oas2Decorators: { type: 'object' },
|
|
178
|
-
oas3_0Decorators: { type: 'object' },
|
|
179
|
-
oas3_1Decorators: { type: 'object' },
|
|
180
|
-
},
|
|
181
|
-
};
|
|
182
|
-
|
|
183
|
-
const RootConfigStyleguide: NodeType = {
|
|
184
|
-
properties: {
|
|
185
|
-
plugins: {
|
|
186
|
-
type: 'array',
|
|
187
|
-
items: { type: 'string' },
|
|
188
|
-
},
|
|
189
|
-
...ConfigStyleguide.properties,
|
|
190
214
|
},
|
|
191
215
|
};
|
|
192
216
|
|
|
@@ -263,6 +287,10 @@ const Assert: NodeType = {
|
|
|
263
287
|
ref: (value: string | boolean) =>
|
|
264
288
|
typeof value === 'string' ? { type: 'string' } : { type: 'boolean' },
|
|
265
289
|
},
|
|
290
|
+
additionalProperties: (_value: unknown, key: string) => {
|
|
291
|
+
if (/^\w+\/\w+$/.test(key)) return { type: 'object' };
|
|
292
|
+
return;
|
|
293
|
+
},
|
|
266
294
|
required: ['subject'],
|
|
267
295
|
};
|
|
268
296
|
|