@redocly/openapi-core 1.16.0 → 1.17.0
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/CHANGELOG.md +10 -0
- package/lib/bundle.d.ts +1 -1
- package/lib/config/load.d.ts +12 -3
- package/lib/config/load.js +32 -12
- package/lib/config/utils.d.ts +1 -0
- package/lib/config/utils.js +5 -1
- package/lib/lint.d.ts +1 -0
- package/lib/lint.js +3 -7
- package/lib/oas-types.d.ts +1 -1
- package/lib/types/oas3_1.js +1 -0
- package/lib/types/redocly-yaml.d.ts +3 -1
- package/lib/types/redocly-yaml.js +34 -36
- package/package.json +1 -1
- package/src/__tests__/lint.test.ts +22 -12
- package/src/config/__tests__/load.test.ts +86 -61
- package/src/config/load.ts +49 -23
- package/src/config/utils.ts +4 -0
- package/src/lint.ts +10 -9
- package/src/types/oas3_1.ts +1 -0
- package/src/types/redocly-yaml.ts +32 -33
- package/tsconfig.tsbuildinfo +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# @redocly/openapi-core
|
|
2
2
|
|
|
3
|
+
## 1.17.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Changed resolution process to include extendedTypes and plugins before linting.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Added support for the `contentSchema` keyword to parse as a schema instance.
|
|
12
|
+
|
|
3
13
|
## 1.16.0
|
|
4
14
|
|
|
5
15
|
### Minor Changes
|
package/lib/bundle.d.ts
CHANGED
|
@@ -47,4 +47,4 @@ export declare function bundleDocument(opts: {
|
|
|
47
47
|
removeUnusedComponents?: boolean;
|
|
48
48
|
keepUrlRefs?: boolean;
|
|
49
49
|
}): Promise<BundleResult>;
|
|
50
|
-
export declare function mapTypeToComponent(typeName: string, version: SpecMajorVersion): "definitions" | "examples" | "
|
|
50
|
+
export declare function mapTypeToComponent(typeName: string, version: SpecMajorVersion): "definitions" | "examples" | "parameters" | "headers" | "schemas" | "responses" | "requestBodies" | "securitySchemes" | "links" | "callbacks" | null;
|
package/lib/config/load.d.ts
CHANGED
|
@@ -4,7 +4,12 @@ import type { Document } from '../resolve';
|
|
|
4
4
|
import type { RegionalTokenWithValidity } from '../redocly/redocly-client-types';
|
|
5
5
|
import type { RawConfig, RawUniversalConfig, Region } from './types';
|
|
6
6
|
import type { ResolvedRefMap } from '../resolve';
|
|
7
|
-
export type RawConfigProcessor = (
|
|
7
|
+
export type RawConfigProcessor = (params: {
|
|
8
|
+
document: Document;
|
|
9
|
+
resolvedRefMap: ResolvedRefMap;
|
|
10
|
+
config: Config;
|
|
11
|
+
parsed: Document['parsed'];
|
|
12
|
+
}) => void | Promise<void>;
|
|
8
13
|
export declare function loadConfig(options?: {
|
|
9
14
|
configPath?: string;
|
|
10
15
|
customExtends?: string[];
|
|
@@ -17,9 +22,13 @@ export declare const CONFIG_FILE_NAMES: string[];
|
|
|
17
22
|
export declare function findConfig(dir?: string): string | undefined;
|
|
18
23
|
export declare function getConfig(options?: {
|
|
19
24
|
configPath?: string;
|
|
20
|
-
processRawConfig?: RawConfigProcessor;
|
|
21
25
|
externalRefResolver?: BaseResolver;
|
|
22
|
-
}): Promise<
|
|
26
|
+
}): Promise<{
|
|
27
|
+
rawConfig: RawConfig;
|
|
28
|
+
document?: Document;
|
|
29
|
+
parsed?: Document['parsed'];
|
|
30
|
+
resolvedRefMap?: ResolvedRefMap;
|
|
31
|
+
}>;
|
|
23
32
|
type CreateConfigOptions = {
|
|
24
33
|
extends?: string[];
|
|
25
34
|
tokens?: RegionalTokenWithValidity[];
|
package/lib/config/load.js
CHANGED
|
@@ -68,10 +68,13 @@ function addConfigMetadata({ rawConfig, customExtends, configPath, tokens, files
|
|
|
68
68
|
function loadConfig(options = {}) {
|
|
69
69
|
return __awaiter(this, void 0, void 0, function* () {
|
|
70
70
|
const { configPath = findConfig(), customExtends, processRawConfig, files, region, externalRefResolver, } = options;
|
|
71
|
-
const rawConfig = yield getConfig({
|
|
71
|
+
const { rawConfig, document, parsed, resolvedRefMap } = yield getConfig({
|
|
72
|
+
configPath,
|
|
73
|
+
externalRefResolver,
|
|
74
|
+
});
|
|
72
75
|
const redoclyClient = env_1.isBrowser ? undefined : new redocly_1.RedoclyClient();
|
|
73
76
|
const tokens = redoclyClient && redoclyClient.hasTokens() ? redoclyClient.getAllTokens() : [];
|
|
74
|
-
|
|
77
|
+
const config = yield addConfigMetadata({
|
|
75
78
|
rawConfig,
|
|
76
79
|
customExtends,
|
|
77
80
|
configPath,
|
|
@@ -80,6 +83,23 @@ function loadConfig(options = {}) {
|
|
|
80
83
|
region,
|
|
81
84
|
externalRefResolver,
|
|
82
85
|
});
|
|
86
|
+
if (document && parsed && resolvedRefMap && typeof processRawConfig === 'function') {
|
|
87
|
+
try {
|
|
88
|
+
yield processRawConfig({
|
|
89
|
+
document,
|
|
90
|
+
resolvedRefMap,
|
|
91
|
+
config,
|
|
92
|
+
parsed,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
if (e instanceof utils_2.ConfigValidationError) {
|
|
97
|
+
throw e;
|
|
98
|
+
}
|
|
99
|
+
throw new Error(`Error parsing config file at '${configPath}': ${e.message}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return config;
|
|
83
103
|
});
|
|
84
104
|
}
|
|
85
105
|
exports.loadConfig = loadConfig;
|
|
@@ -101,24 +121,24 @@ function findConfig(dir) {
|
|
|
101
121
|
exports.findConfig = findConfig;
|
|
102
122
|
function getConfig(options = {}) {
|
|
103
123
|
return __awaiter(this, void 0, void 0, function* () {
|
|
104
|
-
const { configPath = findConfig(),
|
|
124
|
+
const { configPath = findConfig(), externalRefResolver = new resolve_1.BaseResolver() } = options;
|
|
105
125
|
if (!configPath)
|
|
106
|
-
return {};
|
|
126
|
+
return { rawConfig: {} };
|
|
107
127
|
try {
|
|
108
128
|
const { document, resolvedRefMap } = yield (0, config_resolvers_1.resolveConfigFileAndRefs)({
|
|
109
129
|
configPath,
|
|
110
130
|
externalRefResolver,
|
|
111
131
|
});
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
132
|
+
const bundledRefMap = (0, utils_2.deepCloneMapWithJSON)(resolvedRefMap);
|
|
133
|
+
const parsed = yield (0, bundle_1.bundleConfig)(JSON.parse(JSON.stringify(document)), bundledRefMap);
|
|
134
|
+
return {
|
|
135
|
+
rawConfig: (0, utils_2.transformConfig)(parsed),
|
|
136
|
+
document,
|
|
137
|
+
parsed,
|
|
138
|
+
resolvedRefMap,
|
|
139
|
+
};
|
|
117
140
|
}
|
|
118
141
|
catch (e) {
|
|
119
|
-
if (e instanceof utils_2.ConfigValidationError) {
|
|
120
|
-
throw e;
|
|
121
|
-
}
|
|
122
142
|
throw new Error(`Error parsing config file at '${configPath}': ${e.message}`);
|
|
123
143
|
}
|
|
124
144
|
});
|
package/lib/config/utils.d.ts
CHANGED
|
@@ -14,3 +14,4 @@ export declare function getResolveConfig(resolve?: RawResolveConfig): ResolveCon
|
|
|
14
14
|
export declare function getUniquePlugins(plugins: Plugin[]): Plugin[];
|
|
15
15
|
export declare class ConfigValidationError extends Error {
|
|
16
16
|
}
|
|
17
|
+
export declare function deepCloneMapWithJSON<K, V>(originalMap: Map<K, V>): Map<K, V>;
|
package/lib/config/utils.js
CHANGED
|
@@ -11,7 +11,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
11
11
|
return t;
|
|
12
12
|
};
|
|
13
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.ConfigValidationError = exports.getUniquePlugins = exports.getResolveConfig = exports.transformConfig = exports.checkForDeprecatedFields = exports.getMergedConfig = exports.mergeExtends = exports.prefixRules = exports.transformApiDefinitionsToApis = exports.parsePresetName = void 0;
|
|
14
|
+
exports.deepCloneMapWithJSON = exports.ConfigValidationError = exports.getUniquePlugins = exports.getResolveConfig = exports.transformConfig = exports.checkForDeprecatedFields = exports.getMergedConfig = exports.mergeExtends = exports.prefixRules = exports.transformApiDefinitionsToApis = exports.parsePresetName = void 0;
|
|
15
15
|
const utils_1 = require("../utils");
|
|
16
16
|
const config_1 = require("./config");
|
|
17
17
|
const logger_1 = require("../logger");
|
|
@@ -251,3 +251,7 @@ exports.getUniquePlugins = getUniquePlugins;
|
|
|
251
251
|
class ConfigValidationError extends Error {
|
|
252
252
|
}
|
|
253
253
|
exports.ConfigValidationError = ConfigValidationError;
|
|
254
|
+
function deepCloneMapWithJSON(originalMap) {
|
|
255
|
+
return new Map(JSON.parse(JSON.stringify([...originalMap])));
|
|
256
|
+
}
|
|
257
|
+
exports.deepCloneMapWithJSON = deepCloneMapWithJSON;
|
package/lib/lint.d.ts
CHANGED
|
@@ -22,6 +22,7 @@ export declare function lintDocument(opts: {
|
|
|
22
22
|
}): Promise<import("./walk").NormalizedProblem[]>;
|
|
23
23
|
export declare function lintConfig(opts: {
|
|
24
24
|
document: Document;
|
|
25
|
+
config: Config;
|
|
25
26
|
resolvedRefMap?: ResolvedRefMap;
|
|
26
27
|
severity?: ProblemSeverity;
|
|
27
28
|
externalRefResolver?: BaseResolver;
|
package/lib/lint.js
CHANGED
|
@@ -20,6 +20,7 @@ const oas_types_1 = require("./oas-types");
|
|
|
20
20
|
const redocly_yaml_1 = require("./types/redocly-yaml");
|
|
21
21
|
const spec_1 = require("./rules/common/spec");
|
|
22
22
|
const no_unresolved_refs_1 = require("./rules/no-unresolved-refs");
|
|
23
|
+
const config_2 = require("@redocly/config");
|
|
23
24
|
function lint(opts) {
|
|
24
25
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
26
|
const { ref, externalRefResolver = new resolve_1.BaseResolver(opts.config.resolve) } = opts;
|
|
@@ -85,18 +86,13 @@ function lintDocument(opts) {
|
|
|
85
86
|
exports.lintDocument = lintDocument;
|
|
86
87
|
function lintConfig(opts) {
|
|
87
88
|
return __awaiter(this, void 0, void 0, function* () {
|
|
88
|
-
const { document, severity, externalRefResolver = new resolve_1.BaseResolver() } = opts;
|
|
89
|
+
const { document, severity, externalRefResolver = new resolve_1.BaseResolver(), config } = opts;
|
|
89
90
|
const ctx = {
|
|
90
91
|
problems: [],
|
|
91
92
|
oasVersion: oas_types_1.SpecVersion.OAS3_0,
|
|
92
93
|
visitorsData: {},
|
|
93
94
|
};
|
|
94
|
-
const
|
|
95
|
-
const config = new config_1.StyleguideConfig({
|
|
96
|
-
plugins,
|
|
97
|
-
rules: { spec: 'error' },
|
|
98
|
-
});
|
|
99
|
-
const types = (0, types_1.normalizeTypes)(opts.externalConfigTypes || redocly_yaml_1.ConfigTypes, config);
|
|
95
|
+
const types = (0, types_1.normalizeTypes)(opts.externalConfigTypes || (0, redocly_yaml_1.createConfigTypes)(config_2.rootRedoclyConfigSchema, config), { doNotResolveExamples: config.styleguide.doNotResolveExamples });
|
|
100
96
|
const rules = [
|
|
101
97
|
{
|
|
102
98
|
severity: severity || 'error',
|
package/lib/oas-types.d.ts
CHANGED
|
@@ -24,4 +24,4 @@ export type Oas2DecoratorsSet = Record<string, Oas2Preprocessor>;
|
|
|
24
24
|
export type Async2DecoratorsSet = Record<string, Async2Preprocessor>;
|
|
25
25
|
export declare function detectSpec(root: any): SpecVersion;
|
|
26
26
|
export declare function getMajorSpecVersion(version: SpecVersion): SpecMajorVersion;
|
|
27
|
-
export declare function getTypes(spec: SpecVersion): Record<string, import("./types").NodeType> | Record<"Root" | "Tag" | "ExternalDocs" | "SecurityRequirement" | "Info" | "Contact" | "License" | "Paths" | "PathItem" | "Parameter" | "Operation" | "Example" | "Header" | "Responses" | "Response" | "Schema" | "Xml" | "SchemaProperties" | "NamedSchemas" | "NamedResponses" | "NamedParameters" | "NamedSecuritySchemes" | "SecurityScheme" | "Examples" | "ExamplesMap" | "TagList" | "SecurityRequirementList" | "ParameterList" | "ParameterItems" | "TagGroup" | "TagGroups" | "EnumDescriptions" | "Logo" | "XCodeSample" | "XCodeSampleList" | "XServer" | "XServerList", import("./types").NodeType> | Record<"Root" | "Tag" | "ExternalDocs" | "Server" | "ServerVariable" | "SecurityRequirement" | "Info" | "Contact" | "License" | "Paths" | "PathItem" | "Callback" | "CallbacksMap" | "Parameter" | "Operation" | "RequestBody" | "MediaTypesMap" | "MediaType" | "Example" | "Encoding" | "Header" | "Responses" | "Response" | "Link" | "Schema" | "Xml" | "SchemaProperties" | "DiscriminatorMapping" | "Discriminator" | "Components" | "NamedSchemas" | "NamedResponses" | "NamedParameters" | "NamedExamples" | "NamedRequestBodies" | "NamedHeaders" | "NamedSecuritySchemes" | "NamedLinks" | "NamedCallbacks" | "ImplicitFlow" | "PasswordFlow" | "ClientCredentials" | "AuthorizationCode" | "OAuth2Flows" | "SecurityScheme" | "ServerVariablesMap" | "ExamplesMap" | "EncodingMap" | "HeadersMap" | "LinksMap" | "TagList" | "SecurityRequirementList" | "ParameterList" | "TagGroup" | "TagGroups" | "EnumDescriptions" | "Logo" | "XCodeSample" | "XCodeSampleList" | "ServerList" | "XUsePkce"
|
|
27
|
+
export declare function getTypes(spec: SpecVersion): Record<string, import("./types").NodeType> | Record<"Root" | "Tag" | "ExternalDocs" | "SecurityRequirement" | "Info" | "Contact" | "License" | "Paths" | "PathItem" | "Parameter" | "Operation" | "Example" | "Header" | "Responses" | "Response" | "Schema" | "Xml" | "SchemaProperties" | "NamedSchemas" | "NamedResponses" | "NamedParameters" | "NamedSecuritySchemes" | "SecurityScheme" | "Examples" | "ExamplesMap" | "TagList" | "SecurityRequirementList" | "ParameterList" | "ParameterItems" | "TagGroup" | "TagGroups" | "EnumDescriptions" | "Logo" | "XCodeSample" | "XCodeSampleList" | "XServer" | "XServerList", import("./types").NodeType> | Record<"Root" | "Tag" | "ExternalDocs" | "Server" | "ServerVariable" | "SecurityRequirement" | "Info" | "Contact" | "License" | "Paths" | "PathItem" | "Callback" | "CallbacksMap" | "Parameter" | "Operation" | "RequestBody" | "MediaTypesMap" | "MediaType" | "Example" | "Encoding" | "Header" | "Responses" | "Response" | "Link" | "Schema" | "Xml" | "SchemaProperties" | "DiscriminatorMapping" | "Discriminator" | "Components" | "NamedSchemas" | "NamedResponses" | "NamedParameters" | "NamedExamples" | "NamedRequestBodies" | "NamedHeaders" | "NamedSecuritySchemes" | "NamedLinks" | "NamedCallbacks" | "ImplicitFlow" | "PasswordFlow" | "ClientCredentials" | "AuthorizationCode" | "OAuth2Flows" | "SecurityScheme" | "ServerVariablesMap" | "ExamplesMap" | "EncodingMap" | "HeadersMap" | "LinksMap" | "WebhooksMap" | "TagList" | "SecurityRequirementList" | "ParameterList" | "TagGroup" | "TagGroups" | "EnumDescriptions" | "Logo" | "XCodeSample" | "XCodeSampleList" | "ServerList" | "XUsePkce", import("./types").NodeType> | Record<"Root" | "Info" | "License" | "Operation" | "Schema" | "SchemaProperties" | "Components" | "SecurityScheme" | "NamedPathItems", import("./types").NodeType>;
|
package/lib/types/oas3_1.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { NodeType } from '.';
|
|
2
2
|
import type { JSONSchema } from 'json-schema-to-ts';
|
|
3
|
+
import { Config } from '../config';
|
|
3
4
|
declare const builtInCommonRules: readonly ["spec", "info-contact", "operation-operationId", "tag-description", "tags-alphabetical"];
|
|
4
5
|
export type BuiltInCommonRuleId = typeof builtInCommonRules[number];
|
|
5
6
|
declare const builtInCommonOASRules: readonly ["info-license-url", "info-license", "no-ambiguous-paths", "no-enum-type-mismatch", "no-http-verbs-in-paths", "no-identical-paths", "no-invalid-parameter-examples", "no-invalid-schema-examples", "no-path-trailing-slash", "operation-2xx-response", "operation-4xx-response", "operation-description", "operation-operationId-unique", "operation-operationId-url-safe", "operation-parameters-unique", "operation-singular-tag", "operation-summary", "operation-tag-defined", "parameter-description", "path-declaration-must-exist", "path-excludes-patterns", "path-http-verbs-order", "path-not-include-query", "path-params-defined", "path-parameters-defined", "path-segment-plural", "paths-kebab-case", "required-string-property-missing-min-length", "response-contains-header", "scalar-property-missing-example", "security-defined", "spec-strict-refs", "no-unresolved-refs", "no-required-schema-properties-undefined"];
|
|
@@ -16,9 +17,10 @@ declare const oas3NodeTypesList: readonly ["Root", "Tag", "TagList", "ExternalDo
|
|
|
16
17
|
export type Oas3NodeType = typeof oas3NodeTypesList[number];
|
|
17
18
|
declare const oas3_1NodeTypesList: readonly ["Root", "Schema", "SchemaProperties", "Info", "License", "Components", "NamedPathItems", "SecurityScheme", "Operation"];
|
|
18
19
|
export type Oas3_1NodeType = typeof oas3_1NodeTypesList[number];
|
|
19
|
-
export declare
|
|
20
|
+
export declare function createConfigTypes(extraSchemas: JSONSchema, config?: Config): {
|
|
20
21
|
ConfigRoot: NodeType;
|
|
21
22
|
ConfigApisProperties: NodeType;
|
|
23
|
+
AssertionDefinitionSubject: NodeType;
|
|
22
24
|
};
|
|
23
25
|
export declare const ConfigTypes: Record<string, NodeType>;
|
|
24
26
|
export {};
|
|
@@ -5,6 +5,7 @@ const config_1 = require("@redocly/config");
|
|
|
5
5
|
const _1 = require(".");
|
|
6
6
|
const utils_1 = require("../utils");
|
|
7
7
|
const json_schema_adapter_1 = require("./json-schema-adapter");
|
|
8
|
+
const oas_types_1 = require("../oas-types");
|
|
8
9
|
const builtInCommonRules = [
|
|
9
10
|
'spec',
|
|
10
11
|
'info-contact',
|
|
@@ -194,7 +195,6 @@ const oas3_1NodeTypesList = [
|
|
|
194
195
|
'SecurityScheme',
|
|
195
196
|
'Operation',
|
|
196
197
|
];
|
|
197
|
-
const asyncNodeTypesList = ['Message'];
|
|
198
198
|
const ConfigStyleguide = {
|
|
199
199
|
properties: {
|
|
200
200
|
extends: {
|
|
@@ -296,37 +296,30 @@ const Schema = {
|
|
|
296
296
|
properties: {},
|
|
297
297
|
additionalProperties: {},
|
|
298
298
|
};
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
...new Set([
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
}
|
|
320
|
-
else {
|
|
321
|
-
return { type: 'string' };
|
|
322
|
-
}
|
|
299
|
+
function createAssertionDefinitionSubject(nodeNames) {
|
|
300
|
+
return {
|
|
301
|
+
properties: {
|
|
302
|
+
type: {
|
|
303
|
+
enum: [...new Set(['any', ...nodeNames, 'SpecExtension'])],
|
|
304
|
+
},
|
|
305
|
+
property: (value) => {
|
|
306
|
+
if (Array.isArray(value)) {
|
|
307
|
+
return { type: 'array', items: { type: 'string' } };
|
|
308
|
+
}
|
|
309
|
+
else if (value === null) {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
return { type: 'string' };
|
|
314
|
+
}
|
|
315
|
+
},
|
|
316
|
+
filterInParentKeys: { type: 'array', items: { type: 'string' } },
|
|
317
|
+
filterOutParentKeys: { type: 'array', items: { type: 'string' } },
|
|
318
|
+
matchParentKeys: { type: 'string' },
|
|
323
319
|
},
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
},
|
|
328
|
-
required: ['type'],
|
|
329
|
-
};
|
|
320
|
+
required: ['type'],
|
|
321
|
+
};
|
|
322
|
+
}
|
|
330
323
|
const AssertionDefinitionAssertions = {
|
|
331
324
|
properties: {
|
|
332
325
|
enum: { type: 'array', items: { type: 'string' } },
|
|
@@ -897,11 +890,17 @@ const ConfigMockServer = {
|
|
|
897
890
|
errorIfForcedExampleNotFound: { type: 'boolean' },
|
|
898
891
|
},
|
|
899
892
|
};
|
|
900
|
-
|
|
893
|
+
function createConfigTypes(extraSchemas, config) {
|
|
894
|
+
const nodeNames = Object.values(oas_types_1.SpecVersion).flatMap((version) => {
|
|
895
|
+
const types = (config === null || config === void 0 ? void 0 : config.styleguide)
|
|
896
|
+
? config.styleguide.extendTypes((0, oas_types_1.getTypes)(version), version)
|
|
897
|
+
: (0, oas_types_1.getTypes)(version);
|
|
898
|
+
return Object.keys(types);
|
|
899
|
+
});
|
|
901
900
|
// Create types based on external schemas
|
|
902
901
|
const nodeTypes = (0, json_schema_adapter_1.getNodeTypesFromJSONSchema)('rootRedoclyConfigSchema', extraSchemas);
|
|
903
|
-
return Object.assign(Object.assign(Object.assign({}, CoreConfigTypes), { ConfigRoot: createConfigRoot(nodeTypes), ConfigApisProperties: createConfigApisProperties(nodeTypes) }), nodeTypes);
|
|
904
|
-
}
|
|
902
|
+
return Object.assign(Object.assign(Object.assign({}, CoreConfigTypes), { ConfigRoot: createConfigRoot(nodeTypes), ConfigApisProperties: createConfigApisProperties(nodeTypes), AssertionDefinitionSubject: createAssertionDefinitionSubject(nodeNames) }), nodeTypes);
|
|
903
|
+
}
|
|
905
904
|
exports.createConfigTypes = createConfigTypes;
|
|
906
905
|
const CoreConfigTypes = {
|
|
907
906
|
Assert,
|
|
@@ -964,6 +963,5 @@ const CoreConfigTypes = {
|
|
|
964
963
|
Heading,
|
|
965
964
|
Typography,
|
|
966
965
|
AssertionDefinitionAssertions,
|
|
967
|
-
AssertionDefinitionSubject,
|
|
968
966
|
};
|
|
969
|
-
exports.ConfigTypes =
|
|
967
|
+
exports.ConfigTypes = createConfigTypes(config_1.rootRedoclyConfigSchema);
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@ import { outdent } from 'outdent';
|
|
|
3
3
|
|
|
4
4
|
import { lintFromString, lintConfig, lintDocument, lint } from '../lint';
|
|
5
5
|
import { BaseResolver } from '../resolve';
|
|
6
|
-
import { loadConfig } from '../config/load';
|
|
6
|
+
import { createConfig, loadConfig } from '../config/load';
|
|
7
7
|
import { parseYamlToDocument, replaceSourceWithRef, makeConfig } from '../../__tests__/utils';
|
|
8
8
|
import { detectSpec } from '../oas-types';
|
|
9
9
|
import { rootRedoclyConfigSchema } from '@redocly/config';
|
|
@@ -293,7 +293,7 @@ describe('lint', () => {
|
|
|
293
293
|
- url: http://redocly-example.com
|
|
294
294
|
paths: {}
|
|
295
295
|
`,
|
|
296
|
-
config: await loadConfig(),
|
|
296
|
+
config: await loadConfig({ configPath: path.join(__dirname, 'fixtures/redocly.yaml') }),
|
|
297
297
|
});
|
|
298
298
|
|
|
299
299
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
@@ -374,7 +374,8 @@ describe('lint', () => {
|
|
|
374
374
|
`,
|
|
375
375
|
''
|
|
376
376
|
);
|
|
377
|
-
const
|
|
377
|
+
const config = await createConfig({});
|
|
378
|
+
const results = await lintConfig({ document, config });
|
|
378
379
|
|
|
379
380
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
380
381
|
[
|
|
@@ -435,7 +436,8 @@ describe('lint', () => {
|
|
|
435
436
|
`,
|
|
436
437
|
''
|
|
437
438
|
);
|
|
438
|
-
const
|
|
439
|
+
const config = await createConfig({});
|
|
440
|
+
const results = await lintConfig({ document, config });
|
|
439
441
|
|
|
440
442
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
441
443
|
[
|
|
@@ -475,7 +477,8 @@ describe('lint', () => {
|
|
|
475
477
|
`,
|
|
476
478
|
''
|
|
477
479
|
);
|
|
478
|
-
const
|
|
480
|
+
const config = await createConfig({});
|
|
481
|
+
const results = await lintConfig({ document, config });
|
|
479
482
|
|
|
480
483
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
481
484
|
[
|
|
@@ -510,7 +513,8 @@ describe('lint', () => {
|
|
|
510
513
|
`,
|
|
511
514
|
''
|
|
512
515
|
);
|
|
513
|
-
const
|
|
516
|
+
const config = await createConfig({});
|
|
517
|
+
const results = await lintConfig({ document, config });
|
|
514
518
|
|
|
515
519
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
516
520
|
[
|
|
@@ -534,7 +538,8 @@ describe('lint', () => {
|
|
|
534
538
|
|
|
535
539
|
it('lintConfig should detect wrong fields in the default configuration after merging with the portal config schema', async () => {
|
|
536
540
|
const document = testPortalConfig;
|
|
537
|
-
const
|
|
541
|
+
const config = await createConfig({});
|
|
542
|
+
const results = await lintConfig({ document, config });
|
|
538
543
|
|
|
539
544
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
540
545
|
[
|
|
@@ -1165,13 +1170,18 @@ describe('lint', () => {
|
|
|
1165
1170
|
|
|
1166
1171
|
it('lintConfig should alternate its behavior when supplied externalConfigTypes', async () => {
|
|
1167
1172
|
const document = testPortalConfig;
|
|
1173
|
+
const config = await createConfig({});
|
|
1168
1174
|
const results = await lintConfig({
|
|
1169
1175
|
document,
|
|
1170
|
-
externalConfigTypes: createConfigTypes(
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1176
|
+
externalConfigTypes: createConfigTypes(
|
|
1177
|
+
{
|
|
1178
|
+
type: 'object',
|
|
1179
|
+
properties: { theme: rootRedoclyConfigSchema.properties.theme },
|
|
1180
|
+
additionalProperties: false,
|
|
1181
|
+
},
|
|
1182
|
+
config
|
|
1183
|
+
),
|
|
1184
|
+
config,
|
|
1175
1185
|
});
|
|
1176
1186
|
|
|
1177
1187
|
expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`
|
|
@@ -58,6 +58,88 @@ describe('loadConfig', () => {
|
|
|
58
58
|
expect(mockFn).toHaveBeenCalled();
|
|
59
59
|
});
|
|
60
60
|
|
|
61
|
+
it('should resolve config and call processRawConfig', async () => {
|
|
62
|
+
let problems: NormalizedProblem[];
|
|
63
|
+
let doc: any;
|
|
64
|
+
|
|
65
|
+
await loadConfig({
|
|
66
|
+
configPath: path.join(__dirname, './fixtures/resolve-refs-in-config/config-with-refs.yaml'),
|
|
67
|
+
processRawConfig: async ({ document, parsed, resolvedRefMap, config }) => {
|
|
68
|
+
doc = parsed;
|
|
69
|
+
problems = await lintConfig({
|
|
70
|
+
document,
|
|
71
|
+
severity: 'warn',
|
|
72
|
+
resolvedRefMap,
|
|
73
|
+
config,
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(replaceSourceWithRef(problems!, __dirname)).toMatchInlineSnapshot(`
|
|
79
|
+
[
|
|
80
|
+
{
|
|
81
|
+
"from": {
|
|
82
|
+
"pointer": "#/seo",
|
|
83
|
+
"source": "fixtures/resolve-refs-in-config/config-with-refs.yaml",
|
|
84
|
+
},
|
|
85
|
+
"location": [
|
|
86
|
+
{
|
|
87
|
+
"pointer": "#/title",
|
|
88
|
+
"reportOnKey": false,
|
|
89
|
+
"source": "fixtures/resolve-refs-in-config/seo.yaml",
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
"message": "Expected type \`string\` but got \`integer\`.",
|
|
93
|
+
"ruleId": "configuration spec",
|
|
94
|
+
"severity": "warn",
|
|
95
|
+
"suggest": [],
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"from": {
|
|
99
|
+
"pointer": "#/rules",
|
|
100
|
+
"source": "fixtures/resolve-refs-in-config/config-with-refs.yaml",
|
|
101
|
+
},
|
|
102
|
+
"location": [
|
|
103
|
+
{
|
|
104
|
+
"pointer": "#/non-existing-rule",
|
|
105
|
+
"reportOnKey": true,
|
|
106
|
+
"source": "fixtures/resolve-refs-in-config/rules.yaml",
|
|
107
|
+
},
|
|
108
|
+
],
|
|
109
|
+
"message": "Property \`non-existing-rule\` is not expected here.",
|
|
110
|
+
"ruleId": "configuration spec",
|
|
111
|
+
"severity": "warn",
|
|
112
|
+
"suggest": [],
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"location": [
|
|
116
|
+
{
|
|
117
|
+
"pointer": "#/theme",
|
|
118
|
+
"reportOnKey": false,
|
|
119
|
+
"source": "fixtures/resolve-refs-in-config/config-with-refs.yaml",
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
"message": "Can't resolve $ref: ENOENT: no such file or directory 'fixtures/resolve-refs-in-config/wrong-ref.yaml'",
|
|
123
|
+
"ruleId": "configuration no-unresolved-refs",
|
|
124
|
+
"severity": "warn",
|
|
125
|
+
"suggest": [],
|
|
126
|
+
},
|
|
127
|
+
]
|
|
128
|
+
`);
|
|
129
|
+
expect(doc).toMatchInlineSnapshot(`
|
|
130
|
+
{
|
|
131
|
+
"rules": {
|
|
132
|
+
"info-license": "error",
|
|
133
|
+
"non-existing-rule": "warn",
|
|
134
|
+
},
|
|
135
|
+
"seo": {
|
|
136
|
+
"title": 1,
|
|
137
|
+
},
|
|
138
|
+
"theme": undefined,
|
|
139
|
+
}
|
|
140
|
+
`);
|
|
141
|
+
});
|
|
142
|
+
|
|
61
143
|
it('should call externalRefResolver if such passed', async () => {
|
|
62
144
|
const externalRefResolver = new BaseResolver();
|
|
63
145
|
const resolverSpy = jest.spyOn(externalRefResolver, 'resolveDocument');
|
|
@@ -104,22 +186,16 @@ describe('findConfig', () => {
|
|
|
104
186
|
describe('getConfig', () => {
|
|
105
187
|
jest.spyOn(fs, 'hasOwnProperty').mockImplementation(() => false);
|
|
106
188
|
it('should return empty object if there is no configPath and config file is not found', () => {
|
|
107
|
-
expect(getConfig()).toEqual(Promise.resolve({}));
|
|
189
|
+
expect(getConfig()).toEqual(Promise.resolve({ rawConfig: {} }));
|
|
108
190
|
});
|
|
109
191
|
|
|
110
192
|
it('should resolve refs in config', async () => {
|
|
111
193
|
let problems: NormalizedProblem[];
|
|
112
|
-
|
|
194
|
+
|
|
195
|
+
const { rawConfig } = await getConfig({
|
|
113
196
|
configPath: path.join(__dirname, './fixtures/resolve-refs-in-config/config-with-refs.yaml'),
|
|
114
|
-
processRawConfig: async (config, resolvedRefMap) => {
|
|
115
|
-
problems = await lintConfig({
|
|
116
|
-
document: config,
|
|
117
|
-
severity: 'warn',
|
|
118
|
-
resolvedRefMap,
|
|
119
|
-
});
|
|
120
|
-
},
|
|
121
197
|
});
|
|
122
|
-
expect(
|
|
198
|
+
expect(rawConfig).toEqual({
|
|
123
199
|
seo: {
|
|
124
200
|
title: 1,
|
|
125
201
|
},
|
|
@@ -130,57 +206,6 @@ describe('getConfig', () => {
|
|
|
130
206
|
},
|
|
131
207
|
},
|
|
132
208
|
});
|
|
133
|
-
expect(replaceSourceWithRef(problems!, __dirname)).toMatchInlineSnapshot(`
|
|
134
|
-
[
|
|
135
|
-
{
|
|
136
|
-
"from": {
|
|
137
|
-
"pointer": "#/seo",
|
|
138
|
-
"source": "fixtures/resolve-refs-in-config/config-with-refs.yaml",
|
|
139
|
-
},
|
|
140
|
-
"location": [
|
|
141
|
-
{
|
|
142
|
-
"pointer": "#/title",
|
|
143
|
-
"reportOnKey": false,
|
|
144
|
-
"source": "fixtures/resolve-refs-in-config/seo.yaml",
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
"message": "Expected type \`string\` but got \`integer\`.",
|
|
148
|
-
"ruleId": "configuration spec",
|
|
149
|
-
"severity": "warn",
|
|
150
|
-
"suggest": [],
|
|
151
|
-
},
|
|
152
|
-
{
|
|
153
|
-
"from": {
|
|
154
|
-
"pointer": "#/rules",
|
|
155
|
-
"source": "fixtures/resolve-refs-in-config/config-with-refs.yaml",
|
|
156
|
-
},
|
|
157
|
-
"location": [
|
|
158
|
-
{
|
|
159
|
-
"pointer": "#/non-existing-rule",
|
|
160
|
-
"reportOnKey": true,
|
|
161
|
-
"source": "fixtures/resolve-refs-in-config/rules.yaml",
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
"message": "Property \`non-existing-rule\` is not expected here.",
|
|
165
|
-
"ruleId": "configuration spec",
|
|
166
|
-
"severity": "warn",
|
|
167
|
-
"suggest": [],
|
|
168
|
-
},
|
|
169
|
-
{
|
|
170
|
-
"location": [
|
|
171
|
-
{
|
|
172
|
-
"pointer": "#/theme",
|
|
173
|
-
"reportOnKey": false,
|
|
174
|
-
"source": "fixtures/resolve-refs-in-config/config-with-refs.yaml",
|
|
175
|
-
},
|
|
176
|
-
],
|
|
177
|
-
"message": "Can't resolve $ref: ENOENT: no such file or directory 'fixtures/resolve-refs-in-config/wrong-ref.yaml'",
|
|
178
|
-
"ruleId": "configuration no-unresolved-refs",
|
|
179
|
-
"severity": "warn",
|
|
180
|
-
"suggest": [],
|
|
181
|
-
},
|
|
182
|
-
]
|
|
183
|
-
`);
|
|
184
209
|
});
|
|
185
210
|
});
|
|
186
211
|
|