@redocly/openapi-core 1.0.0-beta.61 → 1.0.0-beta.65
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/__tests__/lint.test.ts +17 -0
- package/__tests__/resolve.test.ts +10 -2
- package/__tests__/utils.ts +3 -5
- package/lib/benchmark/utils.js +2 -2
- package/lib/config/config.d.ts +1 -0
- package/lib/config/config.js +3 -3
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -1
- package/lib/js-yaml/index.d.ts +3 -0
- package/lib/js-yaml/index.js +19 -0
- package/lib/oas-types.js +3 -0
- package/lib/resolve.d.ts +1 -1
- package/lib/resolve.js +3 -4
- package/lib/rules/builtin.d.ts +6 -0
- package/lib/rules/common/info-description-override.d.ts +2 -0
- package/lib/rules/common/info-description-override.js +24 -0
- package/lib/rules/common/operation-description-override.d.ts +2 -0
- package/lib/rules/common/operation-description-override.js +29 -0
- package/lib/rules/common/tag-description-override.d.ts +2 -0
- package/lib/rules/common/tag-description-override.js +25 -0
- package/lib/rules/oas2/index.d.ts +3 -0
- package/lib/rules/oas2/index.js +6 -0
- package/lib/rules/oas3/index.d.ts +3 -0
- package/lib/rules/oas3/index.js +7 -1
- package/lib/types/redocly-yaml.js +332 -21
- package/lib/utils.d.ts +5 -1
- package/lib/utils.js +18 -3
- package/package.json +3 -3
- package/src/__tests__/js-yaml.test.ts +47 -0
- package/src/__tests__/lint.test.ts +13 -0
- package/src/__tests__/utils.test.ts +56 -0
- package/src/benchmark/utils.ts +2 -2
- package/src/config/config.ts +4 -3
- package/src/index.ts +2 -0
- package/src/js-yaml/index.ts +19 -0
- package/src/oas-types.ts +4 -0
- package/src/resolve.ts +5 -5
- package/src/rules/__tests__/no-unresolved-refs.test.ts +2 -2
- package/src/rules/common/info-description-override.ts +24 -0
- package/src/rules/common/operation-description-override.ts +30 -0
- package/src/rules/common/tag-description-override.ts +25 -0
- package/src/rules/oas2/index.ts +6 -0
- package/src/rules/oas3/index.ts +8 -3
- package/src/types/redocly-yaml.ts +434 -22
- package/src/typings/swagger.ts +0 -1
- package/src/utils.ts +27 -3
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
// TODO: add a type for "types" https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/js-yaml/index.d.ts
|
|
2
|
+
// @ts-ignore
|
|
3
|
+
import { JSON_SCHEMA, types, LoadOptions, DumpOptions, load, dump } from 'js-yaml';
|
|
4
|
+
|
|
5
|
+
const DEFAULT_SCHEMA_WITHOUT_TIMESTAMP = JSON_SCHEMA.extend({
|
|
6
|
+
implicit: [types.merge],
|
|
7
|
+
explicit: [
|
|
8
|
+
types.binary,
|
|
9
|
+
types.omap,
|
|
10
|
+
types.pairs,
|
|
11
|
+
types.set,
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export const parseYaml = (str: string, opts?: LoadOptions): unknown =>
|
|
16
|
+
load(str, {schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts});
|
|
17
|
+
|
|
18
|
+
export const stringifyYaml = (obj: any, opts?: DumpOptions): string =>
|
|
19
|
+
dump(obj, {schema: DEFAULT_SCHEMA_WITHOUT_TIMESTAMP, ...opts});
|
package/src/oas-types.ts
CHANGED
|
@@ -34,6 +34,10 @@ export function detectOpenAPI(root: any): OasVersion {
|
|
|
34
34
|
throw new Error('This doesn’t look like an OpenAPI document.\n');
|
|
35
35
|
}
|
|
36
36
|
|
|
37
|
+
if (root.openapi && typeof root.openapi !== 'string') {
|
|
38
|
+
throw new Error(`Invalid OpenAPI version: should be a string but got "${typeof root.openapi}"`);
|
|
39
|
+
}
|
|
40
|
+
|
|
37
41
|
if (root.openapi && root.openapi.startsWith('3.0')) {
|
|
38
42
|
return OasVersion.Version3_0;
|
|
39
43
|
}
|
package/src/resolve.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as url from 'url';
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
import { OasRef } from './typings/openapi';
|
|
6
6
|
import { isRef, joinPointer, escapePointer, parseRef, isAbsoluteUrl } from './ref-utils';
|
|
7
7
|
import type { YAMLNode, LoadOptions } from 'yaml-ast-parser';
|
|
8
8
|
import { NormalizedNodeType, isNamedType } from './types';
|
|
9
|
-
import { readFileFromUrl } from './utils';
|
|
9
|
+
import { readFileFromUrl, parseYaml } from './utils';
|
|
10
10
|
import { ResolveConfig } from './config/config';
|
|
11
11
|
|
|
12
12
|
export type CollectedRefs = Map<string /* absoluteFilePath */, Document>;
|
|
@@ -52,7 +52,7 @@ export class ResolveError extends Error {
|
|
|
52
52
|
}
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
-
const jsYamlErrorLineColRegexp =
|
|
55
|
+
const jsYamlErrorLineColRegexp = /\((\d+):(\d+)\)$/;
|
|
56
56
|
|
|
57
57
|
export class YamlParseError extends Error {
|
|
58
58
|
col: number;
|
|
@@ -79,7 +79,7 @@ export function makeDocumentFromString(sourceString: string, absoluteRef: string
|
|
|
79
79
|
try {
|
|
80
80
|
return {
|
|
81
81
|
source,
|
|
82
|
-
parsed:
|
|
82
|
+
parsed: parseYaml(sourceString, { filename: absoluteRef }),
|
|
83
83
|
};
|
|
84
84
|
} catch (e) {
|
|
85
85
|
throw new YamlParseError(e, source);
|
|
@@ -133,7 +133,7 @@ export class BaseResolver {
|
|
|
133
133
|
try {
|
|
134
134
|
return {
|
|
135
135
|
source,
|
|
136
|
-
parsed:
|
|
136
|
+
parsed: parseYaml(source.body, { filename: source.absoluteRef }),
|
|
137
137
|
};
|
|
138
138
|
} catch (e) {
|
|
139
139
|
throw new YamlParseError(e, source);
|
|
@@ -83,7 +83,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
|
|
|
83
83
|
},
|
|
84
84
|
},
|
|
85
85
|
],
|
|
86
|
-
"message": "Failed to parse: unexpected end of the stream within a single quoted scalar in \\"fixtures/invalid-yaml.yaml\\"
|
|
86
|
+
"message": "Failed to parse: unexpected end of the stream within a single quoted scalar in \\"fixtures/invalid-yaml.yaml\\" (2:1)",
|
|
87
87
|
"ruleId": "no-unresolved-refs",
|
|
88
88
|
"severity": "error",
|
|
89
89
|
"suggest": Array [],
|
|
@@ -96,7 +96,7 @@ describe('oas3 boolean-parameter-prefixes', () => {
|
|
|
96
96
|
"source": "foobar.yaml",
|
|
97
97
|
},
|
|
98
98
|
],
|
|
99
|
-
"message": "Can't resolve $ref: unexpected end of the stream within a single quoted scalar in \\"fixtures/invalid-yaml.yaml\\"
|
|
99
|
+
"message": "Can't resolve $ref: unexpected end of the stream within a single quoted scalar in \\"fixtures/invalid-yaml.yaml\\" (2:1)",
|
|
100
100
|
"ruleId": "no-unresolved-refs",
|
|
101
101
|
"severity": "error",
|
|
102
102
|
"suggest": Array [],
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { Oas3Decorator, Oas2Decorator } from '../../visitors';
|
|
2
|
+
import { readFileAsStringSync } from '../../utils';
|
|
3
|
+
import { UserContext } from '../../walk';
|
|
4
|
+
|
|
5
|
+
export const InfoDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ filePath }) => {
|
|
6
|
+
return {
|
|
7
|
+
Info: {
|
|
8
|
+
leave(info, { report, location }: UserContext) {
|
|
9
|
+
if (!filePath)
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Parameter "filePath" is not provided for "info-description-override" rule`,
|
|
12
|
+
);
|
|
13
|
+
try {
|
|
14
|
+
info.description = readFileAsStringSync(filePath);
|
|
15
|
+
} catch (e) {
|
|
16
|
+
report({
|
|
17
|
+
message: `Failed to read markdown override file for "info.description".\n${e.message}`,
|
|
18
|
+
location: location.child('description'),
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Oas3Decorator, Oas2Decorator } from '../../visitors';
|
|
2
|
+
import { Oas2Operation } from '../../typings/swagger';
|
|
3
|
+
import { Oas3Operation } from '../../typings/openapi';
|
|
4
|
+
import { readFileAsStringSync } from '../../utils';
|
|
5
|
+
import { UserContext } from '../../walk';
|
|
6
|
+
|
|
7
|
+
export const OperationDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ operationIds }) => {
|
|
8
|
+
return {
|
|
9
|
+
Operation: {
|
|
10
|
+
leave(operation: Oas2Operation | Oas3Operation, { report, location }: UserContext) {
|
|
11
|
+
if (!operation.operationId) return;
|
|
12
|
+
if (!operationIds)
|
|
13
|
+
throw new Error(
|
|
14
|
+
`Parameter "operationIds" is not provided for "operation-description-override" rule`,
|
|
15
|
+
);
|
|
16
|
+
const operationId = operation.operationId;
|
|
17
|
+
if (operationIds[operationId]) {
|
|
18
|
+
try {
|
|
19
|
+
operation.description = readFileAsStringSync(operationIds[operationId]);
|
|
20
|
+
} catch (e) {
|
|
21
|
+
report({
|
|
22
|
+
message: `Failed to read markdown override file for operation "${operationId}".\n${e.message}`,
|
|
23
|
+
location: location.child('operationId').key(),
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Oas3Decorator, Oas2Decorator } from '../../visitors';
|
|
2
|
+
import { readFileAsStringSync } from '../../utils';
|
|
3
|
+
import { UserContext } from '../../walk';
|
|
4
|
+
|
|
5
|
+
export const TagDescriptionOverride: Oas3Decorator | Oas2Decorator = ({ tagNames }) => {
|
|
6
|
+
return {
|
|
7
|
+
Tag: {
|
|
8
|
+
leave(tag, { report }: UserContext) {
|
|
9
|
+
if (!tagNames)
|
|
10
|
+
throw new Error(
|
|
11
|
+
`Parameter "tagNames" is not provided for "tag-description-override" rule`,
|
|
12
|
+
);
|
|
13
|
+
if (tagNames[tag.name]) {
|
|
14
|
+
try {
|
|
15
|
+
tag.description = readFileAsStringSync(tagNames[tag.name]);
|
|
16
|
+
} catch (e) {
|
|
17
|
+
report({
|
|
18
|
+
message: `Failed to read markdown override file for tag "${tag.name}".\n${e.message}`,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
};
|
|
25
|
+
};
|
package/src/rules/oas2/index.ts
CHANGED
|
@@ -29,6 +29,9 @@ import { NoIdenticalPaths } from '../common/no-identical-paths';
|
|
|
29
29
|
import { OperationOperationId } from '../common/operation-operationId';
|
|
30
30
|
import { OperationSummary } from '../common/operation-summary';
|
|
31
31
|
import { NoAmbiguousPaths } from '../common/no-ambiguous-paths';
|
|
32
|
+
import { OperationDescriptionOverride } from '../common/operation-description-override';
|
|
33
|
+
import { TagDescriptionOverride } from '../common/tag-description-override';
|
|
34
|
+
import { InfoDescriptionOverride } from '../common/info-description-override';
|
|
32
35
|
|
|
33
36
|
export const rules = {
|
|
34
37
|
spec: OasSpec as Oas2Rule,
|
|
@@ -66,4 +69,7 @@ export const rules = {
|
|
|
66
69
|
export const preprocessors = {};
|
|
67
70
|
export const decorators = {
|
|
68
71
|
'registry-dependencies': RegistryDependencies as Oas2Decorator,
|
|
72
|
+
'operation-description-override': OperationDescriptionOverride as Oas2Decorator,
|
|
73
|
+
'tag-description-override': TagDescriptionOverride as Oas2Decorator,
|
|
74
|
+
'info-description-override': InfoDescriptionOverride as Oas2Decorator,
|
|
69
75
|
};
|
package/src/rules/oas3/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Oas3RuleSet } from '../../oas-types';
|
|
2
|
+
import { Oas3Decorator } from '../../visitors';
|
|
2
3
|
import { OasSpec } from '../common/spec';
|
|
3
4
|
import { Operation2xxResponse } from '../common/operation-2xx-response';
|
|
4
5
|
import { OperationIdUnique } from '../common/operation-operationId-unique';
|
|
@@ -37,8 +38,9 @@ import { OperationOperationId } from '../common/operation-operationId';
|
|
|
37
38
|
import { OperationSummary } from '../common/operation-summary';
|
|
38
39
|
import { NoAmbiguousPaths } from '../common/no-ambiguous-paths';
|
|
39
40
|
import { NoEmptyEnumServers } from './no-servers-empty-enum';
|
|
40
|
-
|
|
41
|
-
import {
|
|
41
|
+
import { OperationDescriptionOverride } from '../common/operation-description-override';
|
|
42
|
+
import { TagDescriptionOverride } from '../common/tag-description-override';
|
|
43
|
+
import { InfoDescriptionOverride } from '../common/info-description-override';
|
|
42
44
|
|
|
43
45
|
export const rules = {
|
|
44
46
|
spec: OasSpec,
|
|
@@ -78,11 +80,14 @@ export const rules = {
|
|
|
78
80
|
'no-identical-paths': NoIdenticalPaths,
|
|
79
81
|
'no-ambiguous-paths': NoAmbiguousPaths,
|
|
80
82
|
'no-undefined-server-variable': NoUndefinedServerVariable,
|
|
81
|
-
'no-servers-empty-enum': NoEmptyEnumServers
|
|
83
|
+
'no-servers-empty-enum': NoEmptyEnumServers,
|
|
82
84
|
} as Oas3RuleSet;
|
|
83
85
|
|
|
84
86
|
export const preprocessors = {};
|
|
85
87
|
|
|
86
88
|
export const decorators = {
|
|
87
89
|
'registry-dependencies': RegistryDependencies as Oas3Decorator,
|
|
90
|
+
'operation-description-override': OperationDescriptionOverride as Oas3Decorator,
|
|
91
|
+
'tag-description-override': TagDescriptionOverride as Oas3Decorator,
|
|
92
|
+
'info-description-override': InfoDescriptionOverride as Oas3Decorator,
|
|
88
93
|
};
|