@redocly/openapi-core 1.0.0-beta.76 → 1.0.0-beta.80
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__/utils.ts +11 -1
- package/lib/bundle.d.ts +3 -1
- package/lib/bundle.js +30 -8
- package/lib/config/builtIn.js +18 -4
- package/lib/config/config.d.ts +2 -9
- package/lib/{rules → decorators}/common/info-description-override.d.ts +0 -0
- package/lib/{rules → decorators}/common/info-description-override.js +0 -0
- package/lib/{rules → decorators}/common/operation-description-override.d.ts +0 -0
- package/lib/{rules → decorators}/common/operation-description-override.js +0 -0
- package/lib/{rules → decorators}/common/registry-dependencies.d.ts +0 -0
- package/lib/{rules → decorators}/common/registry-dependencies.js +0 -0
- package/lib/decorators/common/remove-x-internal.d.ts +2 -0
- package/lib/decorators/common/remove-x-internal.js +58 -0
- package/lib/{rules → decorators}/common/tag-description-override.d.ts +0 -0
- package/lib/{rules → decorators}/common/tag-description-override.js +0 -0
- package/lib/decorators/oas2/index.d.ts +8 -0
- package/lib/decorators/oas2/index.js +15 -0
- package/lib/decorators/oas3/index.d.ts +8 -0
- package/lib/decorators/oas3/index.js +15 -0
- package/lib/format/format.d.ts +1 -1
- package/lib/format/format.js +39 -1
- package/lib/js-yaml/index.js +1 -1
- package/lib/resolve.d.ts +1 -0
- package/lib/resolve.js +7 -3
- package/lib/rules/oas2/index.d.ts +1 -7
- package/lib/rules/oas2/index.js +1 -11
- package/lib/rules/oas2/remove-unused-components.d.ts +2 -0
- package/lib/rules/oas2/remove-unused-components.js +73 -0
- package/lib/rules/oas3/index.d.ts +0 -7
- package/lib/rules/oas3/index.js +1 -11
- package/lib/rules/oas3/remove-unused-components.d.ts +2 -0
- package/lib/rules/oas3/remove-unused-components.js +83 -0
- package/lib/typings/swagger.d.ts +14 -0
- package/lib/utils.d.ts +2 -0
- package/lib/utils.js +9 -1
- package/lib/walk.js +5 -8
- package/package.json +1 -1
- package/src/__tests__/js-yaml.test.ts +29 -5
- package/src/__tests__/lint.test.ts +1 -3
- package/src/bundle.ts +37 -8
- package/src/config/builtIn.ts +20 -7
- package/src/config/config.ts +2 -3
- package/src/decorators/__tests__/remove-x-internal.test.ts +316 -0
- package/src/{rules → decorators}/common/info-description-override.ts +0 -0
- package/src/{rules → decorators}/common/operation-description-override.ts +0 -0
- package/src/{rules → decorators}/common/registry-dependencies.ts +0 -0
- package/src/decorators/common/remove-x-internal.ts +59 -0
- package/src/{rules → decorators}/common/tag-description-override.ts +0 -0
- package/src/decorators/oas2/index.ts +14 -0
- package/src/decorators/oas3/index.ts +14 -0
- package/src/format/format.ts +47 -2
- package/src/js-yaml/index.ts +1 -2
- package/src/resolve.ts +6 -6
- package/src/rules/__tests__/no-unresolved-refs.test.ts +1 -4
- package/src/rules/common/__tests__/info-description.test.ts +1 -3
- package/src/rules/common/__tests__/info-license.test.ts +1 -2
- package/src/rules/common/__tests__/license-url.test.ts +1 -2
- package/src/rules/common/__tests__/no-ambiguous-paths.test.ts +1 -2
- package/src/rules/common/__tests__/no-enum-type-mismatch.test.ts +1 -2
- package/src/rules/common/__tests__/no-identical-paths.test.ts +1 -2
- package/src/rules/common/__tests__/no-path-trailing-slash.test.ts +1 -2
- package/src/rules/common/__tests__/operation-2xx-response.test.ts +1 -2
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +1 -2
- package/src/rules/common/__tests__/operation-operationId-unique.test.ts +1 -2
- package/src/rules/common/__tests__/operation-operationId-url-safe.test.ts +1 -2
- package/src/rules/common/__tests__/operation-parameters-unique.test.ts +1 -2
- package/src/rules/common/__tests__/operation-security-defined.test.ts +1 -2
- package/src/rules/common/__tests__/operation-singular-tag.test.ts +1 -2
- package/src/rules/common/__tests__/path-http-verbs-order.test.ts +1 -2
- package/src/rules/common/__tests__/path-not-include-query.test.ts +1 -2
- package/src/rules/common/__tests__/path-params-defined.test.ts +1 -2
- package/src/rules/common/__tests__/paths-kebab-case.test.ts +1 -2
- package/src/rules/common/__tests__/tag-description.test.ts +1 -2
- package/src/rules/common/__tests__/tags-alphabetical.test.ts +1 -2
- package/src/rules/oas2/__tests__/boolean-parameter-prefixes.test.ts +1 -2
- package/src/rules/oas2/__tests__/spec/referenceableScalars.test.ts +1 -2
- package/src/rules/oas2/index.ts +1 -11
- package/src/rules/oas2/remove-unused-components.ts +76 -0
- package/src/rules/oas3/__tests__/boolean-parameter-prefixes.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-empty-enum-servers.com.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-example-value-and-externalValue.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-server-example.com.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-server-trailing-slash.test.ts +1 -2
- package/src/rules/oas3/__tests__/no-unused-components.test.ts +1 -2
- package/src/rules/oas3/index.ts +0 -12
- package/src/rules/oas3/remove-unused-components.ts +84 -0
- package/src/types/oas2.ts +0 -3
- package/src/typings/swagger.ts +7 -0
- package/src/utils.ts +8 -0
- package/src/walk.ts +6 -13
- package/tsconfig.tsbuildinfo +1 -1
- package/lib/rules/builtin.d.ts +0 -20
- package/lib/rules/builtin.js +0 -17
- package/src/rules/__tests__/config.ts +0 -10
- package/src/rules/builtin.ts +0 -18
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RemoveUnusedComponents = void 0;
|
|
4
|
+
const utils_1 = require("../../utils");
|
|
5
|
+
const RemoveUnusedComponents = () => {
|
|
6
|
+
let components = new Map();
|
|
7
|
+
function registerComponent(location, componentType, name) {
|
|
8
|
+
var _a;
|
|
9
|
+
components.set(location.absolutePointer, {
|
|
10
|
+
used: ((_a = components.get(location.absolutePointer)) === null || _a === void 0 ? void 0 : _a.used) || false,
|
|
11
|
+
componentType,
|
|
12
|
+
name,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
return {
|
|
16
|
+
ref: {
|
|
17
|
+
leave(ref, { type, resolve, key }) {
|
|
18
|
+
if (['Schema', 'Header', 'Parameter', 'Response', 'Example', 'RequestBody'].includes(type.name)) {
|
|
19
|
+
const resolvedRef = resolve(ref);
|
|
20
|
+
if (!resolvedRef.location)
|
|
21
|
+
return;
|
|
22
|
+
components.set(resolvedRef.location.absolutePointer, {
|
|
23
|
+
used: true,
|
|
24
|
+
name: key.toString(),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
DefinitionRoot: {
|
|
30
|
+
leave(root, ctx) {
|
|
31
|
+
const data = ctx.getVisitorData();
|
|
32
|
+
data.removedCount = 0;
|
|
33
|
+
components.forEach(usageInfo => {
|
|
34
|
+
const { used, componentType, name } = usageInfo;
|
|
35
|
+
if (!used && componentType) {
|
|
36
|
+
let componentChild = root.components[componentType];
|
|
37
|
+
delete componentChild[name];
|
|
38
|
+
data.removedCount++;
|
|
39
|
+
if (utils_1.isEmptyObject(componentChild)) {
|
|
40
|
+
delete root.components[componentType];
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
if (utils_1.isEmptyObject(root.components)) {
|
|
45
|
+
delete root.components;
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
NamedSchemas: {
|
|
50
|
+
Schema(schema, { location, key }) {
|
|
51
|
+
if (!schema.allOf) {
|
|
52
|
+
registerComponent(location, 'schemas', key.toString());
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
NamedParameters: {
|
|
57
|
+
Parameter(_parameter, { location, key }) {
|
|
58
|
+
registerComponent(location, 'parameters', key.toString());
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
NamedResponses: {
|
|
62
|
+
Response(_response, { location, key }) {
|
|
63
|
+
registerComponent(location, 'responses', key.toString());
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
NamedExamples: {
|
|
67
|
+
Example(_example, { location, key }) {
|
|
68
|
+
registerComponent(location, 'examples', key.toString());
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
NamedRequestBodies: {
|
|
72
|
+
RequestBody(_requestBody, { location, key }) {
|
|
73
|
+
registerComponent(location, 'requestBodies', key.toString());
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
NamedHeaders: {
|
|
77
|
+
Header(_header, { location, key }) {
|
|
78
|
+
registerComponent(location, 'headers', key.toString());
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
exports.RemoveUnusedComponents = RemoveUnusedComponents;
|
package/lib/typings/swagger.d.ts
CHANGED
|
@@ -16,6 +16,20 @@ export interface Oas2Definition {
|
|
|
16
16
|
tags?: Oas2Tag[];
|
|
17
17
|
externalDocs?: Oas2ExternalDocs;
|
|
18
18
|
}
|
|
19
|
+
export interface Oas2Components {
|
|
20
|
+
definitions?: {
|
|
21
|
+
[name: string]: Record<string, Oas2Schema>;
|
|
22
|
+
};
|
|
23
|
+
securityDefinitions?: {
|
|
24
|
+
[name: string]: Record<string, Oas2SecurityScheme>;
|
|
25
|
+
};
|
|
26
|
+
responses?: {
|
|
27
|
+
[name: string]: Record<string, Oas2Response>;
|
|
28
|
+
};
|
|
29
|
+
parameters?: {
|
|
30
|
+
[name: string]: Record<string, Oas2Parameter>;
|
|
31
|
+
};
|
|
32
|
+
}
|
|
19
33
|
export interface Oas2Info {
|
|
20
34
|
title: string;
|
|
21
35
|
version: string;
|
package/lib/utils.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export declare type BundleOutputFormat = 'json' | 'yml' | 'yaml';
|
|
|
16
16
|
export declare function loadYaml(filename: string): Promise<unknown>;
|
|
17
17
|
export declare function notUndefined<T>(x: T | undefined): x is T;
|
|
18
18
|
export declare function isPlainObject(value: any): value is object;
|
|
19
|
+
export declare function isEmptyObject(value: any): value is object;
|
|
20
|
+
export declare function isEmptyArray(value: any): boolean;
|
|
19
21
|
export declare function readFileFromUrl(url: string, config: HttpResolveConfig): Promise<{
|
|
20
22
|
body: any;
|
|
21
23
|
mimeType: any;
|
package/lib/utils.js
CHANGED
|
@@ -9,7 +9,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.isNotEmptyObject = exports.slash = exports.isPathParameter = exports.readFileAsStringSync = exports.isSingular = exports.validateMimeTypeOAS3 = exports.validateMimeType = exports.splitCamelCaseIntoWords = exports.omitObjectProps = exports.pickObjectProps = exports.match = exports.readFileFromUrl = exports.isPlainObject = exports.notUndefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
|
|
12
|
+
exports.isNotEmptyObject = exports.slash = exports.isPathParameter = exports.readFileAsStringSync = exports.isSingular = exports.validateMimeTypeOAS3 = exports.validateMimeType = exports.splitCamelCaseIntoWords = exports.omitObjectProps = exports.pickObjectProps = exports.match = exports.readFileFromUrl = exports.isEmptyArray = exports.isEmptyObject = exports.isPlainObject = exports.notUndefined = exports.loadYaml = exports.popStack = exports.pushStack = exports.stringifyYaml = exports.parseYaml = void 0;
|
|
13
13
|
const fs = require("fs");
|
|
14
14
|
const minimatch = require("minimatch");
|
|
15
15
|
const node_fetch_1 = require("node-fetch");
|
|
@@ -42,6 +42,14 @@ function isPlainObject(value) {
|
|
|
42
42
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
43
43
|
}
|
|
44
44
|
exports.isPlainObject = isPlainObject;
|
|
45
|
+
function isEmptyObject(value) {
|
|
46
|
+
return isPlainObject(value) && Object.keys(value).length === 0;
|
|
47
|
+
}
|
|
48
|
+
exports.isEmptyObject = isEmptyObject;
|
|
49
|
+
function isEmptyArray(value) {
|
|
50
|
+
return Array.isArray(value) && value.length === 0;
|
|
51
|
+
}
|
|
52
|
+
exports.isEmptyArray = isEmptyArray;
|
|
45
53
|
function readFileFromUrl(url, config) {
|
|
46
54
|
return __awaiter(this, void 0, void 0, function* () {
|
|
47
55
|
const headers = {};
|
package/lib/walk.js
CHANGED
|
@@ -101,10 +101,9 @@ function walkDocument(opts) {
|
|
|
101
101
|
if (!activatedOn.skipped) {
|
|
102
102
|
visitedBySome = true;
|
|
103
103
|
enteredContexts.add(context);
|
|
104
|
-
const ignoreNextVisitorsOnNode = visitWithContext(visit, resolvedNode, context, ruleId, severity);
|
|
105
|
-
if (ignoreNextVisitorsOnNode)
|
|
104
|
+
const { ignoreNextVisitorsOnNode } = visitWithContext(visit, resolvedNode, context, ruleId, severity);
|
|
105
|
+
if (ignoreNextVisitorsOnNode)
|
|
106
106
|
break;
|
|
107
|
-
}
|
|
108
107
|
}
|
|
109
108
|
}
|
|
110
109
|
}
|
|
@@ -211,17 +210,15 @@ function walkDocument(opts) {
|
|
|
211
210
|
key,
|
|
212
211
|
parentLocations: collectParentsLocations(context),
|
|
213
212
|
oasVersion: ctx.oasVersion,
|
|
214
|
-
ignoreNextVisitorsOnNode: () => {
|
|
215
|
-
ignoreNextVisitorsOnNode = true;
|
|
216
|
-
},
|
|
213
|
+
ignoreNextVisitorsOnNode: () => { ignoreNextVisitorsOnNode = true; },
|
|
217
214
|
getVisitorData: getVisitorDataFn.bind(undefined, ruleId),
|
|
218
215
|
}, collectParents(context), context);
|
|
219
|
-
return ignoreNextVisitorsOnNode;
|
|
216
|
+
return { ignoreNextVisitorsOnNode };
|
|
220
217
|
}
|
|
221
218
|
function resolve(ref, from = currentLocation.source.absoluteRef) {
|
|
222
219
|
if (!ref_utils_1.isRef(ref))
|
|
223
220
|
return { location, node: ref };
|
|
224
|
-
const refId = from
|
|
221
|
+
const refId = resolve_1.makeRefId(from, ref.$ref);
|
|
225
222
|
const resolvedRef = resolvedRefMap.get(refId);
|
|
226
223
|
if (!resolvedRef) {
|
|
227
224
|
return {
|
package/package.json
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { outdent } from 'outdent';
|
|
1
2
|
import { parseYaml, stringifyYaml } from '../js-yaml';
|
|
2
3
|
|
|
3
4
|
const yaml = `
|
|
@@ -7,7 +8,8 @@ const yaml = `
|
|
|
7
8
|
number: 1000
|
|
8
9
|
decimal: 12.34
|
|
9
10
|
boolean: true
|
|
10
|
-
|
|
11
|
+
dateWithoutQuotes: 2020-01-01
|
|
12
|
+
dateWithQuotes: '2020-01-01'
|
|
11
13
|
array:
|
|
12
14
|
- 1
|
|
13
15
|
- 2
|
|
@@ -16,6 +18,16 @@ const yaml = `
|
|
|
16
18
|
key2: 2
|
|
17
19
|
`;
|
|
18
20
|
|
|
21
|
+
const yamlToDump = outdent`
|
|
22
|
+
date: '2022-01-21T11:29:56.694Z'
|
|
23
|
+
dateWithoutQuotes: 2020-01-01
|
|
24
|
+
dateWithQuotes: '2020-01-01'
|
|
25
|
+
dateImplicit: !!str 2020-01-01
|
|
26
|
+
string: test
|
|
27
|
+
stringWithQuotes: 'test'
|
|
28
|
+
stringWithDoubleQuotes: "test"
|
|
29
|
+
`;
|
|
30
|
+
|
|
19
31
|
const jsObject = {
|
|
20
32
|
emptyValue: null,
|
|
21
33
|
'spaces in keys': 'spaces in keys',
|
|
@@ -23,7 +35,8 @@ const jsObject = {
|
|
|
23
35
|
number: 1000,
|
|
24
36
|
decimal: 12.34,
|
|
25
37
|
boolean: true,
|
|
26
|
-
|
|
38
|
+
dateWithoutQuotes: '2020-01-01',
|
|
39
|
+
dateWithQuotes: '2020-01-01',
|
|
27
40
|
array: [1, 2],
|
|
28
41
|
object: { key1: 1, key2: 2 },
|
|
29
42
|
};
|
|
@@ -33,14 +46,25 @@ describe('js-yaml', () => {
|
|
|
33
46
|
expect(parseYaml(yaml)).toEqual(jsObject);
|
|
34
47
|
});
|
|
35
48
|
|
|
49
|
+
test('should correctly dump date and string', () => {
|
|
50
|
+
expect(stringifyYaml(parseYaml(yamlToDump))).toMatchInlineSnapshot(
|
|
51
|
+
`
|
|
52
|
+
"date: '2022-01-21T11:29:56.694Z'
|
|
53
|
+
dateWithoutQuotes: '2020-01-01'
|
|
54
|
+
dateWithQuotes: '2020-01-01'
|
|
55
|
+
dateImplicit: '2020-01-01'
|
|
56
|
+
string: test
|
|
57
|
+
stringWithQuotes: test
|
|
58
|
+
stringWithDoubleQuotes: test
|
|
59
|
+
"
|
|
60
|
+
`);
|
|
61
|
+
});
|
|
62
|
+
|
|
36
63
|
test('parse and stringify', () => {
|
|
37
64
|
expect(parseYaml(stringifyYaml(jsObject))).toEqual(jsObject);
|
|
38
65
|
});
|
|
39
66
|
|
|
40
67
|
test('should throw an error for unsupported types', () => {
|
|
41
|
-
expect(() => stringifyYaml({ date: new Date() }))
|
|
42
|
-
.toThrow('unacceptable kind of an object to dump [object Date]');
|
|
43
|
-
|
|
44
68
|
expect(() => stringifyYaml({ foo: () => {} }))
|
|
45
69
|
.toThrow('unacceptable kind of an object to dump [object Function]');
|
|
46
70
|
});
|
|
@@ -3,9 +3,7 @@ import { outdent } from 'outdent';
|
|
|
3
3
|
import { lintFromString, lintConfig, lintDocument } from '../lint';
|
|
4
4
|
import { BaseResolver } from '../resolve';
|
|
5
5
|
import { loadConfig } from '../config/load';
|
|
6
|
-
import { parseYamlToDocument, replaceSourceWithRef } from '../../__tests__/utils';
|
|
7
|
-
// todo create general utils for tests and move this config.
|
|
8
|
-
import { makeConfig } from '../rules/__tests__/config';
|
|
6
|
+
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../__tests__/utils';
|
|
9
7
|
|
|
10
8
|
describe('lint', () => {
|
|
11
9
|
it('lintFromString should work', async () => {
|
package/src/bundle.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import isEqual = require('lodash.isequal');
|
|
2
|
-
import { BaseResolver, resolveDocument, Document } from './resolve';
|
|
2
|
+
import { BaseResolver, resolveDocument, Document, ResolvedRefMap, makeRefId } from './resolve';
|
|
3
3
|
import { Oas3Rule, normalizeVisitors, Oas3Visitor, Oas2Visitor } from './visitors';
|
|
4
4
|
import { Oas3Types } from './types/oas3';
|
|
5
5
|
import { Oas2Types } from './types/oas2';
|
|
@@ -14,6 +14,8 @@ import { reportUnresolvedRef } from './rules/no-unresolved-refs';
|
|
|
14
14
|
import { isPlainObject } from './utils';
|
|
15
15
|
import { OasRef } from './typings/openapi';
|
|
16
16
|
import { isRedoclyRegistryURL } from './redocly';
|
|
17
|
+
import { RemoveUnusedComponents as RemoveUnusedComponentsOas2 } from './rules/oas2/remove-unused-components';
|
|
18
|
+
import { RemoveUnusedComponents as RemoveUnusedComponentsOas3 } from './rules/oas3/remove-unused-components';
|
|
17
19
|
|
|
18
20
|
export type Oas3RuleSet = Record<string, Oas3Rule>;
|
|
19
21
|
|
|
@@ -31,6 +33,7 @@ export async function bundle(opts: {
|
|
|
31
33
|
dereference?: boolean;
|
|
32
34
|
base?: string;
|
|
33
35
|
skipRedoclyRegistryRefs?: boolean;
|
|
36
|
+
removeUnusedComponents?: boolean;
|
|
34
37
|
}) {
|
|
35
38
|
const {
|
|
36
39
|
ref,
|
|
@@ -66,6 +69,7 @@ export async function bundleDocument(opts: {
|
|
|
66
69
|
externalRefResolver: BaseResolver;
|
|
67
70
|
dereference?: boolean;
|
|
68
71
|
skipRedoclyRegistryRefs?: boolean;
|
|
72
|
+
removeUnusedComponents?: boolean;
|
|
69
73
|
}) {
|
|
70
74
|
const {
|
|
71
75
|
document,
|
|
@@ -74,6 +78,7 @@ export async function bundleDocument(opts: {
|
|
|
74
78
|
externalRefResolver,
|
|
75
79
|
dereference = false,
|
|
76
80
|
skipRedoclyRegistryRefs = false,
|
|
81
|
+
removeUnusedComponents = false,
|
|
77
82
|
} = opts;
|
|
78
83
|
const oasVersion = detectOpenAPI(document.parsed);
|
|
79
84
|
const oasMajorVersion = openAPIMajor(oasVersion);
|
|
@@ -92,6 +97,7 @@ export async function bundleDocument(opts: {
|
|
|
92
97
|
|
|
93
98
|
const preprocessors = initRules(rules as any, config, 'preprocessors', oasVersion);
|
|
94
99
|
const decorators = initRules(rules as any, config, 'decorators', oasVersion);
|
|
100
|
+
|
|
95
101
|
const ctx: BundleContext = {
|
|
96
102
|
problems: [],
|
|
97
103
|
oasVersion: oasVersion,
|
|
@@ -99,25 +105,35 @@ export async function bundleDocument(opts: {
|
|
|
99
105
|
visitorsData: {},
|
|
100
106
|
};
|
|
101
107
|
|
|
108
|
+
if (removeUnusedComponents) {
|
|
109
|
+
decorators.push({
|
|
110
|
+
severity: 'error',
|
|
111
|
+
ruleId: 'remove-unused-components',
|
|
112
|
+
visitor: oasMajorVersion === OasMajorVersion.Version2
|
|
113
|
+
? RemoveUnusedComponentsOas2({})
|
|
114
|
+
: RemoveUnusedComponentsOas3({})
|
|
115
|
+
})
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const resolvedRefMap = await resolveDocument({
|
|
119
|
+
rootDocument: document,
|
|
120
|
+
rootType: types.DefinitionRoot,
|
|
121
|
+
externalRefResolver,
|
|
122
|
+
});
|
|
123
|
+
|
|
102
124
|
const bundleVisitor = normalizeVisitors(
|
|
103
125
|
[
|
|
104
126
|
...preprocessors,
|
|
105
127
|
{
|
|
106
128
|
severity: 'error',
|
|
107
129
|
ruleId: 'bundler',
|
|
108
|
-
visitor: makeBundleVisitor(oasMajorVersion, dereference, skipRedoclyRegistryRefs, document),
|
|
130
|
+
visitor: makeBundleVisitor(oasMajorVersion, dereference, skipRedoclyRegistryRefs, document, resolvedRefMap),
|
|
109
131
|
},
|
|
110
132
|
...decorators,
|
|
111
133
|
],
|
|
112
134
|
types,
|
|
113
135
|
);
|
|
114
136
|
|
|
115
|
-
const resolvedRefMap = await resolveDocument({
|
|
116
|
-
rootDocument: document,
|
|
117
|
-
rootType: types.DefinitionRoot,
|
|
118
|
-
externalRefResolver,
|
|
119
|
-
});
|
|
120
|
-
|
|
121
137
|
walkDocument({
|
|
122
138
|
document,
|
|
123
139
|
rootType: types.DefinitionRoot as NormalizedNodeType,
|
|
@@ -182,6 +198,7 @@ function makeBundleVisitor(
|
|
|
182
198
|
dereference: boolean,
|
|
183
199
|
skipRedoclyRegistryRefs: boolean,
|
|
184
200
|
rootDocument: Document,
|
|
201
|
+
resolvedRefMap: ResolvedRefMap
|
|
185
202
|
) {
|
|
186
203
|
let components: Record<string, Record<string, any>>;
|
|
187
204
|
|
|
@@ -214,6 +231,7 @@ function makeBundleVisitor(
|
|
|
214
231
|
replaceRef(node, resolved, ctx);
|
|
215
232
|
} else {
|
|
216
233
|
node.$ref = saveComponent(componentType, resolved, ctx);
|
|
234
|
+
resolveBundledComponent(node, resolved, ctx);
|
|
217
235
|
}
|
|
218
236
|
}
|
|
219
237
|
},
|
|
@@ -251,6 +269,17 @@ function makeBundleVisitor(
|
|
|
251
269
|
};
|
|
252
270
|
}
|
|
253
271
|
|
|
272
|
+
function resolveBundledComponent(node: OasRef, resolved: ResolveResult<any>, ctx: UserContext) {
|
|
273
|
+
const newRefId = makeRefId(ctx.location.source.absoluteRef, node.$ref)
|
|
274
|
+
resolvedRefMap.set(newRefId, {
|
|
275
|
+
document: rootDocument,
|
|
276
|
+
isRemote: false,
|
|
277
|
+
node: resolved.node,
|
|
278
|
+
nodePointer: node.$ref,
|
|
279
|
+
resolved: true,
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
|
|
254
283
|
function replaceRef(ref: OasRef, resolved: ResolveResult<any>, ctx: UserContext) {
|
|
255
284
|
if (!isPlainObject(resolved.node)) {
|
|
256
285
|
ctx.parent[ctx.key] = resolved.node;
|
package/src/config/builtIn.ts
CHANGED
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
import recommended from './recommended';
|
|
2
2
|
import all from './all';
|
|
3
3
|
import minimal from './minimal';
|
|
4
|
-
import { LintRawConfig, Plugin } from './config';
|
|
5
|
-
|
|
6
|
-
import
|
|
4
|
+
import { CustomRulesConfig, LintRawConfig, Plugin } from './config';
|
|
5
|
+
import { rules as oas3Rules } from '../rules/oas3';
|
|
6
|
+
import { rules as oas2Rules } from '../rules/oas2';
|
|
7
|
+
import { preprocessors as oas3Preprocessors } from '../rules/oas3';
|
|
8
|
+
import { preprocessors as oas2Preprocessors } from '../rules/oas2';
|
|
9
|
+
import { decorators as oas3Decorators } from '../decorators/oas3';
|
|
10
|
+
import { decorators as oas2Decorators } from '../decorators/oas2';
|
|
7
11
|
|
|
8
12
|
export const builtInConfigs: Record<string, LintRawConfig> = {
|
|
9
13
|
recommended,
|
|
@@ -16,8 +20,17 @@ export const builtInConfigs: Record<string, LintRawConfig> = {
|
|
|
16
20
|
|
|
17
21
|
export const defaultPlugin: Plugin = {
|
|
18
22
|
id: '', // default plugin doesn't have id
|
|
19
|
-
rules:
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
rules: {
|
|
24
|
+
oas3: oas3Rules,
|
|
25
|
+
oas2: oas2Rules,
|
|
26
|
+
} as CustomRulesConfig,
|
|
27
|
+
preprocessors: {
|
|
28
|
+
oas3: oas3Preprocessors,
|
|
29
|
+
oas2: oas2Preprocessors,
|
|
30
|
+
},
|
|
31
|
+
decorators: {
|
|
32
|
+
oas3: oas3Decorators,
|
|
33
|
+
oas2: oas2Decorators,
|
|
34
|
+
},
|
|
22
35
|
configs: builtInConfigs,
|
|
23
|
-
}
|
|
36
|
+
}
|
package/src/config/config.ts
CHANGED