@redocly/openapi-core 1.0.0-beta.109 → 1.0.0-beta.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/lib/config/config-resolvers.js +44 -25
- package/lib/config/config.d.ts +1 -0
- package/lib/config/config.js +1 -0
- package/lib/config/load.d.ts +8 -2
- package/lib/config/load.js +4 -2
- package/lib/config/types.d.ts +10 -0
- package/lib/config/utils.js +2 -2
- package/lib/rules/ajv.d.ts +1 -1
- package/lib/rules/ajv.js +5 -5
- package/lib/rules/common/assertions/asserts.d.ts +3 -5
- package/lib/rules/common/assertions/asserts.js +137 -97
- package/lib/rules/common/assertions/index.js +2 -6
- package/lib/rules/common/assertions/utils.d.ts +12 -6
- package/lib/rules/common/assertions/utils.js +33 -20
- package/lib/rules/common/no-ambiguous-paths.js +1 -1
- package/lib/rules/common/no-identical-paths.js +4 -4
- package/lib/rules/common/operation-2xx-response.js +2 -2
- package/lib/rules/common/operation-4xx-response.js +2 -2
- package/lib/rules/common/path-not-include-query.js +1 -1
- package/lib/rules/common/path-params-defined.js +7 -2
- package/lib/rules/common/response-contains-header.js +2 -2
- package/lib/rules/common/security-defined.js +10 -5
- package/lib/rules/common/spec.js +14 -12
- package/lib/rules/oas3/request-mime-type.js +1 -1
- package/lib/rules/oas3/response-mime-type.js +1 -1
- package/lib/rules/other/stats.d.ts +1 -1
- package/lib/rules/other/stats.js +1 -1
- package/lib/rules/utils.d.ts +1 -0
- package/lib/rules/utils.js +18 -2
- package/lib/types/oas2.js +6 -6
- package/lib/types/oas3.js +11 -11
- package/lib/types/oas3_1.js +3 -3
- package/lib/types/redocly-yaml.js +30 -5
- package/lib/utils.d.ts +1 -0
- package/lib/utils.js +13 -1
- package/lib/visitors.d.ts +7 -6
- package/lib/visitors.js +11 -3
- package/package.json +3 -5
- package/src/__tests__/__snapshots__/bundle.test.ts.snap +1 -1
- package/src/__tests__/lint.test.ts +88 -0
- package/src/__tests__/utils.test.ts +11 -0
- package/src/__tests__/walk.test.ts +2 -2
- package/src/config/__tests__/config-resolvers.test.ts +62 -1
- package/src/config/__tests__/config.test.ts +5 -0
- package/src/config/__tests__/fixtures/resolve-config/local-config-with-custom-function.yaml +16 -0
- package/src/config/__tests__/fixtures/resolve-config/local-config-with-wrong-custom-function.yaml +16 -0
- package/src/config/__tests__/fixtures/resolve-config/plugin.js +11 -0
- package/src/config/__tests__/load.test.ts +1 -1
- package/src/config/__tests__/resolve-plugins.test.ts +3 -3
- package/src/config/config-resolvers.ts +30 -6
- package/src/config/config.ts +2 -0
- package/src/config/load.ts +10 -4
- package/src/config/types.ts +13 -0
- package/src/config/utils.ts +1 -0
- package/src/rules/ajv.ts +4 -4
- package/src/rules/common/__tests__/operation-2xx-response.test.ts +37 -0
- package/src/rules/common/__tests__/operation-4xx-response.test.ts +37 -0
- package/src/rules/common/__tests__/path-params-defined.test.ts +69 -0
- package/src/rules/common/__tests__/security-defined.test.ts +6 -6
- package/src/rules/common/__tests__/spec.test.ts +125 -0
- package/src/rules/common/assertions/__tests__/asserts.test.ts +491 -428
- package/src/rules/common/assertions/__tests__/utils.test.ts +2 -2
- package/src/rules/common/assertions/asserts.ts +155 -97
- package/src/rules/common/assertions/index.ts +2 -11
- package/src/rules/common/assertions/utils.ts +66 -36
- package/src/rules/common/no-ambiguous-paths.ts +1 -1
- package/src/rules/common/no-identical-paths.ts +4 -4
- package/src/rules/common/operation-2xx-response.ts +2 -2
- package/src/rules/common/operation-4xx-response.ts +2 -2
- package/src/rules/common/path-not-include-query.ts +1 -1
- package/src/rules/common/path-params-defined.ts +9 -2
- package/src/rules/common/response-contains-header.ts +6 -1
- package/src/rules/common/security-defined.ts +10 -5
- package/src/rules/common/spec.ts +15 -11
- package/src/rules/oas3/__tests__/no-invalid-media-type-examples.test.ts +51 -2
- package/src/rules/oas3/__tests__/response-contains-header.test.ts +116 -0
- package/src/rules/oas3/request-mime-type.ts +1 -1
- package/src/rules/oas3/response-mime-type.ts +1 -1
- package/src/rules/other/stats.ts +1 -1
- package/src/rules/utils.ts +24 -1
- package/src/types/oas2.ts +6 -6
- package/src/types/oas3.ts +11 -11
- package/src/types/oas3_1.ts +3 -3
- package/src/types/redocly-yaml.ts +30 -4
- package/src/utils.ts +13 -0
- package/src/visitors.ts +25 -10
- package/tsconfig.tsbuildinfo +1 -1
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ See https://github.com/Redocly/redocly-cli
|
|
|
10
10
|
import { formatProblems, lint, loadConfig } from '@redocly/openapi-core';
|
|
11
11
|
|
|
12
12
|
const pathToApi = 'openapi.yaml';
|
|
13
|
-
const config = loadConfig('optional/path/to/.redocly.yaml');
|
|
13
|
+
const config = loadConfig({ configPath: 'optional/path/to/.redocly.yaml' });
|
|
14
14
|
const lintResults = await lint({ ref: pathToApi, config });
|
|
15
15
|
```
|
|
16
16
|
|
|
@@ -20,6 +20,6 @@ const lintResults = await lint({ ref: pathToApi, config });
|
|
|
20
20
|
import { formatProblems, bundle, loadConfig } from '@redocly/openapi-core';
|
|
21
21
|
|
|
22
22
|
const pathToApi = 'openapi.yaml';
|
|
23
|
-
const config = loadConfig('optional/path/to/.redocly.yaml');
|
|
23
|
+
const config = loadConfig({ configPath: 'optional/path/to/.redocly.yaml' });
|
|
24
24
|
const { bundle, problems } = await bundle({ ref: pathToApi, config });
|
|
25
25
|
```
|
|
@@ -23,20 +23,22 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
23
23
|
exports.resolvePreset = exports.resolveStyleguideConfig = exports.resolveApis = exports.resolvePlugins = exports.resolveConfig = void 0;
|
|
24
24
|
const path = require("path");
|
|
25
25
|
const ref_utils_1 = require("../ref-utils");
|
|
26
|
+
const utils_1 = require("../utils");
|
|
26
27
|
const resolve_1 = require("../resolve");
|
|
27
28
|
const builtIn_1 = require("./builtIn");
|
|
28
|
-
const
|
|
29
|
+
const utils_2 = require("./utils");
|
|
29
30
|
const env_1 = require("../env");
|
|
30
|
-
const
|
|
31
|
+
const utils_3 = require("../utils");
|
|
31
32
|
const config_1 = require("./config");
|
|
32
33
|
const logger_1 = require("../logger");
|
|
34
|
+
const asserts_1 = require("../rules/common/assertions/asserts");
|
|
33
35
|
function resolveConfig(rawConfig, configPath) {
|
|
34
36
|
var _a, _b, _c, _d, _e;
|
|
35
37
|
return __awaiter(this, void 0, void 0, function* () {
|
|
36
|
-
if ((_b = (_a = rawConfig.styleguide) === null || _a === void 0 ? void 0 : _a.extends) === null || _b === void 0 ? void 0 : _b.some(
|
|
38
|
+
if ((_b = (_a = rawConfig.styleguide) === null || _a === void 0 ? void 0 : _a.extends) === null || _b === void 0 ? void 0 : _b.some(utils_3.isNotString)) {
|
|
37
39
|
throw new Error(`Error configuration format not detected in extends value must contain strings`);
|
|
38
40
|
}
|
|
39
|
-
const resolver = new resolve_1.BaseResolver(
|
|
41
|
+
const resolver = new resolve_1.BaseResolver(utils_2.getResolveConfig(rawConfig.resolve));
|
|
40
42
|
const configExtends = (_d = (_c = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.styleguide) === null || _c === void 0 ? void 0 : _c.extends) !== null && _d !== void 0 ? _d : ['recommended'];
|
|
41
43
|
const recommendedFallback = !((_e = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.styleguide) === null || _e === void 0 ? void 0 : _e.extends);
|
|
42
44
|
const styleguideConfig = Object.assign(Object.assign({}, rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.styleguide), { extends: configExtends, recommendedFallback });
|
|
@@ -60,11 +62,11 @@ function resolvePlugins(plugins, configPath = '') {
|
|
|
60
62
|
return [];
|
|
61
63
|
// TODO: implement or reuse Resolver approach so it will work in node and browser envs
|
|
62
64
|
const requireFunc = (plugin) => {
|
|
63
|
-
if (env_1.isBrowser &&
|
|
65
|
+
if (env_1.isBrowser && utils_3.isString(plugin)) {
|
|
64
66
|
logger_1.logger.error(`Cannot load ${plugin}. Plugins aren't supported in browser yet.`);
|
|
65
67
|
return undefined;
|
|
66
68
|
}
|
|
67
|
-
if (
|
|
69
|
+
if (utils_3.isString(plugin)) {
|
|
68
70
|
const absoltePluginPath = path.resolve(path.dirname(configPath), plugin);
|
|
69
71
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
70
72
|
// @ts-ignore
|
|
@@ -79,7 +81,7 @@ function resolvePlugins(plugins, configPath = '') {
|
|
|
79
81
|
const seenPluginIds = new Map();
|
|
80
82
|
return plugins
|
|
81
83
|
.map((p) => {
|
|
82
|
-
if (
|
|
84
|
+
if (utils_3.isString(p) && ref_utils_1.isAbsoluteUrl(p)) {
|
|
83
85
|
throw new Error(logger_1.colorize.red(`We don't support remote plugins yet.`));
|
|
84
86
|
}
|
|
85
87
|
// TODO: resolve npm packages similar to eslint
|
|
@@ -103,10 +105,10 @@ function resolvePlugins(plugins, configPath = '') {
|
|
|
103
105
|
}
|
|
104
106
|
plugin.rules = {};
|
|
105
107
|
if (pluginModule.rules.oas3) {
|
|
106
|
-
plugin.rules.oas3 =
|
|
108
|
+
plugin.rules.oas3 = utils_2.prefixRules(pluginModule.rules.oas3, id);
|
|
107
109
|
}
|
|
108
110
|
if (pluginModule.rules.oas2) {
|
|
109
|
-
plugin.rules.oas2 =
|
|
111
|
+
plugin.rules.oas2 = utils_2.prefixRules(pluginModule.rules.oas2, id);
|
|
110
112
|
}
|
|
111
113
|
}
|
|
112
114
|
if (pluginModule.preprocessors) {
|
|
@@ -115,10 +117,10 @@ function resolvePlugins(plugins, configPath = '') {
|
|
|
115
117
|
}
|
|
116
118
|
plugin.preprocessors = {};
|
|
117
119
|
if (pluginModule.preprocessors.oas3) {
|
|
118
|
-
plugin.preprocessors.oas3 =
|
|
120
|
+
plugin.preprocessors.oas3 = utils_2.prefixRules(pluginModule.preprocessors.oas3, id);
|
|
119
121
|
}
|
|
120
122
|
if (pluginModule.preprocessors.oas2) {
|
|
121
|
-
plugin.preprocessors.oas2 =
|
|
123
|
+
plugin.preprocessors.oas2 = utils_2.prefixRules(pluginModule.preprocessors.oas2, id);
|
|
122
124
|
}
|
|
123
125
|
}
|
|
124
126
|
if (pluginModule.decorators) {
|
|
@@ -127,15 +129,18 @@ function resolvePlugins(plugins, configPath = '') {
|
|
|
127
129
|
}
|
|
128
130
|
plugin.decorators = {};
|
|
129
131
|
if (pluginModule.decorators.oas3) {
|
|
130
|
-
plugin.decorators.oas3 =
|
|
132
|
+
plugin.decorators.oas3 = utils_2.prefixRules(pluginModule.decorators.oas3, id);
|
|
131
133
|
}
|
|
132
134
|
if (pluginModule.decorators.oas2) {
|
|
133
|
-
plugin.decorators.oas2 =
|
|
135
|
+
plugin.decorators.oas2 = utils_2.prefixRules(pluginModule.decorators.oas2, id);
|
|
134
136
|
}
|
|
135
137
|
}
|
|
138
|
+
if (pluginModule.assertions) {
|
|
139
|
+
plugin.assertions = pluginModule.assertions;
|
|
140
|
+
}
|
|
136
141
|
return plugin;
|
|
137
142
|
})
|
|
138
|
-
.filter(
|
|
143
|
+
.filter(utils_3.isDefined);
|
|
139
144
|
}
|
|
140
145
|
exports.resolvePlugins = resolvePlugins;
|
|
141
146
|
function resolveApis({ rawConfig, configPath = '', resolver, }) {
|
|
@@ -144,7 +149,7 @@ function resolveApis({ rawConfig, configPath = '', resolver, }) {
|
|
|
144
149
|
const { apis = {}, styleguide: styleguideConfig = {} } = rawConfig;
|
|
145
150
|
const resolvedApis = {};
|
|
146
151
|
for (const [apiName, apiContent] of Object.entries(apis || {})) {
|
|
147
|
-
if ((_b = (_a = apiContent.styleguide) === null || _a === void 0 ? void 0 : _a.extends) === null || _b === void 0 ? void 0 : _b.some(
|
|
152
|
+
if ((_b = (_a = apiContent.styleguide) === null || _a === void 0 ? void 0 : _a.extends) === null || _b === void 0 ? void 0 : _b.some(utils_3.isNotString)) {
|
|
148
153
|
throw new Error(`Error configuration format not detected in extends value must contain strings`);
|
|
149
154
|
}
|
|
150
155
|
const rawStyleguideConfig = getMergedRawStyleguideConfig(styleguideConfig, apiContent.styleguide);
|
|
@@ -165,8 +170,8 @@ function resolveAndMergeNestedStyleguideConfig({ styleguideConfig, configPath =
|
|
|
165
170
|
if (parentConfigPaths.includes(configPath)) {
|
|
166
171
|
throw new Error(`Circular dependency in config file: "${configPath}"`);
|
|
167
172
|
}
|
|
168
|
-
const plugins =
|
|
169
|
-
const pluginPaths = (_a = styleguideConfig === null || styleguideConfig === void 0 ? void 0 : styleguideConfig.plugins) === null || _a === void 0 ? void 0 : _a.filter(
|
|
173
|
+
const plugins = utils_2.getUniquePlugins(resolvePlugins([...((styleguideConfig === null || styleguideConfig === void 0 ? void 0 : styleguideConfig.plugins) || []), builtIn_1.defaultPlugin], configPath));
|
|
174
|
+
const pluginPaths = (_a = styleguideConfig === null || styleguideConfig === void 0 ? void 0 : styleguideConfig.plugins) === null || _a === void 0 ? void 0 : _a.filter(utils_3.isString).map((p) => path.resolve(path.dirname(configPath), p));
|
|
170
175
|
const resolvedConfigPath = ref_utils_1.isAbsoluteUrl(configPath)
|
|
171
176
|
? configPath
|
|
172
177
|
: configPath && path.resolve(configPath);
|
|
@@ -186,24 +191,23 @@ function resolveAndMergeNestedStyleguideConfig({ styleguideConfig, configPath =
|
|
|
186
191
|
resolver: resolver,
|
|
187
192
|
}, [...parentConfigPaths, resolvedConfigPath], extendPaths);
|
|
188
193
|
}))) || []);
|
|
189
|
-
const _d =
|
|
194
|
+
const _d = utils_2.mergeExtends([
|
|
190
195
|
...extendConfigs,
|
|
191
196
|
Object.assign(Object.assign({}, styleguideConfig), { plugins, extends: undefined, extendPaths: [...parentConfigPaths, resolvedConfigPath], pluginPaths }),
|
|
192
197
|
]), { plugins: mergedPlugins = [] } = _d, styleguide = __rest(_d, ["plugins"]);
|
|
193
|
-
return Object.assign(Object.assign({}, styleguide), { extendPaths: (_c = styleguide.extendPaths) === null || _c === void 0 ? void 0 : _c.filter((path) => path && !ref_utils_1.isAbsoluteUrl(path)), plugins:
|
|
198
|
+
return Object.assign(Object.assign({}, styleguide), { extendPaths: (_c = styleguide.extendPaths) === null || _c === void 0 ? void 0 : _c.filter((path) => path && !ref_utils_1.isAbsoluteUrl(path)), plugins: utils_2.getUniquePlugins(mergedPlugins), recommendedFallback: styleguideConfig === null || styleguideConfig === void 0 ? void 0 : styleguideConfig.recommendedFallback, doNotResolveExamples: styleguideConfig === null || styleguideConfig === void 0 ? void 0 : styleguideConfig.doNotResolveExamples });
|
|
194
199
|
});
|
|
195
200
|
}
|
|
196
201
|
function resolveStyleguideConfig(opts, parentConfigPaths = [], extendPaths = []) {
|
|
197
202
|
return __awaiter(this, void 0, void 0, function* () {
|
|
198
203
|
const resolvedStyleguideConfig = yield resolveAndMergeNestedStyleguideConfig(opts, parentConfigPaths, extendPaths);
|
|
199
|
-
return Object.assign(Object.assign({}, resolvedStyleguideConfig), { rules: resolvedStyleguideConfig.rules &&
|
|
200
|
-
groupStyleguideAssertionRules(resolvedStyleguideConfig.rules) });
|
|
204
|
+
return Object.assign(Object.assign({}, resolvedStyleguideConfig), { rules: resolvedStyleguideConfig.rules && groupStyleguideAssertionRules(resolvedStyleguideConfig) });
|
|
201
205
|
});
|
|
202
206
|
}
|
|
203
207
|
exports.resolveStyleguideConfig = resolveStyleguideConfig;
|
|
204
208
|
function resolvePreset(presetName, plugins) {
|
|
205
209
|
var _a;
|
|
206
|
-
const { pluginId, configName } =
|
|
210
|
+
const { pluginId, configName } = utils_2.parsePresetName(presetName);
|
|
207
211
|
const plugin = plugins.find((p) => p.id === pluginId);
|
|
208
212
|
if (!plugin) {
|
|
209
213
|
throw new Error(`Invalid config ${logger_1.colorize.red(presetName)}: plugin ${pluginId} is not included.`);
|
|
@@ -221,7 +225,7 @@ function loadExtendStyleguideConfig(filePath, resolver) {
|
|
|
221
225
|
return __awaiter(this, void 0, void 0, function* () {
|
|
222
226
|
try {
|
|
223
227
|
const fileSource = yield resolver.loadExternalRef(filePath);
|
|
224
|
-
const rawConfig =
|
|
228
|
+
const rawConfig = utils_2.transformConfig(utils_3.parseYaml(fileSource.body));
|
|
225
229
|
if (!rawConfig.styleguide) {
|
|
226
230
|
throw new Error(`Styleguide configuration format not detected: "${filePath}"`);
|
|
227
231
|
}
|
|
@@ -233,12 +237,12 @@ function loadExtendStyleguideConfig(filePath, resolver) {
|
|
|
233
237
|
});
|
|
234
238
|
}
|
|
235
239
|
function getMergedRawStyleguideConfig(rootStyleguideConfig, apiStyleguideConfig) {
|
|
236
|
-
const resultLint = Object.assign(Object.assign(Object.assign({}, rootStyleguideConfig), apiStyleguideConfig), { rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.rules), oas2Rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas2Rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas2Rules), oas3_0Rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_0Rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_0Rules), oas3_1Rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_1Rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_1Rules), preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.preprocessors), oas2Preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas2Preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas2Preprocessors), oas3_0Preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_0Preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_0Preprocessors), oas3_1Preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_1Preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_1Preprocessors), decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.decorators), oas2Decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas2Decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas2Decorators), oas3_0Decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_0Decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_0Decorators), oas3_1Decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_1Decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_1Decorators), recommendedFallback: (apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.extends)
|
|
240
|
+
const resultLint = Object.assign(Object.assign(Object.assign({}, rootStyleguideConfig), utils_1.pickDefined(apiStyleguideConfig)), { rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.rules), oas2Rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas2Rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas2Rules), oas3_0Rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_0Rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_0Rules), oas3_1Rules: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_1Rules), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_1Rules), preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.preprocessors), oas2Preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas2Preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas2Preprocessors), oas3_0Preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_0Preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_0Preprocessors), oas3_1Preprocessors: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_1Preprocessors), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_1Preprocessors), decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.decorators), oas2Decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas2Decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas2Decorators), oas3_0Decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_0Decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_0Decorators), oas3_1Decorators: Object.assign(Object.assign({}, rootStyleguideConfig === null || rootStyleguideConfig === void 0 ? void 0 : rootStyleguideConfig.oas3_1Decorators), apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.oas3_1Decorators), recommendedFallback: (apiStyleguideConfig === null || apiStyleguideConfig === void 0 ? void 0 : apiStyleguideConfig.extends)
|
|
237
241
|
? false
|
|
238
242
|
: rootStyleguideConfig.recommendedFallback });
|
|
239
243
|
return resultLint;
|
|
240
244
|
}
|
|
241
|
-
function groupStyleguideAssertionRules(rules) {
|
|
245
|
+
function groupStyleguideAssertionRules({ rules, plugins, }) {
|
|
242
246
|
if (!rules) {
|
|
243
247
|
return rules;
|
|
244
248
|
}
|
|
@@ -249,6 +253,21 @@ function groupStyleguideAssertionRules(rules) {
|
|
|
249
253
|
for (const [ruleKey, rule] of Object.entries(rules)) {
|
|
250
254
|
if (ruleKey.startsWith('assert/') && typeof rule === 'object' && rule !== null) {
|
|
251
255
|
const assertion = rule;
|
|
256
|
+
if (plugins) {
|
|
257
|
+
for (const field of Object.keys(assertion)) {
|
|
258
|
+
const [pluginId, fn] = field.split('/');
|
|
259
|
+
if (!pluginId || !fn)
|
|
260
|
+
continue;
|
|
261
|
+
const plugin = plugins.find((plugin) => plugin.id === pluginId);
|
|
262
|
+
if (!plugin) {
|
|
263
|
+
throw Error(logger_1.colorize.red(`Plugin ${logger_1.colorize.blue(pluginId)} isn't found.`));
|
|
264
|
+
}
|
|
265
|
+
if (!plugin.assertions || !plugin.assertions[fn]) {
|
|
266
|
+
throw Error(`Plugin ${logger_1.colorize.red(pluginId)} doesn't export assertions function with name ${logger_1.colorize.red(fn)}.`);
|
|
267
|
+
}
|
|
268
|
+
asserts_1.asserts[field] = asserts_1.buildAssertCustomFunction(plugin.assertions[fn]);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
252
271
|
assertions.push(Object.assign(Object.assign({}, assertion), { assertionId: ruleKey.replace('assert/', '') }));
|
|
253
272
|
}
|
|
254
273
|
else {
|
package/lib/config/config.d.ts
CHANGED
package/lib/config/config.js
CHANGED
|
@@ -249,6 +249,7 @@ class Config {
|
|
|
249
249
|
this.resolve = utils_2.getResolveConfig(rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.resolve);
|
|
250
250
|
this.region = rawConfig.region;
|
|
251
251
|
this.organization = rawConfig.organization;
|
|
252
|
+
this.files = rawConfig.files || [];
|
|
252
253
|
}
|
|
253
254
|
}
|
|
254
255
|
exports.Config = Config;
|
package/lib/config/load.d.ts
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { Config } from './config';
|
|
2
|
-
import type { RawConfig } from './types';
|
|
2
|
+
import type { RawConfig, Region } from './types';
|
|
3
3
|
import { RegionalTokenWithValidity } from '../redocly/redocly-client-types';
|
|
4
|
-
export declare function loadConfig(
|
|
4
|
+
export declare function loadConfig(options?: {
|
|
5
|
+
configPath?: string;
|
|
6
|
+
customExtends?: string[];
|
|
7
|
+
processRawConfig?: (rawConfig: RawConfig) => void | Promise<void>;
|
|
8
|
+
files?: string[];
|
|
9
|
+
region?: Region;
|
|
10
|
+
}): Promise<Config>;
|
|
5
11
|
export declare const CONFIG_FILE_NAMES: string[];
|
|
6
12
|
export declare function findConfig(dir?: string): string | undefined;
|
|
7
13
|
export declare function getConfig(configPath?: string | undefined): Promise<RawConfig>;
|
package/lib/config/load.js
CHANGED
|
@@ -59,9 +59,11 @@ function addConfigMetadata({ rawConfig, customExtends, configPath, tokens, }) {
|
|
|
59
59
|
return config_resolvers_1.resolveConfig(rawConfig, configPath);
|
|
60
60
|
});
|
|
61
61
|
}
|
|
62
|
-
function loadConfig(
|
|
62
|
+
function loadConfig(options = {}) {
|
|
63
63
|
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
-
const
|
|
64
|
+
const { configPath = findConfig(), customExtends, processRawConfig, files, region } = options;
|
|
65
|
+
const config = yield getConfig(configPath);
|
|
66
|
+
const rawConfig = Object.assign(Object.assign({}, config), { files: files !== null && files !== void 0 ? files : config.files, region: region !== null && region !== void 0 ? region : config.region });
|
|
65
67
|
if (typeof processRawConfig === 'function') {
|
|
66
68
|
yield processRawConfig(rawConfig);
|
|
67
69
|
}
|
package/lib/config/types.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ProblemSeverity } from '../walk';
|
|
2
2
|
import type { Oas3PreprocessorsSet, OasMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet, Oas3RuleSet, OasVersion } from '../oas-types';
|
|
3
3
|
import type { NodeType } from '../types';
|
|
4
|
+
import { Location } from '../ref-utils';
|
|
4
5
|
export declare type RuleSeverity = ProblemSeverity | 'off';
|
|
5
6
|
export declare type PreprocessorSeverity = RuleSeverity | 'on';
|
|
6
7
|
export declare type RuleConfig = RuleSeverity | ({
|
|
@@ -50,6 +51,12 @@ export declare type CustomRulesConfig = {
|
|
|
50
51
|
oas3?: Oas3RuleSet;
|
|
51
52
|
oas2?: Oas2RuleSet;
|
|
52
53
|
};
|
|
54
|
+
export declare type AssertResult = {
|
|
55
|
+
message?: string;
|
|
56
|
+
location?: Location;
|
|
57
|
+
};
|
|
58
|
+
export declare type CustomFunction = (value: any, options: unknown, baseLocation: Location) => AssertResult[];
|
|
59
|
+
export declare type AssertionsConfig = Record<string, CustomFunction>;
|
|
53
60
|
export declare type Plugin = {
|
|
54
61
|
id: string;
|
|
55
62
|
configs?: Record<string, PluginStyleguideConfig>;
|
|
@@ -57,6 +64,7 @@ export declare type Plugin = {
|
|
|
57
64
|
preprocessors?: PreprocessorsConfig;
|
|
58
65
|
decorators?: DecoratorsConfig;
|
|
59
66
|
typeExtension?: TypeExtensionsConfig;
|
|
67
|
+
assertions?: AssertionsConfig;
|
|
60
68
|
};
|
|
61
69
|
export declare type PluginStyleguideConfig = Omit<StyleguideRawConfig, 'plugins' | 'extends'>;
|
|
62
70
|
export declare type ResolveHeader = {
|
|
@@ -101,6 +109,7 @@ export declare type DeprecatedInApi = {
|
|
|
101
109
|
};
|
|
102
110
|
export declare type ResolvedApi = Omit<Api, 'styleguide'> & {
|
|
103
111
|
styleguide: ResolvedStyleguideConfig;
|
|
112
|
+
files?: string[];
|
|
104
113
|
};
|
|
105
114
|
export declare type RawConfig = {
|
|
106
115
|
apis?: Record<string, Api>;
|
|
@@ -108,6 +117,7 @@ export declare type RawConfig = {
|
|
|
108
117
|
resolve?: RawResolveConfig;
|
|
109
118
|
region?: Region;
|
|
110
119
|
organization?: string;
|
|
120
|
+
files?: string[];
|
|
111
121
|
} & FeaturesConfig;
|
|
112
122
|
export declare type FlatApi = Omit<Api, 'styleguide'> & Omit<ApiStyleguideRawConfig, 'doNotResolveExamples'>;
|
|
113
123
|
export declare type FlatRawConfig = Omit<RawConfig, 'styleguide' | 'resolve' | 'apis'> & Omit<StyleguideRawConfig, 'doNotResolveExamples'> & {
|
package/lib/config/utils.js
CHANGED
|
@@ -139,7 +139,7 @@ function mergeExtends(rulesConfList) {
|
|
|
139
139
|
}
|
|
140
140
|
exports.mergeExtends = mergeExtends;
|
|
141
141
|
function getMergedConfig(config, apiName) {
|
|
142
|
-
var _a, _b, _c, _d, _e, _f;
|
|
142
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
143
143
|
const extendPaths = [
|
|
144
144
|
...Object.values(config.apis).map((api) => { var _a; return (_a = api === null || api === void 0 ? void 0 : api.styleguide) === null || _a === void 0 ? void 0 : _a.extendPaths; }),
|
|
145
145
|
(_b = (_a = config.rawConfig) === null || _a === void 0 ? void 0 : _a.styleguide) === null || _b === void 0 ? void 0 : _b.extendPaths,
|
|
@@ -156,7 +156,7 @@ function getMergedConfig(config, apiName) {
|
|
|
156
156
|
? new config_1.Config(Object.assign(Object.assign({}, config.rawConfig), { styleguide: Object.assign(Object.assign({}, (config.apis[apiName]
|
|
157
157
|
? config.apis[apiName].styleguide
|
|
158
158
|
: config.rawConfig.styleguide)), { extendPaths,
|
|
159
|
-
pluginPaths }), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_e = config.apis[apiName]) === null || _e === void 0 ? void 0 : _e['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_f = config.apis[apiName]) === null || _f === void 0 ? void 0 : _f['features.mockServer']) }), config.configFile)
|
|
159
|
+
pluginPaths }), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_e = config.apis[apiName]) === null || _e === void 0 ? void 0 : _e['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_f = config.apis[apiName]) === null || _f === void 0 ? void 0 : _f['features.mockServer']), files: [...config.files, ...((_j = (_h = (_g = config.apis) === null || _g === void 0 ? void 0 : _g[apiName]) === null || _h === void 0 ? void 0 : _h.files) !== null && _j !== void 0 ? _j : [])] }), config.configFile)
|
|
160
160
|
: config;
|
|
161
161
|
}
|
|
162
162
|
exports.getMergedConfig = getMergedConfig;
|
package/lib/rules/ajv.d.ts
CHANGED
package/lib/rules/ajv.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateJsonSchema = exports.releaseAjvInstance = void 0;
|
|
4
|
-
const
|
|
4
|
+
const _2020_1 = require("@redocly/ajv/dist/2020");
|
|
5
5
|
const ref_utils_1 = require("../ref-utils");
|
|
6
6
|
let ajvInstance = null;
|
|
7
7
|
function releaseAjvInstance() {
|
|
@@ -10,7 +10,7 @@ function releaseAjvInstance() {
|
|
|
10
10
|
exports.releaseAjvInstance = releaseAjvInstance;
|
|
11
11
|
function getAjv(resolve, allowAdditionalProperties) {
|
|
12
12
|
if (!ajvInstance) {
|
|
13
|
-
ajvInstance = new
|
|
13
|
+
ajvInstance = new _2020_1.default({
|
|
14
14
|
schemaId: '$id',
|
|
15
15
|
meta: true,
|
|
16
16
|
allErrors: true,
|
|
@@ -20,7 +20,7 @@ function getAjv(resolve, allowAdditionalProperties) {
|
|
|
20
20
|
discriminator: true,
|
|
21
21
|
allowUnionTypes: true,
|
|
22
22
|
validateFormats: false,
|
|
23
|
-
|
|
23
|
+
defaultUnevaluatedProperties: allowAdditionalProperties,
|
|
24
24
|
loadSchemaSync(base, $ref) {
|
|
25
25
|
const resolvedRef = resolve({ $ref }, base.split('#')[0]);
|
|
26
26
|
if (!resolvedRef || !resolvedRef.location)
|
|
@@ -68,8 +68,8 @@ function validateJsonSchema(data, schema, schemaLoc, instancePath, resolve, allo
|
|
|
68
68
|
if (propName) {
|
|
69
69
|
message = `\`${propName}\` property ${message}`;
|
|
70
70
|
}
|
|
71
|
-
if (error.keyword === 'additionalProperties') {
|
|
72
|
-
const property = error.params.additionalProperty;
|
|
71
|
+
if (error.keyword === 'additionalProperties' || error.keyword === 'unevaluatedProperties') {
|
|
72
|
+
const property = error.params.additionalProperty || error.params.unevaluatedProperty;
|
|
73
73
|
message = `${message} \`${property}\``;
|
|
74
74
|
error.instancePath += '/' + ref_utils_1.escapePointer(property);
|
|
75
75
|
}
|
|
@@ -1,10 +1,8 @@
|
|
|
1
|
+
import { AssertResult, CustomFunction } from 'core/src/config/types';
|
|
1
2
|
import { Location } from '../../../ref-utils';
|
|
2
|
-
declare type
|
|
3
|
-
isValid: boolean;
|
|
4
|
-
location?: Location;
|
|
5
|
-
};
|
|
6
|
-
declare type Asserts = Record<string, (value: any, condition: any, baseLocation: Location, rawValue?: any) => AssertResult>;
|
|
3
|
+
declare type Asserts = Record<string, (value: any, condition: any, baseLocation: Location, rawValue?: any) => AssertResult[]>;
|
|
7
4
|
export declare const runOnKeysSet: Set<string>;
|
|
8
5
|
export declare const runOnValuesSet: Set<string>;
|
|
9
6
|
export declare const asserts: Asserts;
|
|
7
|
+
export declare function buildAssertCustomFunction(fn: CustomFunction): (value: string[], options: any, baseLocation: Location) => any;
|
|
10
8
|
export {};
|