@redocly/openapi-core 1.0.0-beta.105 → 1.0.0-beta.106
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 +4 -4
- package/__tests__/utils.ts +5 -5
- package/lib/benchmark/benches/recommended-oas3.bench.js +1 -1
- package/lib/benchmark/utils.d.ts +2 -2
- package/lib/benchmark/utils.js +2 -2
- package/lib/bundle.d.ts +2 -2
- package/lib/bundle.js +2 -2
- package/lib/config/all.d.ts +2 -2
- package/lib/config/all.js +1 -1
- package/lib/config/builtIn.d.ts +2 -2
- package/lib/config/builtIn.js +2 -2
- package/lib/config/config-resolvers.d.ts +5 -5
- package/lib/config/config-resolvers.js +39 -36
- package/lib/config/config.d.ts +5 -5
- package/lib/config/config.js +4 -4
- package/lib/config/load.js +4 -4
- package/lib/config/minimal.d.ts +2 -2
- package/lib/config/minimal.js +1 -1
- package/lib/config/recommended.d.ts +2 -2
- package/lib/config/recommended.js +1 -1
- package/lib/config/rules.d.ts +2 -2
- package/lib/config/rules.js +1 -1
- package/lib/config/types.d.ts +23 -19
- package/lib/config/utils.d.ts +5 -5
- package/lib/config/utils.js +43 -26
- package/lib/decorators/common/remove-x-internal.js +2 -2
- package/lib/format/format.js +1 -1
- package/lib/index.d.ts +1 -1
- package/lib/index.js +2 -2
- package/lib/js-yaml/index.js +1 -6
- package/lib/lint.d.ts +2 -2
- package/lib/lint.js +16 -6
- package/lib/redocly/registry-api.d.ts +1 -1
- package/lib/redocly/registry-api.js +2 -2
- package/lib/rules/common/info-license-url.d.ts +1 -1
- package/lib/rules/common/info-license-url.js +5 -10
- package/lib/rules/common/info-license.d.ts +2 -0
- package/lib/rules/common/info-license.js +17 -0
- package/lib/rules/common/no-enum-type-mismatch.js +1 -3
- package/lib/rules/common/operation-operationId.js +1 -1
- package/lib/rules/common/path-not-include-query.js +1 -1
- package/lib/rules/common/paths-kebab-case.js +4 -1
- package/lib/rules/common/spec.js +1 -1
- package/lib/rules/oas2/index.js +4 -4
- package/lib/rules/oas2/remove-unused-components.js +3 -3
- package/lib/rules/oas3/index.js +4 -4
- package/lib/rules/oas3/no-empty-servers.js +1 -1
- package/lib/rules/oas3/remove-unused-components.js +2 -2
- package/lib/rules/other/stats.js +43 -14
- package/lib/rules/utils.d.ts +1 -1
- package/lib/rules/utils.js +4 -1
- package/lib/types/index.d.ts +2 -2
- package/lib/types/redocly-yaml.js +8 -7
- package/package.json +1 -1
- package/src/__tests__/__snapshots__/bundle.test.ts.snap +141 -0
- package/src/__tests__/bundle.test.ts +68 -34
- package/src/__tests__/codeframes.test.ts +13 -14
- package/src/__tests__/js-yaml.test.ts +6 -4
- package/src/__tests__/lint.test.ts +74 -6
- package/src/__tests__/login.test.ts +2 -2
- package/src/__tests__/normalizeVisitors.test.ts +4 -4
- package/src/__tests__/ref-utils.test.ts +13 -13
- package/src/__tests__/resolve-http.test.ts +1 -1
- package/src/__tests__/resolve.test.ts +14 -11
- package/src/__tests__/walk.test.ts +48 -56
- package/src/benchmark/benches/lint-with-many-rules.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-nested-rule.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-no-rules.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-top-level-rule-report.bench.ts +1 -1
- package/src/benchmark/benches/lint-with-top-level-rule.bench.ts +1 -1
- package/src/benchmark/benches/recommended-oas3.bench.ts +3 -3
- package/src/benchmark/benches/resolve-with-no-external.bench.ts +1 -1
- package/src/benchmark/benchmark.js +9 -5
- package/src/benchmark/utils.ts +5 -5
- package/src/bundle.ts +18 -17
- package/src/config/__tests__/__snapshots__/config-resolvers.test.ts.snap +1 -1
- package/src/config/__tests__/config-resolvers.test.ts +123 -121
- package/src/config/__tests__/config.test.ts +76 -76
- package/src/config/__tests__/fixtures/resolve-config/api/plugin.js +4 -2
- package/src/config/__tests__/fixtures/resolve-config/plugin.js +4 -1
- package/src/config/__tests__/resolve-plugins.test.ts +3 -3
- package/src/config/__tests__/utils.test.ts +83 -0
- package/src/config/all.ts +3 -4
- package/src/config/builtIn.ts +5 -5
- package/src/config/config-resolvers.ts +122 -83
- package/src/config/config.ts +5 -5
- package/src/config/load.ts +6 -6
- package/src/config/minimal.ts +3 -3
- package/src/config/recommended.ts +3 -3
- package/src/config/rules.ts +6 -6
- package/src/config/types.ts +28 -19
- package/src/config/utils.ts +70 -50
- package/src/decorators/__tests__/filter-out.test.ts +8 -4
- package/src/decorators/__tests__/remove-x-internal.test.ts +5 -5
- package/src/decorators/common/filters/filter-helper.ts +1 -1
- package/src/decorators/common/info-description-override.ts +1 -1
- package/src/decorators/common/operation-description-override.ts +1 -1
- package/src/decorators/common/remove-x-internal.ts +4 -4
- package/src/decorators/common/tag-description-override.ts +1 -1
- package/src/format/codeframes.ts +4 -4
- package/src/format/format.ts +10 -10
- package/src/index.ts +2 -3
- package/src/js-yaml/index.ts +3 -8
- package/src/lint.ts +22 -18
- package/src/oas-types.ts +1 -6
- package/src/redocly/__tests__/redocly-client.test.ts +25 -19
- package/src/redocly/index.ts +6 -4
- package/src/redocly/registry-api.ts +6 -6
- package/src/ref-utils.ts +2 -2
- package/src/resolve.ts +7 -4
- package/src/rules/__tests__/no-unresolved-refs.test.ts +4 -4
- package/src/rules/__tests__/utils.test.ts +122 -0
- package/src/rules/ajv.ts +3 -4
- package/src/rules/common/__tests__/info-description.test.ts +3 -3
- package/src/rules/common/__tests__/info-license.test.ts +2 -2
- package/src/rules/common/__tests__/license-url.test.ts +2 -2
- package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -1
- package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +8 -8
- package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -1
- package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +3 -3
- package/src/rules/common/__tests__/operation-2xx-response.test.ts +3 -3
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +3 -3
- package/src/rules/common/__tests__/operation-operationId-unique.test.ts +2 -2
- package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -1
- package/src/rules/common/__tests__/operation-parameters-unique.test.ts +4 -4
- package/src/rules/common/__tests__/operation-security-defined.test.ts +2 -2
- package/src/rules/common/__tests__/operation-singular-tag.test.ts +2 -2
- package/src/rules/common/__tests__/path-http-verbs-order.test.ts +2 -2
- package/src/rules/common/__tests__/path-not-include-query.test.ts +2 -2
- package/src/rules/common/__tests__/path-params-defined.test.ts +3 -3
- package/src/rules/common/__tests__/paths-kebab-case.test.ts +15 -15
- package/src/rules/common/__tests__/scalar-property-missing-example.test.ts +8 -8
- package/src/rules/common/__tests__/spec.test.ts +2 -2
- package/src/rules/common/__tests__/tag-description.test.ts +2 -2
- package/src/rules/common/__tests__/tags-alphabetical.test.ts +2 -2
- package/src/rules/common/assertions/__tests__/asserts.test.ts +513 -130
- package/src/rules/common/assertions/index.ts +6 -6
- package/src/rules/common/info-license-url.ts +4 -9
- package/src/rules/common/info-license.ts +15 -0
- package/src/rules/common/no-ambiguous-paths.ts +1 -1
- package/src/rules/common/no-enum-type-mismatch.ts +12 -9
- package/src/rules/common/no-invalid-parameter-examples.ts +2 -2
- package/src/rules/common/no-invalid-schema-examples.ts +1 -1
- package/src/rules/common/operation-operationId.ts +1 -1
- package/src/rules/common/operation-parameters-unique.ts +2 -2
- package/src/rules/common/path-not-include-query.ts +1 -1
- package/src/rules/common/path-params-defined.ts +1 -1
- package/src/rules/common/paths-kebab-case.ts +4 -1
- package/src/rules/common/scalar-property-missing-example.ts +1 -1
- package/src/rules/common/spec.ts +10 -7
- package/src/rules/no-unresolved-refs.ts +1 -1
- package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +3 -3
- package/src/rules/oas2/__tests__/spec/info.test.ts +12 -12
- package/src/rules/oas2/__tests__/spec/operation.test.ts +4 -4
- package/src/rules/oas2/__tests__/spec/paths.test.ts +10 -10
- package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +6 -2
- package/src/rules/oas2/__tests__/spec/utils.ts +6 -6
- package/src/rules/oas2/index.ts +3 -3
- package/src/rules/oas2/remove-unused-components.ts +13 -8
- package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +3 -3
- package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +2 -2
- package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +8 -8
- package/src/rules/oas3/__tests__/no-server-example.com.test.ts +2 -2
- package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +3 -3
- package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -1
- package/src/rules/oas3/__tests__/spec/callbacks.test.ts +1 -1
- package/src/rules/oas3/__tests__/spec/info.test.ts +12 -12
- package/src/rules/oas3/__tests__/spec/operation.test.ts +8 -8
- package/src/rules/oas3/__tests__/spec/paths.test.ts +10 -10
- package/src/rules/oas3/__tests__/spec/referenceableScalars.test.ts +12 -12
- package/src/rules/oas3/__tests__/spec/servers.test.ts +15 -15
- package/src/rules/oas3/__tests__/spec/spec.test.ts +6 -6
- package/src/rules/oas3/__tests__/spec/utils.ts +6 -6
- package/src/rules/oas3/index.ts +3 -3
- package/src/rules/oas3/no-empty-servers.ts +1 -1
- package/src/rules/oas3/no-invalid-media-type-examples.ts +12 -4
- package/src/rules/oas3/no-servers-empty-enum.ts +9 -10
- package/src/rules/oas3/remove-unused-components.ts +18 -7
- package/src/rules/other/stats.ts +46 -17
- package/src/rules/utils.ts +5 -3
- package/src/types/index.ts +5 -5
- package/src/types/redocly-yaml.ts +8 -7
- package/src/typings/common.ts +9 -1
- package/src/typings/openapi.ts +1 -1
- package/src/visitors.ts +4 -4
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/rules/common/license-url.d.ts +0 -2
- package/lib/rules/common/license-url.js +0 -12
- package/src/rules/common/license-url.ts +0 -10
package/src/bundle.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { Oas3_1Types } from './types/oas3_1';
|
|
|
7
7
|
import { NormalizedNodeType, normalizeTypes, NodeType } from './types';
|
|
8
8
|
import { WalkContext, walkDocument, UserContext, ResolveResult } from './walk';
|
|
9
9
|
import { detectOpenAPI, openAPIMajor, OasMajorVersion } from './oas-types';
|
|
10
|
-
import {isAbsoluteUrl, isRef, Location, refBaseName} from './ref-utils';
|
|
10
|
+
import { isAbsoluteUrl, isRef, Location, refBaseName } from './ref-utils';
|
|
11
11
|
import { initRules } from './config/rules';
|
|
12
12
|
import { reportUnresolvedRef } from './rules/no-unresolved-refs';
|
|
13
13
|
import { isPlainObject } from './utils';
|
|
@@ -16,7 +16,7 @@ import { isRedoclyRegistryURL } from './redocly';
|
|
|
16
16
|
import { RemoveUnusedComponents as RemoveUnusedComponentsOas2 } from './rules/oas2/remove-unused-components';
|
|
17
17
|
import { RemoveUnusedComponents as RemoveUnusedComponentsOas3 } from './rules/oas3/remove-unused-components';
|
|
18
18
|
|
|
19
|
-
import type { Config,
|
|
19
|
+
import type { Config, StyleguideConfig } from './config';
|
|
20
20
|
|
|
21
21
|
export type Oas3RuleSet = Record<string, Oas3Rule>;
|
|
22
22
|
|
|
@@ -57,7 +57,7 @@ export async function bundle(opts: {
|
|
|
57
57
|
return bundleDocument({
|
|
58
58
|
document,
|
|
59
59
|
...opts,
|
|
60
|
-
config: opts.config.
|
|
60
|
+
config: opts.config.styleguide,
|
|
61
61
|
externalRefResolver,
|
|
62
62
|
});
|
|
63
63
|
}
|
|
@@ -66,7 +66,7 @@ type BundleContext = WalkContext;
|
|
|
66
66
|
|
|
67
67
|
export async function bundleDocument(opts: {
|
|
68
68
|
document: Document;
|
|
69
|
-
config:
|
|
69
|
+
config: StyleguideConfig;
|
|
70
70
|
customTypes?: Record<string, NodeType>;
|
|
71
71
|
externalRefResolver: BaseResolver;
|
|
72
72
|
dereference?: boolean;
|
|
@@ -94,9 +94,9 @@ export async function bundleDocument(opts: {
|
|
|
94
94
|
? Oas3_1Types
|
|
95
95
|
: Oas3Types
|
|
96
96
|
: Oas2Types,
|
|
97
|
-
oasVersion
|
|
97
|
+
oasVersion
|
|
98
98
|
),
|
|
99
|
-
config
|
|
99
|
+
config
|
|
100
100
|
);
|
|
101
101
|
|
|
102
102
|
const preprocessors = initRules(rules as any, config, 'preprocessors', oasVersion);
|
|
@@ -113,10 +113,11 @@ export async function bundleDocument(opts: {
|
|
|
113
113
|
decorators.push({
|
|
114
114
|
severity: 'error',
|
|
115
115
|
ruleId: 'remove-unused-components',
|
|
116
|
-
visitor:
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
116
|
+
visitor:
|
|
117
|
+
oasMajorVersion === OasMajorVersion.Version2
|
|
118
|
+
? RemoveUnusedComponentsOas2({})
|
|
119
|
+
: RemoveUnusedComponentsOas3({}),
|
|
120
|
+
});
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
const resolvedRefMap = await resolveDocument({
|
|
@@ -137,12 +138,12 @@ export async function bundleDocument(opts: {
|
|
|
137
138
|
skipRedoclyRegistryRefs,
|
|
138
139
|
document,
|
|
139
140
|
resolvedRefMap,
|
|
140
|
-
keepUrlRefs
|
|
141
|
+
keepUrlRefs
|
|
141
142
|
),
|
|
142
143
|
},
|
|
143
144
|
...decorators,
|
|
144
145
|
] as any,
|
|
145
|
-
types
|
|
146
|
+
types
|
|
146
147
|
);
|
|
147
148
|
|
|
148
149
|
walkDocument({
|
|
@@ -210,7 +211,7 @@ function makeBundleVisitor(
|
|
|
210
211
|
skipRedoclyRegistryRefs: boolean,
|
|
211
212
|
rootDocument: Document,
|
|
212
213
|
resolvedRefMap: ResolvedRefMap,
|
|
213
|
-
keepUrlRefs: boolean
|
|
214
|
+
keepUrlRefs: boolean
|
|
214
215
|
) {
|
|
215
216
|
let components: Record<string, Record<string, any>>;
|
|
216
217
|
|
|
@@ -287,7 +288,7 @@ function makeBundleVisitor(
|
|
|
287
288
|
}
|
|
288
289
|
|
|
289
290
|
function resolveBundledComponent(node: OasRef, resolved: ResolveResult<any>, ctx: UserContext) {
|
|
290
|
-
const newRefId = makeRefId(ctx.location.source.absoluteRef, node.$ref)
|
|
291
|
+
const newRefId = makeRefId(ctx.location.source.absoluteRef, node.$ref);
|
|
291
292
|
resolvedRefMap.set(newRefId, {
|
|
292
293
|
document: rootDocument,
|
|
293
294
|
isRemote: false,
|
|
@@ -310,7 +311,7 @@ function makeBundleVisitor(
|
|
|
310
311
|
function saveComponent(
|
|
311
312
|
componentType: string,
|
|
312
313
|
target: { node: any; location: Location },
|
|
313
|
-
ctx: UserContext
|
|
314
|
+
ctx: UserContext
|
|
314
315
|
) {
|
|
315
316
|
components[componentType] = components[componentType] || {};
|
|
316
317
|
const name = getComponentName(target, componentType, ctx);
|
|
@@ -325,7 +326,7 @@ function makeBundleVisitor(
|
|
|
325
326
|
function isEqualOrEqualRef(
|
|
326
327
|
node: any,
|
|
327
328
|
target: { node: any; location: Location },
|
|
328
|
-
ctx: UserContext
|
|
329
|
+
ctx: UserContext
|
|
329
330
|
) {
|
|
330
331
|
if (
|
|
331
332
|
isRef(node) &&
|
|
@@ -340,7 +341,7 @@ function makeBundleVisitor(
|
|
|
340
341
|
function getComponentName(
|
|
341
342
|
target: { node: any; location: Location },
|
|
342
343
|
componentType: string,
|
|
343
|
-
ctx: UserContext
|
|
344
|
+
ctx: UserContext
|
|
344
345
|
) {
|
|
345
346
|
const [fileRef, pointer] = [target.location.source.absoluteRef, target.location.pointer];
|
|
346
347
|
const componentsGroup = components[componentType];
|
|
@@ -70,7 +70,7 @@ Object {
|
|
|
70
70
|
}
|
|
71
71
|
`;
|
|
72
72
|
|
|
73
|
-
exports[`
|
|
73
|
+
exports[`resolveStyleguideConfig should resolve extends with local file config witch contains path to nested config 1`] = `
|
|
74
74
|
Object {
|
|
75
75
|
"decorators": Object {},
|
|
76
76
|
"doNotResolveExamples": undefined,
|
|
@@ -1,52 +1,52 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { resolveStyleguideConfig, resolveApis, resolveConfig } from '../config-resolvers';
|
|
2
2
|
const path = require('path');
|
|
3
3
|
|
|
4
|
-
import type {
|
|
4
|
+
import type { StyleguideRawConfig, RawConfig } from '../types';
|
|
5
5
|
|
|
6
6
|
const configPath = path.join(__dirname, 'fixtures/resolve-config/.redocly.yaml');
|
|
7
|
-
const
|
|
7
|
+
const baseStyleguideConfig: StyleguideRawConfig = {
|
|
8
8
|
rules: {
|
|
9
9
|
'operation-2xx-response': 'warn',
|
|
10
10
|
},
|
|
11
11
|
};
|
|
12
12
|
|
|
13
|
-
const
|
|
14
|
-
|
|
13
|
+
const minimalStyleguidePreset = resolveStyleguideConfig({
|
|
14
|
+
styleguideConfig: { ...baseStyleguideConfig, extends: ['minimal'] },
|
|
15
15
|
});
|
|
16
16
|
|
|
17
|
-
const
|
|
18
|
-
|
|
17
|
+
const recommendedStyleguidePreset = resolveStyleguideConfig({
|
|
18
|
+
styleguideConfig: { ...baseStyleguideConfig, extends: ['recommended'] },
|
|
19
19
|
});
|
|
20
20
|
|
|
21
21
|
const removeAbsolutePath = (item: string) =>
|
|
22
22
|
item.match(/^.*\/packages\/core\/src\/config\/__tests__\/fixtures\/(.*)$/)![1];
|
|
23
23
|
|
|
24
|
-
describe('
|
|
24
|
+
describe('resolveStyleguideConfig', () => {
|
|
25
25
|
it('should return the config with no recommended', async () => {
|
|
26
|
-
const
|
|
27
|
-
expect(
|
|
28
|
-
expect(
|
|
29
|
-
expect(
|
|
26
|
+
const styleguide = await resolveStyleguideConfig({ styleguideConfig: baseStyleguideConfig });
|
|
27
|
+
expect(styleguide.plugins?.length).toEqual(1);
|
|
28
|
+
expect(styleguide.plugins?.[0].id).toEqual('');
|
|
29
|
+
expect(styleguide.rules).toEqual({
|
|
30
30
|
'operation-2xx-response': 'warn',
|
|
31
31
|
});
|
|
32
32
|
});
|
|
33
33
|
|
|
34
34
|
it('should return the config with correct order by preset', async () => {
|
|
35
35
|
expect(
|
|
36
|
-
await
|
|
37
|
-
|
|
38
|
-
})
|
|
39
|
-
).toEqual(await
|
|
36
|
+
await resolveStyleguideConfig({
|
|
37
|
+
styleguideConfig: { ...baseStyleguideConfig, extends: ['minimal', 'recommended'] },
|
|
38
|
+
})
|
|
39
|
+
).toEqual(await recommendedStyleguidePreset);
|
|
40
40
|
expect(
|
|
41
|
-
await
|
|
42
|
-
|
|
43
|
-
})
|
|
44
|
-
).toEqual(await
|
|
41
|
+
await resolveStyleguideConfig({
|
|
42
|
+
styleguideConfig: { ...baseStyleguideConfig, extends: ['recommended', 'minimal'] },
|
|
43
|
+
})
|
|
44
|
+
).toEqual(await minimalStyleguidePreset);
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
-
it('should return the same
|
|
48
|
-
const configWithEmptyExtends = await
|
|
49
|
-
|
|
47
|
+
it('should return the same styleguideConfig when extends is empty array', async () => {
|
|
48
|
+
const configWithEmptyExtends = await resolveStyleguideConfig({
|
|
49
|
+
styleguideConfig: { ...baseStyleguideConfig, extends: [] },
|
|
50
50
|
});
|
|
51
51
|
expect(configWithEmptyExtends.plugins?.length).toEqual(1);
|
|
52
52
|
expect(configWithEmptyExtends.plugins?.[0].id).toEqual('');
|
|
@@ -57,27 +57,27 @@ describe('resolveLint', () => {
|
|
|
57
57
|
|
|
58
58
|
it('should resolve extends with local file config', async () => {
|
|
59
59
|
const config = {
|
|
60
|
-
...
|
|
60
|
+
...baseStyleguideConfig,
|
|
61
61
|
extends: ['local-config.yaml'],
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
const { plugins, ...
|
|
65
|
-
|
|
64
|
+
const { plugins, ...styleguide } = await resolveStyleguideConfig({
|
|
65
|
+
styleguideConfig: config,
|
|
66
66
|
configPath,
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
expect(
|
|
69
|
+
expect(styleguide?.rules?.['operation-2xx-response']).toEqual('warn');
|
|
70
70
|
expect(plugins).toBeDefined();
|
|
71
71
|
expect(plugins?.length).toBe(2);
|
|
72
72
|
|
|
73
|
-
expect(
|
|
73
|
+
expect(styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
74
74
|
'resolve-config/.redocly.yaml',
|
|
75
75
|
'resolve-config/local-config.yaml',
|
|
76
76
|
'resolve-config/.redocly.yaml',
|
|
77
77
|
]);
|
|
78
|
-
expect(
|
|
78
|
+
expect(styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual(['resolve-config/plugin.js']);
|
|
79
79
|
|
|
80
|
-
expect(
|
|
80
|
+
expect(styleguide.rules).toEqual({
|
|
81
81
|
'boolean-parameter-prefixes': 'error',
|
|
82
82
|
'local/operation-id-not-test': 'error',
|
|
83
83
|
'no-invalid-media-type-examples': 'error',
|
|
@@ -90,64 +90,64 @@ describe('resolveLint', () => {
|
|
|
90
90
|
// TODO: fix circular test
|
|
91
91
|
it.skip('should throw circular error', () => {
|
|
92
92
|
const config = {
|
|
93
|
-
...
|
|
93
|
+
...baseStyleguideConfig,
|
|
94
94
|
extends: ['local-config-with-circular.yaml'],
|
|
95
95
|
};
|
|
96
96
|
expect(() => {
|
|
97
|
-
|
|
97
|
+
resolveStyleguideConfig({ styleguideConfig: config, configPath });
|
|
98
98
|
}).toThrow('Circular dependency in config file');
|
|
99
99
|
});
|
|
100
100
|
|
|
101
101
|
it('should resolve extends with local file config witch contains path to nested config', async () => {
|
|
102
|
-
const
|
|
102
|
+
const styleguideConfig = {
|
|
103
103
|
extends: ['local-config-with-file.yaml'],
|
|
104
104
|
};
|
|
105
|
-
const { plugins, ...
|
|
106
|
-
|
|
105
|
+
const { plugins, ...styleguide } = await resolveStyleguideConfig({
|
|
106
|
+
styleguideConfig,
|
|
107
107
|
configPath,
|
|
108
108
|
});
|
|
109
109
|
|
|
110
|
-
expect(
|
|
111
|
-
expect(
|
|
112
|
-
expect(
|
|
110
|
+
expect(styleguide?.rules?.['no-invalid-media-type-examples']).toEqual('warn');
|
|
111
|
+
expect(styleguide?.rules?.['operation-4xx-response']).toEqual('off');
|
|
112
|
+
expect(styleguide?.rules?.['operation-2xx-response']).toEqual('error');
|
|
113
113
|
expect(plugins).toBeDefined();
|
|
114
114
|
expect(plugins?.length).toBe(3);
|
|
115
115
|
|
|
116
|
-
expect(
|
|
116
|
+
expect(styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
117
117
|
'resolve-config/.redocly.yaml',
|
|
118
118
|
'resolve-config/local-config-with-file.yaml',
|
|
119
119
|
'resolve-config/api/nested-config.yaml',
|
|
120
120
|
'resolve-config/.redocly.yaml',
|
|
121
121
|
]);
|
|
122
|
-
expect(
|
|
122
|
+
expect(styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([
|
|
123
123
|
'resolve-config/api/plugin.js',
|
|
124
124
|
'resolve-config/plugin.js',
|
|
125
125
|
'resolve-config/api/plugin.js',
|
|
126
126
|
]);
|
|
127
127
|
|
|
128
|
-
delete
|
|
129
|
-
delete
|
|
130
|
-
expect(
|
|
128
|
+
delete styleguide.extendPaths;
|
|
129
|
+
delete styleguide.pluginPaths;
|
|
130
|
+
expect(styleguide).toMatchSnapshot();
|
|
131
131
|
});
|
|
132
132
|
|
|
133
133
|
it('should correctly merge assertions from nested config', async () => {
|
|
134
|
-
const
|
|
134
|
+
const styleguideConfig = {
|
|
135
135
|
extends: ['local-config-with-file.yaml'],
|
|
136
136
|
};
|
|
137
137
|
|
|
138
|
-
const
|
|
139
|
-
|
|
138
|
+
const styleguide = await resolveStyleguideConfig({
|
|
139
|
+
styleguideConfig,
|
|
140
140
|
configPath,
|
|
141
141
|
});
|
|
142
142
|
|
|
143
|
-
expect(Array.isArray(
|
|
144
|
-
expect(
|
|
143
|
+
expect(Array.isArray(styleguide.rules?.assertions)).toEqual(true);
|
|
144
|
+
expect(styleguide.rules?.assertions).toMatchObject([
|
|
145
145
|
{
|
|
146
146
|
subject: 'PathItem',
|
|
147
147
|
property: 'get',
|
|
148
148
|
message: 'Every path item must have a GET operation.',
|
|
149
149
|
defined: true,
|
|
150
|
-
assertionId: 'path-item-get-defined'
|
|
150
|
+
assertionId: 'path-item-get-defined',
|
|
151
151
|
},
|
|
152
152
|
{
|
|
153
153
|
subject: 'Tag',
|
|
@@ -156,51 +156,51 @@ describe('resolveLint', () => {
|
|
|
156
156
|
severity: 'error',
|
|
157
157
|
minLength: 13,
|
|
158
158
|
pattern: '/\\.$/',
|
|
159
|
-
assertionId: 'tag-description'
|
|
160
|
-
}
|
|
161
|
-
])
|
|
159
|
+
assertionId: 'tag-description',
|
|
160
|
+
},
|
|
161
|
+
]);
|
|
162
162
|
});
|
|
163
163
|
|
|
164
164
|
it('should resolve extends with url file config witch contains path to nested config', async () => {
|
|
165
|
-
const
|
|
165
|
+
const styleguideConfig = {
|
|
166
166
|
// This points to ./fixtures/resolve-remote-configs/remote-config.yaml
|
|
167
167
|
extends: [
|
|
168
168
|
'https://raw.githubusercontent.com/Redocly/redocly-cli/master/packages/core/src/config/__tests__/fixtures/resolve-remote-configs/remote-config.yaml',
|
|
169
169
|
],
|
|
170
170
|
};
|
|
171
171
|
|
|
172
|
-
const { plugins, ...
|
|
173
|
-
|
|
172
|
+
const { plugins, ...styleguide } = await resolveStyleguideConfig({
|
|
173
|
+
styleguideConfig,
|
|
174
174
|
configPath,
|
|
175
175
|
});
|
|
176
176
|
|
|
177
|
-
expect(
|
|
178
|
-
expect(
|
|
179
|
-
expect(Object.keys(
|
|
177
|
+
expect(styleguide?.rules?.['operation-4xx-response']).toEqual('error');
|
|
178
|
+
expect(styleguide?.rules?.['operation-2xx-response']).toEqual('error');
|
|
179
|
+
expect(Object.keys(styleguide.rules || {}).length).toBe(2);
|
|
180
180
|
|
|
181
|
-
expect(
|
|
181
|
+
expect(styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
182
182
|
'resolve-config/.redocly.yaml',
|
|
183
183
|
'resolve-config/.redocly.yaml',
|
|
184
184
|
]);
|
|
185
|
-
expect(
|
|
185
|
+
expect(styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
|
|
186
186
|
});
|
|
187
187
|
});
|
|
188
188
|
|
|
189
189
|
describe('resolveApis', () => {
|
|
190
|
-
it('should resolve apis
|
|
190
|
+
it('should resolve apis styleguideConfig and merge minimal extends', async () => {
|
|
191
191
|
const rawConfig: RawConfig = {
|
|
192
192
|
apis: {
|
|
193
193
|
petstore: {
|
|
194
194
|
root: 'some/path',
|
|
195
|
-
|
|
195
|
+
styleguide: {},
|
|
196
196
|
},
|
|
197
197
|
},
|
|
198
|
-
|
|
198
|
+
styleguide: {
|
|
199
199
|
extends: ['minimal'],
|
|
200
200
|
},
|
|
201
201
|
};
|
|
202
202
|
const apisResult = await resolveApis({ rawConfig });
|
|
203
|
-
expect(apisResult['petstore'].
|
|
203
|
+
expect(apisResult['petstore'].styleguide).toEqual(await minimalStyleguidePreset);
|
|
204
204
|
});
|
|
205
205
|
|
|
206
206
|
it('should not merge recommended extends by default by every level', async () => {
|
|
@@ -208,39 +208,39 @@ describe('resolveApis', () => {
|
|
|
208
208
|
apis: {
|
|
209
209
|
petstore: {
|
|
210
210
|
root: 'some/path',
|
|
211
|
-
|
|
211
|
+
styleguide: {},
|
|
212
212
|
},
|
|
213
213
|
},
|
|
214
|
-
|
|
214
|
+
styleguide: {},
|
|
215
215
|
};
|
|
216
216
|
|
|
217
217
|
const apisResult = await resolveApis({ rawConfig, configPath });
|
|
218
218
|
|
|
219
|
-
expect(apisResult['petstore'].
|
|
219
|
+
expect(apisResult['petstore'].styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
220
220
|
'resolve-config/.redocly.yaml',
|
|
221
221
|
]);
|
|
222
|
-
expect(apisResult['petstore'].
|
|
222
|
+
expect(apisResult['petstore'].styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
|
|
223
223
|
|
|
224
|
-
expect(apisResult['petstore'].
|
|
224
|
+
expect(apisResult['petstore'].styleguide.rules).toEqual({});
|
|
225
225
|
//@ts-ignore
|
|
226
|
-
expect(apisResult['petstore'].
|
|
226
|
+
expect(apisResult['petstore'].styleguide.plugins.length).toEqual(1);
|
|
227
227
|
//@ts-ignore
|
|
228
|
-
expect(apisResult['petstore'].
|
|
228
|
+
expect(apisResult['petstore'].styleguide.plugins[0].id).toEqual('');
|
|
229
229
|
});
|
|
230
230
|
|
|
231
|
-
it('should resolve apis
|
|
231
|
+
it('should resolve apis styleguideConfig when it contains file and not set recommended', async () => {
|
|
232
232
|
const rawConfig: RawConfig = {
|
|
233
233
|
apis: {
|
|
234
234
|
petstore: {
|
|
235
235
|
root: 'some/path',
|
|
236
|
-
|
|
236
|
+
styleguide: {
|
|
237
237
|
rules: {
|
|
238
238
|
'operation-4xx-response': 'error',
|
|
239
239
|
},
|
|
240
240
|
},
|
|
241
241
|
},
|
|
242
242
|
},
|
|
243
|
-
|
|
243
|
+
styleguide: {
|
|
244
244
|
rules: {
|
|
245
245
|
'operation-2xx-response': 'warn',
|
|
246
246
|
},
|
|
@@ -248,27 +248,27 @@ describe('resolveApis', () => {
|
|
|
248
248
|
};
|
|
249
249
|
|
|
250
250
|
const apisResult = await resolveApis({ rawConfig, configPath });
|
|
251
|
-
expect(apisResult['petstore'].
|
|
251
|
+
expect(apisResult['petstore'].styleguide.rules).toEqual({
|
|
252
252
|
'operation-2xx-response': 'warn',
|
|
253
253
|
'operation-4xx-response': 'error',
|
|
254
254
|
});
|
|
255
255
|
//@ts-ignore
|
|
256
|
-
expect(apisResult['petstore'].
|
|
256
|
+
expect(apisResult['petstore'].styleguide.plugins.length).toEqual(1);
|
|
257
257
|
//@ts-ignore
|
|
258
|
-
expect(apisResult['petstore'].
|
|
258
|
+
expect(apisResult['petstore'].styleguide.plugins[0].id).toEqual('');
|
|
259
259
|
|
|
260
|
-
expect(apisResult['petstore'].
|
|
260
|
+
expect(apisResult['petstore'].styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
261
261
|
'resolve-config/.redocly.yaml',
|
|
262
262
|
]);
|
|
263
|
-
expect(apisResult['petstore'].
|
|
263
|
+
expect(apisResult['petstore'].styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
|
|
264
264
|
});
|
|
265
265
|
|
|
266
|
-
it('should resolve apis
|
|
266
|
+
it('should resolve apis styleguideConfig when it contains file', async () => {
|
|
267
267
|
const rawConfig: RawConfig = {
|
|
268
268
|
apis: {
|
|
269
269
|
petstore: {
|
|
270
270
|
root: 'some/path',
|
|
271
|
-
|
|
271
|
+
styleguide: {
|
|
272
272
|
extends: ['local-config.yaml'],
|
|
273
273
|
rules: {
|
|
274
274
|
'operation-4xx-response': 'error',
|
|
@@ -276,7 +276,7 @@ describe('resolveApis', () => {
|
|
|
276
276
|
},
|
|
277
277
|
},
|
|
278
278
|
},
|
|
279
|
-
|
|
279
|
+
styleguide: {
|
|
280
280
|
extends: ['minimal'],
|
|
281
281
|
rules: {
|
|
282
282
|
'operation-2xx-response': 'warn',
|
|
@@ -285,19 +285,21 @@ describe('resolveApis', () => {
|
|
|
285
285
|
};
|
|
286
286
|
|
|
287
287
|
const apisResult = await resolveApis({ rawConfig, configPath });
|
|
288
|
-
expect(apisResult['petstore'].
|
|
289
|
-
expect(apisResult['petstore'].
|
|
290
|
-
expect(apisResult['petstore'].
|
|
291
|
-
expect(apisResult['petstore'].
|
|
288
|
+
expect(apisResult['petstore'].styleguide.rules).toBeDefined();
|
|
289
|
+
expect(apisResult['petstore'].styleguide.rules?.['operation-2xx-response']).toEqual('warn'); // think about prioritize in merge ???
|
|
290
|
+
expect(apisResult['petstore'].styleguide.rules?.['operation-4xx-response']).toEqual('error');
|
|
291
|
+
expect(apisResult['petstore'].styleguide.rules?.['local/operation-id-not-test']).toEqual(
|
|
292
|
+
'error'
|
|
293
|
+
);
|
|
292
294
|
//@ts-ignore
|
|
293
|
-
expect(apisResult['petstore'].
|
|
295
|
+
expect(apisResult['petstore'].styleguide.plugins.length).toEqual(2);
|
|
294
296
|
|
|
295
|
-
expect(apisResult['petstore'].
|
|
297
|
+
expect(apisResult['petstore'].styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
296
298
|
'resolve-config/.redocly.yaml',
|
|
297
299
|
'resolve-config/local-config.yaml',
|
|
298
300
|
'resolve-config/.redocly.yaml',
|
|
299
301
|
]);
|
|
300
|
-
expect(apisResult['petstore'].
|
|
302
|
+
expect(apisResult['petstore'].styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([
|
|
301
303
|
'resolve-config/plugin.js',
|
|
302
304
|
]);
|
|
303
305
|
});
|
|
@@ -309,14 +311,14 @@ describe('resolveConfig', () => {
|
|
|
309
311
|
apis: {
|
|
310
312
|
petstore: {
|
|
311
313
|
root: 'some/path',
|
|
312
|
-
|
|
314
|
+
styleguide: {
|
|
313
315
|
rules: {
|
|
314
316
|
'operation-4xx-response': 'error',
|
|
315
317
|
},
|
|
316
318
|
},
|
|
317
319
|
},
|
|
318
320
|
},
|
|
319
|
-
|
|
321
|
+
styleguide: {
|
|
320
322
|
rules: {
|
|
321
323
|
'operation-2xx-response': 'warn',
|
|
322
324
|
},
|
|
@@ -325,17 +327,17 @@ describe('resolveConfig', () => {
|
|
|
325
327
|
|
|
326
328
|
const { apis } = await resolveConfig(rawConfig, configPath);
|
|
327
329
|
//@ts-ignore
|
|
328
|
-
expect(apis['petstore'].
|
|
330
|
+
expect(apis['petstore'].styleguide.plugins.length).toEqual(1);
|
|
329
331
|
//@ts-ignore
|
|
330
|
-
expect(apis['petstore'].
|
|
332
|
+
expect(apis['petstore'].styleguide.plugins[0].id).toEqual('');
|
|
331
333
|
|
|
332
|
-
expect(apis['petstore'].
|
|
334
|
+
expect(apis['petstore'].styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
333
335
|
'resolve-config/.redocly.yaml',
|
|
334
336
|
]);
|
|
335
|
-
expect(apis['petstore'].
|
|
337
|
+
expect(apis['petstore'].styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([]);
|
|
336
338
|
|
|
337
|
-
expect(apis['petstore'].
|
|
338
|
-
...(await
|
|
339
|
+
expect(apis['petstore'].styleguide.rules).toEqual({
|
|
340
|
+
...(await recommendedStyleguidePreset).rules,
|
|
339
341
|
'operation-2xx-response': 'warn',
|
|
340
342
|
'operation-4xx-response': 'error',
|
|
341
343
|
});
|
|
@@ -346,7 +348,7 @@ describe('resolveConfig', () => {
|
|
|
346
348
|
apis: {
|
|
347
349
|
petstore: {
|
|
348
350
|
root: 'some/path',
|
|
349
|
-
|
|
351
|
+
styleguide: {
|
|
350
352
|
extends: ['local-config.yaml'],
|
|
351
353
|
rules: {
|
|
352
354
|
'operation-4xx-response': 'error',
|
|
@@ -354,7 +356,7 @@ describe('resolveConfig', () => {
|
|
|
354
356
|
},
|
|
355
357
|
},
|
|
356
358
|
},
|
|
357
|
-
|
|
359
|
+
styleguide: {
|
|
358
360
|
rules: {
|
|
359
361
|
'operation-2xx-response': 'warn',
|
|
360
362
|
},
|
|
@@ -362,24 +364,24 @@ describe('resolveConfig', () => {
|
|
|
362
364
|
};
|
|
363
365
|
|
|
364
366
|
const { apis } = await resolveConfig(rawConfig, configPath);
|
|
365
|
-
expect(apis['petstore'].
|
|
366
|
-
expect(Object.keys(apis['petstore'].
|
|
367
|
-
expect(apis['petstore'].
|
|
368
|
-
expect(apis['petstore'].
|
|
369
|
-
expect(apis['petstore'].
|
|
367
|
+
expect(apis['petstore'].styleguide.rules).toBeDefined();
|
|
368
|
+
expect(Object.keys(apis['petstore'].styleguide.rules || {}).length).toEqual(7);
|
|
369
|
+
expect(apis['petstore'].styleguide.rules?.['operation-2xx-response']).toEqual('warn');
|
|
370
|
+
expect(apis['petstore'].styleguide.rules?.['operation-4xx-response']).toEqual('error');
|
|
371
|
+
expect(apis['petstore'].styleguide.rules?.['operation-description']).toEqual('error'); // from extends file config
|
|
370
372
|
//@ts-ignore
|
|
371
|
-
expect(apis['petstore'].
|
|
373
|
+
expect(apis['petstore'].styleguide.plugins.length).toEqual(2);
|
|
372
374
|
|
|
373
|
-
expect(apis['petstore'].
|
|
375
|
+
expect(apis['petstore'].styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
374
376
|
'resolve-config/.redocly.yaml',
|
|
375
377
|
'resolve-config/local-config.yaml',
|
|
376
378
|
'resolve-config/.redocly.yaml',
|
|
377
379
|
]);
|
|
378
|
-
expect(apis['petstore'].
|
|
380
|
+
expect(apis['petstore'].styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([
|
|
379
381
|
'resolve-config/plugin.js',
|
|
380
382
|
]);
|
|
381
383
|
|
|
382
|
-
expect(apis['petstore'].
|
|
384
|
+
expect(apis['petstore'].styleguide.recommendedFallback).toBe(false);
|
|
383
385
|
});
|
|
384
386
|
|
|
385
387
|
it('should ignore minimal from the root and read local file', async () => {
|
|
@@ -387,7 +389,7 @@ describe('resolveConfig', () => {
|
|
|
387
389
|
apis: {
|
|
388
390
|
petstore: {
|
|
389
391
|
root: 'some/path',
|
|
390
|
-
|
|
392
|
+
styleguide: {
|
|
391
393
|
extends: ['recommended', 'local-config.yaml'],
|
|
392
394
|
rules: {
|
|
393
395
|
'operation-4xx-response': 'error',
|
|
@@ -395,7 +397,7 @@ describe('resolveConfig', () => {
|
|
|
395
397
|
},
|
|
396
398
|
},
|
|
397
399
|
},
|
|
398
|
-
|
|
400
|
+
styleguide: {
|
|
399
401
|
extends: ['minimal'],
|
|
400
402
|
rules: {
|
|
401
403
|
'operation-2xx-response': 'warn',
|
|
@@ -404,26 +406,26 @@ describe('resolveConfig', () => {
|
|
|
404
406
|
};
|
|
405
407
|
|
|
406
408
|
const { apis } = await resolveConfig(rawConfig, configPath);
|
|
407
|
-
expect(apis['petstore'].
|
|
408
|
-
expect(apis['petstore'].
|
|
409
|
-
expect(apis['petstore'].
|
|
410
|
-
expect(apis['petstore'].
|
|
409
|
+
expect(apis['petstore'].styleguide.rules).toBeDefined();
|
|
410
|
+
expect(apis['petstore'].styleguide.rules?.['operation-2xx-response']).toEqual('warn');
|
|
411
|
+
expect(apis['petstore'].styleguide.rules?.['operation-4xx-response']).toEqual('error');
|
|
412
|
+
expect(apis['petstore'].styleguide.rules?.['operation-description']).toEqual('error'); // from extends file config
|
|
411
413
|
//@ts-ignore
|
|
412
|
-
expect(apis['petstore'].
|
|
414
|
+
expect(apis['petstore'].styleguide.plugins.length).toEqual(2);
|
|
413
415
|
//@ts-ignore
|
|
414
|
-
delete apis['petstore'].
|
|
416
|
+
delete apis['petstore'].styleguide.plugins;
|
|
415
417
|
|
|
416
|
-
expect(apis['petstore'].
|
|
418
|
+
expect(apis['petstore'].styleguide.extendPaths!.map(removeAbsolutePath)).toEqual([
|
|
417
419
|
'resolve-config/.redocly.yaml',
|
|
418
420
|
'resolve-config/local-config.yaml',
|
|
419
421
|
'resolve-config/.redocly.yaml',
|
|
420
422
|
]);
|
|
421
|
-
expect(apis['petstore'].
|
|
423
|
+
expect(apis['petstore'].styleguide.pluginPaths!.map(removeAbsolutePath)).toEqual([
|
|
422
424
|
'resolve-config/plugin.js',
|
|
423
425
|
]);
|
|
424
426
|
|
|
425
|
-
delete apis['petstore'].
|
|
426
|
-
delete apis['petstore'].
|
|
427
|
-
expect(apis['petstore'].
|
|
427
|
+
delete apis['petstore'].styleguide.extendPaths;
|
|
428
|
+
delete apis['petstore'].styleguide.pluginPaths;
|
|
429
|
+
expect(apis['petstore'].styleguide).toMatchSnapshot();
|
|
428
430
|
});
|
|
429
431
|
});
|