@redocly/openapi-core 1.0.0-beta.87 → 1.0.0-beta.90
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__/codeframes.test.ts +22 -0
- package/lib/config/config.d.ts +46 -4
- package/lib/config/config.js +66 -6
- package/lib/config/load.d.ts +4 -3
- package/lib/config/load.js +22 -16
- package/lib/format/codeframes.js +5 -2
- package/lib/index.d.ts +3 -3
- package/lib/index.js +4 -1
- package/lib/redocly/index.d.ts +4 -1
- package/lib/redocly/index.js +28 -19
- package/lib/redocly/registry-api.d.ts +4 -1
- package/lib/redocly/registry-api.js +3 -3
- package/lib/rules/oas3/no-empty-servers.js +2 -1
- package/lib/types/redocly-yaml.js +31 -10
- package/package.json +1 -1
- package/src/__tests__/lint.test.ts +40 -6
- package/src/config/__tests__/load.test.ts +7 -0
- package/src/config/config.ts +104 -16
- package/src/config/load.ts +18 -20
- package/src/format/codeframes.ts +4 -2
- package/src/index.ts +11 -3
- package/src/redocly/index.ts +49 -30
- package/src/redocly/registry-api.ts +38 -21
- package/src/rules/oas3/__tests__/spec/spec.test.ts +4 -4
- package/src/rules/oas3/no-empty-servers.ts +2 -1
- package/src/types/redocly-yaml.ts +38 -10
- package/src/utils.ts +0 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -85,6 +85,28 @@ describe('Location', () => {
|
|
|
85
85
|
expect(preciseLocation.end).toEqual({ line: 5, col: 28 });
|
|
86
86
|
});
|
|
87
87
|
|
|
88
|
+
it('should correctly fallback to the closest parent node if node value is null', () => {
|
|
89
|
+
const loc = {
|
|
90
|
+
reportOnKey: false,
|
|
91
|
+
pointer: '#/servers',
|
|
92
|
+
source: new Source(
|
|
93
|
+
'foobar.yaml',
|
|
94
|
+
outdent`
|
|
95
|
+
openapi: 3.0.2
|
|
96
|
+
servers:
|
|
97
|
+
info:
|
|
98
|
+
license:
|
|
99
|
+
name: MIT
|
|
100
|
+
url: https://google.com
|
|
101
|
+
`,
|
|
102
|
+
),
|
|
103
|
+
};
|
|
104
|
+
const preciseLocation = getLineColLocation(loc);
|
|
105
|
+
expect(preciseLocation.start).toEqual({ line: 2, col: 1 });
|
|
106
|
+
expect(preciseLocation.end).toEqual({ line: 2, col: 9 });
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
|
|
88
110
|
it('should return first line for empty doc', () => {
|
|
89
111
|
const loc = {
|
|
90
112
|
reportOnKey: false,
|
package/lib/config/config.d.ts
CHANGED
|
@@ -78,12 +78,27 @@ export declare const DOMAINS: {
|
|
|
78
78
|
[region in Region]: string;
|
|
79
79
|
};
|
|
80
80
|
export declare const AVAILABLE_REGIONS: Region[];
|
|
81
|
-
export declare type
|
|
82
|
-
referenceDocs?: any;
|
|
81
|
+
export declare type DeprecatedRawConfig = {
|
|
83
82
|
apiDefinitions?: Record<string, string>;
|
|
84
83
|
lint?: LintRawConfig;
|
|
85
84
|
resolve?: RawResolveConfig;
|
|
86
85
|
region?: Region;
|
|
86
|
+
referenceDocs?: Record<string, any>;
|
|
87
|
+
};
|
|
88
|
+
export declare type Api = {
|
|
89
|
+
root: string;
|
|
90
|
+
lint?: Omit<LintRawConfig, 'plugins'>;
|
|
91
|
+
'features.openapi'?: Record<string, any>;
|
|
92
|
+
'features.mockServer'?: Record<string, any>;
|
|
93
|
+
};
|
|
94
|
+
export declare type RawConfig = {
|
|
95
|
+
apis?: Record<string, Api>;
|
|
96
|
+
lint?: LintRawConfig;
|
|
97
|
+
resolve?: RawResolveConfig;
|
|
98
|
+
region?: Region;
|
|
99
|
+
'features.openapi'?: Record<string, any>;
|
|
100
|
+
'features.mockServer'?: Record<string, any>;
|
|
101
|
+
organization?: string;
|
|
87
102
|
};
|
|
88
103
|
export declare class LintConfig {
|
|
89
104
|
rawConfig: LintRawConfig;
|
|
@@ -124,11 +139,38 @@ export declare class LintConfig {
|
|
|
124
139
|
export declare class Config {
|
|
125
140
|
rawConfig: RawConfig;
|
|
126
141
|
configFile?: string | undefined;
|
|
127
|
-
|
|
128
|
-
apiDefinitions: Record<string, string>;
|
|
142
|
+
apis: Record<string, Api>;
|
|
129
143
|
lint: LintConfig;
|
|
130
144
|
resolve: ResolveConfig;
|
|
131
145
|
licenseKey?: string;
|
|
132
146
|
region?: Region;
|
|
147
|
+
'features.openapi': Record<string, any>;
|
|
148
|
+
'features.mockServer'?: Record<string, any>;
|
|
149
|
+
organization?: string;
|
|
133
150
|
constructor(rawConfig: RawConfig, configFile?: string | undefined);
|
|
134
151
|
}
|
|
152
|
+
export declare function getMergedConfig(config: Config, entrypointAlias?: string): Config;
|
|
153
|
+
export declare function getMergedLintConfig(config: Config, entrypointAlias?: string): {
|
|
154
|
+
rules: {
|
|
155
|
+
[x: string]: RuleConfig;
|
|
156
|
+
};
|
|
157
|
+
preprocessors: {
|
|
158
|
+
[x: string]: PreprocessorConfig;
|
|
159
|
+
};
|
|
160
|
+
decorators: {
|
|
161
|
+
[x: string]: PreprocessorConfig;
|
|
162
|
+
};
|
|
163
|
+
extends?: string[] | undefined;
|
|
164
|
+
doNotResolveExamples?: boolean | undefined;
|
|
165
|
+
oas2Rules?: Record<string, RuleConfig> | undefined;
|
|
166
|
+
oas3_0Rules?: Record<string, RuleConfig> | undefined;
|
|
167
|
+
oas3_1Rules?: Record<string, RuleConfig> | undefined;
|
|
168
|
+
oas2Preprocessors?: Record<string, PreprocessorConfig> | undefined;
|
|
169
|
+
oas3_0Preprocessors?: Record<string, PreprocessorConfig> | undefined;
|
|
170
|
+
oas3_1Preprocessors?: Record<string, PreprocessorConfig> | undefined;
|
|
171
|
+
oas2Decorators?: Record<string, PreprocessorConfig> | undefined;
|
|
172
|
+
oas3_0Decorators?: Record<string, PreprocessorConfig> | undefined;
|
|
173
|
+
oas3_1Decorators?: Record<string, PreprocessorConfig> | undefined;
|
|
174
|
+
plugins?: (string | Plugin)[] | undefined;
|
|
175
|
+
};
|
|
176
|
+
export declare function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): RawConfig;
|
package/lib/config/config.js
CHANGED
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
2
13
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Config = exports.LintConfig = exports.AVAILABLE_REGIONS = exports.DOMAINS = exports.DEFAULT_REGION = exports.IGNORE_FILE = void 0;
|
|
14
|
+
exports.transformConfig = exports.getMergedLintConfig = exports.getMergedConfig = exports.Config = exports.LintConfig = exports.AVAILABLE_REGIONS = exports.DOMAINS = exports.DEFAULT_REGION = exports.IGNORE_FILE = void 0;
|
|
4
15
|
const fs = require("fs");
|
|
5
16
|
const path = require("path");
|
|
6
17
|
const path_1 = require("path");
|
|
@@ -18,7 +29,6 @@ exports.DOMAINS = {
|
|
|
18
29
|
us: 'redocly.com',
|
|
19
30
|
eu: 'eu.redocly.com',
|
|
20
31
|
};
|
|
21
|
-
exports.AVAILABLE_REGIONS = Object.keys(exports.DOMAINS);
|
|
22
32
|
// FIXME: temporary fix for our lab environments
|
|
23
33
|
if (REDOCLY_DOMAIN === null || REDOCLY_DOMAIN === void 0 ? void 0 : REDOCLY_DOMAIN.endsWith('.redocly.host')) {
|
|
24
34
|
exports.DOMAINS[REDOCLY_DOMAIN.split('.')[0]] = REDOCLY_DOMAIN;
|
|
@@ -26,6 +36,7 @@ if (REDOCLY_DOMAIN === null || REDOCLY_DOMAIN === void 0 ? void 0 : REDOCLY_DOMA
|
|
|
26
36
|
if (REDOCLY_DOMAIN === 'redoc.online') {
|
|
27
37
|
exports.DOMAINS[REDOCLY_DOMAIN] = REDOCLY_DOMAIN;
|
|
28
38
|
}
|
|
39
|
+
exports.AVAILABLE_REGIONS = Object.keys(exports.DOMAINS);
|
|
29
40
|
class LintConfig {
|
|
30
41
|
constructor(rawConfig, configFile) {
|
|
31
42
|
this.rawConfig = rawConfig;
|
|
@@ -65,7 +76,9 @@ class LintConfig {
|
|
|
65
76
|
[oas_types_1.OasVersion.Version3_0]: Object.assign(Object.assign({}, merged.decorators), merged.oas3_0Decorators),
|
|
66
77
|
[oas_types_1.OasVersion.Version3_1]: Object.assign(Object.assign({}, merged.decorators), merged.oas3_1Decorators),
|
|
67
78
|
};
|
|
68
|
-
const dir = this.configFile
|
|
79
|
+
const dir = this.configFile
|
|
80
|
+
? path.dirname(this.configFile)
|
|
81
|
+
: (typeof process !== 'undefined' && process.cwd()) || '';
|
|
69
82
|
const ignoreFile = path.join(dir, exports.IGNORE_FILE);
|
|
70
83
|
/* no crash when using it on the client */
|
|
71
84
|
if (fs.hasOwnProperty('existsSync') && fs.existsSync(ignoreFile)) {
|
|
@@ -87,7 +100,8 @@ class LintConfig {
|
|
|
87
100
|
const ignoreFile = path.join(dir, exports.IGNORE_FILE);
|
|
88
101
|
const mapped = {};
|
|
89
102
|
for (const absFileName of Object.keys(this.ignore)) {
|
|
90
|
-
const ignoredRules = (mapped[utils_1.slash(path.relative(dir, absFileName))] =
|
|
103
|
+
const ignoredRules = (mapped[utils_1.slash(path.relative(dir, absFileName))] =
|
|
104
|
+
this.ignore[absFileName]);
|
|
91
105
|
for (const ruleId of Object.keys(ignoredRules)) {
|
|
92
106
|
ignoredRules[ruleId] = Array.from(ignoredRules[ruleId]);
|
|
93
107
|
}
|
|
@@ -238,9 +252,10 @@ class Config {
|
|
|
238
252
|
var _a, _b, _c;
|
|
239
253
|
this.rawConfig = rawConfig;
|
|
240
254
|
this.configFile = configFile;
|
|
241
|
-
this.
|
|
255
|
+
this.apis = rawConfig.apis || {};
|
|
242
256
|
this.lint = new LintConfig(rawConfig.lint || {}, configFile);
|
|
243
|
-
this.
|
|
257
|
+
this['features.openapi'] = rawConfig['features.openapi'] || {};
|
|
258
|
+
this['features.mockServer'] = rawConfig['features.mockServer'] || {};
|
|
244
259
|
this.resolve = {
|
|
245
260
|
http: {
|
|
246
261
|
headers: (_c = (_b = (_a = rawConfig === null || rawConfig === void 0 ? void 0 : rawConfig.resolve) === null || _a === void 0 ? void 0 : _a.http) === null || _b === void 0 ? void 0 : _b.headers) !== null && _c !== void 0 ? _c : [],
|
|
@@ -248,6 +263,7 @@ class Config {
|
|
|
248
263
|
},
|
|
249
264
|
};
|
|
250
265
|
this.region = rawConfig.region;
|
|
266
|
+
this.organization = rawConfig.organization;
|
|
251
267
|
}
|
|
252
268
|
}
|
|
253
269
|
exports.Config = Config;
|
|
@@ -398,3 +414,47 @@ function assignExisting(target, obj) {
|
|
|
398
414
|
}
|
|
399
415
|
}
|
|
400
416
|
}
|
|
417
|
+
function getMergedConfig(config, entrypointAlias) {
|
|
418
|
+
var _a, _b;
|
|
419
|
+
return entrypointAlias
|
|
420
|
+
? new Config(Object.assign(Object.assign({}, config.rawConfig), { lint: getMergedLintConfig(config, entrypointAlias), 'features.openapi': Object.assign(Object.assign({}, config['features.openapi']), (_a = config.apis[entrypointAlias]) === null || _a === void 0 ? void 0 : _a['features.openapi']), 'features.mockServer': Object.assign(Object.assign({}, config['features.mockServer']), (_b = config.apis[entrypointAlias]) === null || _b === void 0 ? void 0 : _b['features.mockServer']) }))
|
|
421
|
+
: config;
|
|
422
|
+
}
|
|
423
|
+
exports.getMergedConfig = getMergedConfig;
|
|
424
|
+
function getMergedLintConfig(config, entrypointAlias) {
|
|
425
|
+
var _a, _b, _c, _d;
|
|
426
|
+
const apiLint = entrypointAlias ? (_a = config.apis[entrypointAlias]) === null || _a === void 0 ? void 0 : _a.lint : {};
|
|
427
|
+
const mergedLint = Object.assign(Object.assign(Object.assign({}, config.rawConfig.lint), apiLint), { rules: Object.assign(Object.assign({}, (_b = config.rawConfig.lint) === null || _b === void 0 ? void 0 : _b.rules), apiLint === null || apiLint === void 0 ? void 0 : apiLint.rules), preprocessors: Object.assign(Object.assign({}, (_c = config.rawConfig.lint) === null || _c === void 0 ? void 0 : _c.preprocessors), apiLint === null || apiLint === void 0 ? void 0 : apiLint.preprocessors), decorators: Object.assign(Object.assign({}, (_d = config.rawConfig.lint) === null || _d === void 0 ? void 0 : _d.decorators), apiLint === null || apiLint === void 0 ? void 0 : apiLint.decorators) });
|
|
428
|
+
return mergedLint;
|
|
429
|
+
}
|
|
430
|
+
exports.getMergedLintConfig = getMergedLintConfig;
|
|
431
|
+
function transformApiDefinitionsToApis(apiDefinitions = {}) {
|
|
432
|
+
let apis = {};
|
|
433
|
+
for (const [apiName, apiPath] of Object.entries(apiDefinitions)) {
|
|
434
|
+
apis[apiName] = { root: apiPath };
|
|
435
|
+
}
|
|
436
|
+
return apis;
|
|
437
|
+
}
|
|
438
|
+
function transformConfig(rawConfig) {
|
|
439
|
+
if (rawConfig.apis && rawConfig.apiDefinitions) {
|
|
440
|
+
throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n");
|
|
441
|
+
}
|
|
442
|
+
if (rawConfig['features.openapi'] &&
|
|
443
|
+
rawConfig.referenceDocs) {
|
|
444
|
+
throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n");
|
|
445
|
+
}
|
|
446
|
+
const _a = rawConfig, { apiDefinitions, referenceDocs } = _a, rest = __rest(_a, ["apiDefinitions", "referenceDocs"]);
|
|
447
|
+
// TODO: put links to the changelog and uncomment this after successful release of ReferenceDocs/Redoc, Portal and Workflows
|
|
448
|
+
// if (apiDefinitions) {
|
|
449
|
+
// process.stderr.write(
|
|
450
|
+
// `The ${yellow('apiDefinitions')} field is deprecated. Use ${green('apis')} instead, see changelog: <link>\n`
|
|
451
|
+
// );
|
|
452
|
+
// }
|
|
453
|
+
// if (referenceDocs) {
|
|
454
|
+
// process.stderr.write(
|
|
455
|
+
// `The ${yellow('referenceDocs')} field is deprecated. Use ${green('features.openapi')} instead, see changelog: <link>\n`
|
|
456
|
+
// );
|
|
457
|
+
// }
|
|
458
|
+
return Object.assign({ 'features.openapi': referenceDocs, apis: transformApiDefinitionsToApis(apiDefinitions) }, rest);
|
|
459
|
+
}
|
|
460
|
+
exports.transformConfig = transformConfig;
|
package/lib/config/load.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { Config } from './config';
|
|
2
|
-
export declare function loadConfig(configPath?: string, customExtends?: string[]): Promise<Config>;
|
|
1
|
+
import { Config, RawConfig } from './config';
|
|
2
|
+
export declare function loadConfig(configPath?: string | undefined, customExtends?: string[]): Promise<Config>;
|
|
3
3
|
export declare const CONFIG_FILE_NAMES: string[];
|
|
4
|
-
export declare function findConfig(): string | undefined;
|
|
4
|
+
export declare function findConfig(dir?: string): string | undefined;
|
|
5
|
+
export declare function getConfig(configPath?: string | undefined): Promise<RawConfig>;
|
package/lib/config/load.js
CHANGED
|
@@ -9,27 +9,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.findConfig = exports.CONFIG_FILE_NAMES = exports.loadConfig = void 0;
|
|
12
|
+
exports.getConfig = exports.findConfig = exports.CONFIG_FILE_NAMES = exports.loadConfig = void 0;
|
|
13
13
|
const fs = require("fs");
|
|
14
|
+
const path = require("path");
|
|
14
15
|
const redocly_1 = require("../redocly");
|
|
15
16
|
const utils_1 = require("../utils");
|
|
16
17
|
const config_1 = require("./config");
|
|
17
18
|
const builtIn_1 = require("./builtIn");
|
|
18
|
-
function loadConfig(configPath, customExtends) {
|
|
19
|
+
function loadConfig(configPath = findConfig(), customExtends) {
|
|
19
20
|
var _a, _b;
|
|
20
21
|
return __awaiter(this, void 0, void 0, function* () {
|
|
21
|
-
|
|
22
|
-
configPath = findConfig();
|
|
23
|
-
}
|
|
24
|
-
let rawConfig = {};
|
|
25
|
-
if (configPath !== undefined) {
|
|
26
|
-
try {
|
|
27
|
-
rawConfig = (yield utils_1.loadYaml(configPath));
|
|
28
|
-
}
|
|
29
|
-
catch (e) {
|
|
30
|
-
throw new Error(`Error parsing config file at \`${configPath}\`: ${e.message}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
22
|
+
const rawConfig = yield getConfig(configPath);
|
|
33
23
|
if (customExtends !== undefined) {
|
|
34
24
|
rawConfig.lint = rawConfig.lint || {};
|
|
35
25
|
rawConfig.lint.extends = customExtends;
|
|
@@ -64,10 +54,12 @@ function loadConfig(configPath, customExtends) {
|
|
|
64
54
|
}
|
|
65
55
|
exports.loadConfig = loadConfig;
|
|
66
56
|
exports.CONFIG_FILE_NAMES = ['redocly.yaml', 'redocly.yml', '.redocly.yaml', '.redocly.yml'];
|
|
67
|
-
function findConfig() {
|
|
57
|
+
function findConfig(dir) {
|
|
68
58
|
if (!fs.hasOwnProperty('existsSync'))
|
|
69
59
|
return;
|
|
70
|
-
const existingConfigFiles = exports.CONFIG_FILE_NAMES
|
|
60
|
+
const existingConfigFiles = exports.CONFIG_FILE_NAMES
|
|
61
|
+
.map(name => dir ? path.resolve(dir, name) : name)
|
|
62
|
+
.filter(fs.existsSync);
|
|
71
63
|
if (existingConfigFiles.length > 1) {
|
|
72
64
|
throw new Error(`
|
|
73
65
|
Multiple configuration files are not allowed.
|
|
@@ -78,3 +70,17 @@ function findConfig() {
|
|
|
78
70
|
return existingConfigFiles[0];
|
|
79
71
|
}
|
|
80
72
|
exports.findConfig = findConfig;
|
|
73
|
+
function getConfig(configPath = findConfig()) {
|
|
74
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
75
|
+
if (!configPath)
|
|
76
|
+
return {};
|
|
77
|
+
try {
|
|
78
|
+
const rawConfig = ((yield utils_1.loadYaml(configPath)) || {});
|
|
79
|
+
return config_1.transformConfig(rawConfig);
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
throw new Error(`Error parsing config file at '${configPath}': ${e.message}`);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
exports.getConfig = getConfig;
|
package/lib/format/codeframes.js
CHANGED
|
@@ -142,9 +142,12 @@ function getAstNodeByPointer(root, pointer, reportOnKey) {
|
|
|
142
142
|
for (const key of pointerSegments) {
|
|
143
143
|
if (currentNode.kind === yamlAst.Kind.MAP) {
|
|
144
144
|
const mapping = currentNode.mappings.find((m) => m.key.value === key);
|
|
145
|
-
if (!
|
|
145
|
+
if (!mapping)
|
|
146
146
|
break;
|
|
147
|
-
currentNode = mapping
|
|
147
|
+
currentNode = mapping;
|
|
148
|
+
if (!(mapping === null || mapping === void 0 ? void 0 : mapping.value))
|
|
149
|
+
break; // If node has value - return value, if not - return node itself
|
|
150
|
+
currentNode = mapping.value;
|
|
148
151
|
}
|
|
149
152
|
else if (currentNode.kind === yamlAst.Kind.SEQ) {
|
|
150
153
|
const elem = currentNode.items[parseInt(key, 10)];
|
package/lib/index.d.ts
CHANGED
|
@@ -3,13 +3,13 @@ export { Oas3_1Types } from './types/oas3_1';
|
|
|
3
3
|
export { Oas3Types } from './types/oas3';
|
|
4
4
|
export { Oas2Types } from './types/oas2';
|
|
5
5
|
export { ConfigTypes } from './types/redocly-yaml';
|
|
6
|
-
export { Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3Schema, Oas3_1Schema, Oas3Tag, Oas3_1Webhooks, Referenced } from './typings/openapi';
|
|
6
|
+
export { Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3Schema, Oas3_1Schema, Oas3Tag, Oas3_1Webhooks, Referenced, } from './typings/openapi';
|
|
7
7
|
export { Oas2Definition } from './typings/swagger';
|
|
8
8
|
export { StatsAccumulator, StatsName } from './typings/common';
|
|
9
9
|
export { normalizeTypes } from './types';
|
|
10
10
|
export { Stats } from './rules/other/stats';
|
|
11
|
-
export { Config, LintConfig, RawConfig, IGNORE_FILE, Region } from './config/config';
|
|
12
|
-
export { loadConfig, findConfig, CONFIG_FILE_NAMES } from './config/load';
|
|
11
|
+
export { Config, LintConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, } from './config/config';
|
|
12
|
+
export { loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES } from './config/load';
|
|
13
13
|
export { RedoclyClient, isRedoclyRegistryURL } from './redocly';
|
|
14
14
|
export { Source, BaseResolver, Document, resolveDocument, ResolveError, YamlParseError, makeDocumentFromString, } from './resolve';
|
|
15
15
|
export { parseYaml, stringifyYaml } from './js-yaml';
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.mapTypeToComponent = exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.isRef = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.isRedoclyRegistryURL = exports.RedoclyClient = exports.CONFIG_FILE_NAMES = exports.findConfig = exports.loadConfig = exports.IGNORE_FILE = exports.LintConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.slash = exports.readFileFromUrl = void 0;
|
|
3
|
+
exports.mapTypeToComponent = exports.bundleDocument = exports.bundle = exports.lintConfig = exports.lintFromString = exports.lintDocument = exports.validate = exports.lint = exports.getTotals = exports.formatProblems = exports.getLineColLocation = exports.getAstNodeByPointer = exports.walkDocument = exports.normalizeVisitors = exports.OasVersion = exports.openAPIMajor = exports.OasMajorVersion = exports.detectOpenAPI = exports.isRef = exports.unescapePointer = exports.stringifyYaml = exports.parseYaml = exports.makeDocumentFromString = exports.YamlParseError = exports.ResolveError = exports.resolveDocument = exports.BaseResolver = exports.Source = exports.isRedoclyRegistryURL = exports.RedoclyClient = exports.CONFIG_FILE_NAMES = exports.findConfig = exports.getConfig = exports.loadConfig = exports.transformConfig = exports.getMergedConfig = exports.IGNORE_FILE = exports.LintConfig = exports.Config = exports.Stats = exports.normalizeTypes = exports.ConfigTypes = exports.Oas2Types = exports.Oas3Types = exports.Oas3_1Types = exports.slash = exports.readFileFromUrl = void 0;
|
|
4
4
|
var utils_1 = require("./utils");
|
|
5
5
|
Object.defineProperty(exports, "readFileFromUrl", { enumerable: true, get: function () { return utils_1.readFileFromUrl; } });
|
|
6
6
|
Object.defineProperty(exports, "slash", { enumerable: true, get: function () { return utils_1.slash; } });
|
|
@@ -20,8 +20,11 @@ var config_1 = require("./config/config");
|
|
|
20
20
|
Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
|
|
21
21
|
Object.defineProperty(exports, "LintConfig", { enumerable: true, get: function () { return config_1.LintConfig; } });
|
|
22
22
|
Object.defineProperty(exports, "IGNORE_FILE", { enumerable: true, get: function () { return config_1.IGNORE_FILE; } });
|
|
23
|
+
Object.defineProperty(exports, "getMergedConfig", { enumerable: true, get: function () { return config_1.getMergedConfig; } });
|
|
24
|
+
Object.defineProperty(exports, "transformConfig", { enumerable: true, get: function () { return config_1.transformConfig; } });
|
|
23
25
|
var load_1 = require("./config/load");
|
|
24
26
|
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_1.loadConfig; } });
|
|
27
|
+
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return load_1.getConfig; } });
|
|
25
28
|
Object.defineProperty(exports, "findConfig", { enumerable: true, get: function () { return load_1.findConfig; } });
|
|
26
29
|
Object.defineProperty(exports, "CONFIG_FILE_NAMES", { enumerable: true, get: function () { return load_1.CONFIG_FILE_NAMES; } });
|
|
27
30
|
var redocly_1 = require("./redocly");
|
package/lib/redocly/index.d.ts
CHANGED
|
@@ -20,7 +20,10 @@ export declare class RedoclyClient {
|
|
|
20
20
|
isAuthorizedWithRedoclyByRegion(): Promise<boolean>;
|
|
21
21
|
isAuthorizedWithRedocly(): Promise<boolean>;
|
|
22
22
|
readCredentialsFile(credentialsPath: string): any;
|
|
23
|
-
verifyToken(accessToken: string, region: Region, verbose?: boolean): Promise<
|
|
23
|
+
verifyToken(accessToken: string, region: Region, verbose?: boolean): Promise<{
|
|
24
|
+
viewerId: string;
|
|
25
|
+
organizations: string[];
|
|
26
|
+
}>;
|
|
24
27
|
login(accessToken: string, verbose?: boolean): Promise<void>;
|
|
25
28
|
logout(): void;
|
|
26
29
|
}
|
package/lib/redocly/index.js
CHANGED
|
@@ -24,9 +24,7 @@ class RedoclyClient {
|
|
|
24
24
|
this.accessTokens = {};
|
|
25
25
|
this.region = this.loadRegion(region);
|
|
26
26
|
this.loadTokens();
|
|
27
|
-
this.domain = region
|
|
28
|
-
? config_1.DOMAINS[region]
|
|
29
|
-
: process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION];
|
|
27
|
+
this.domain = region ? config_1.DOMAINS[region] : process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION];
|
|
30
28
|
/*
|
|
31
29
|
* We can't use process.env here because it is replaced by a const in some client-side bundles,
|
|
32
30
|
* which breaks assignment.
|
|
@@ -73,8 +71,9 @@ class RedoclyClient {
|
|
|
73
71
|
const credentialsPath = path_1.resolve(os_1.homedir(), TOKEN_FILENAME);
|
|
74
72
|
const credentials = this.readCredentialsFile(credentialsPath);
|
|
75
73
|
if (utils_1.isNotEmptyObject(credentials)) {
|
|
76
|
-
this.setAccessTokens(Object.assign(Object.assign({}, credentials), (credentials.token &&
|
|
77
|
-
[this.region]
|
|
74
|
+
this.setAccessTokens(Object.assign(Object.assign({}, credentials), (credentials.token &&
|
|
75
|
+
!credentials[this.region] && {
|
|
76
|
+
[this.region]: credentials.token,
|
|
78
77
|
})));
|
|
79
78
|
}
|
|
80
79
|
if (process.env.REDOCLY_AUTHORIZATION) {
|
|
@@ -82,17 +81,17 @@ class RedoclyClient {
|
|
|
82
81
|
}
|
|
83
82
|
}
|
|
84
83
|
getAllTokens() {
|
|
85
|
-
return Object.entries(this.accessTokens)
|
|
84
|
+
return Object.entries(this.accessTokens)
|
|
85
|
+
.filter(([region]) => config_1.AVAILABLE_REGIONS.includes(region))
|
|
86
|
+
.map(([region, token]) => ({ region, token }));
|
|
86
87
|
}
|
|
87
88
|
getValidTokens() {
|
|
88
89
|
return __awaiter(this, void 0, void 0, function* () {
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return validTokens;
|
|
90
|
+
const allTokens = this.getAllTokens();
|
|
91
|
+
const verifiedTokens = yield Promise.allSettled(allTokens.map(({ token, region }) => this.verifyToken(token, region)));
|
|
92
|
+
return allTokens
|
|
93
|
+
.filter((_, index) => verifiedTokens[index].status === 'fulfilled')
|
|
94
|
+
.map(({ token, region }) => ({ token, region, valid: true }));
|
|
96
95
|
});
|
|
97
96
|
}
|
|
98
97
|
getTokens() {
|
|
@@ -102,10 +101,20 @@ class RedoclyClient {
|
|
|
102
101
|
}
|
|
103
102
|
isAuthorizedWithRedoclyByRegion() {
|
|
104
103
|
return __awaiter(this, void 0, void 0, function* () {
|
|
105
|
-
if (!this.hasTokens())
|
|
104
|
+
if (!this.hasTokens()) {
|
|
106
105
|
return false;
|
|
106
|
+
}
|
|
107
107
|
const accessToken = this.accessTokens[this.region];
|
|
108
|
-
|
|
108
|
+
if (!accessToken) {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
yield this.verifyToken(accessToken, this.region);
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
return false;
|
|
117
|
+
}
|
|
109
118
|
});
|
|
110
119
|
}
|
|
111
120
|
isAuthorizedWithRedocly() {
|
|
@@ -118,8 +127,6 @@ class RedoclyClient {
|
|
|
118
127
|
}
|
|
119
128
|
verifyToken(accessToken, region, verbose = false) {
|
|
120
129
|
return __awaiter(this, void 0, void 0, function* () {
|
|
121
|
-
if (!accessToken)
|
|
122
|
-
return false;
|
|
123
130
|
return this.registryApi.authStatus(accessToken, region, verbose);
|
|
124
131
|
});
|
|
125
132
|
}
|
|
@@ -127,8 +134,10 @@ class RedoclyClient {
|
|
|
127
134
|
return __awaiter(this, void 0, void 0, function* () {
|
|
128
135
|
const credentialsPath = path_1.resolve(os_1.homedir(), TOKEN_FILENAME);
|
|
129
136
|
process.stdout.write(colorette_1.gray('\n Logging in...\n'));
|
|
130
|
-
|
|
131
|
-
|
|
137
|
+
try {
|
|
138
|
+
yield this.verifyToken(accessToken, this.region, verbose);
|
|
139
|
+
}
|
|
140
|
+
catch (err) {
|
|
132
141
|
process.stdout.write(colorette_1.red('Authorization failed. Please check if you entered a valid API key.\n'));
|
|
133
142
|
process.exit(1);
|
|
134
143
|
}
|
|
@@ -8,7 +8,10 @@ export declare class RegistryApi {
|
|
|
8
8
|
getBaseUrl(region?: Region): string;
|
|
9
9
|
setAccessTokens(accessTokens: AccessTokens): this;
|
|
10
10
|
private request;
|
|
11
|
-
authStatus(accessToken: string, region: Region, verbose?: boolean): Promise<
|
|
11
|
+
authStatus(accessToken: string, region: Region, verbose?: boolean): Promise<{
|
|
12
|
+
viewerId: string;
|
|
13
|
+
organizations: string[];
|
|
14
|
+
}>;
|
|
12
15
|
prepareFileUpload({ organizationId, name, version, filesHash, filename, isUpsert, }: RegistryApiTypes.PrepareFileuploadParams): Promise<RegistryApiTypes.PrepareFileuploadOKResponse>;
|
|
13
16
|
pushApi({ organizationId, name, version, rootFilePath, filePaths, branch, isUpsert, }: RegistryApiTypes.PushApiParams): Promise<void>;
|
|
14
17
|
}
|
|
@@ -50,13 +50,13 @@ class RegistryApi {
|
|
|
50
50
|
return __awaiter(this, void 0, void 0, function* () {
|
|
51
51
|
try {
|
|
52
52
|
const response = yield this.request('', { headers: { authorization: accessToken } }, region);
|
|
53
|
-
return response.
|
|
53
|
+
return yield response.json();
|
|
54
54
|
}
|
|
55
55
|
catch (error) {
|
|
56
56
|
if (verbose) {
|
|
57
57
|
console.log(error);
|
|
58
58
|
}
|
|
59
|
-
|
|
59
|
+
throw error;
|
|
60
60
|
}
|
|
61
61
|
});
|
|
62
62
|
}
|
|
@@ -86,7 +86,7 @@ class RegistryApi {
|
|
|
86
86
|
method: 'PUT',
|
|
87
87
|
headers: {
|
|
88
88
|
'content-type': 'application/json',
|
|
89
|
-
authorization: this.accessToken
|
|
89
|
+
authorization: this.accessToken,
|
|
90
90
|
},
|
|
91
91
|
body: JSON.stringify({
|
|
92
92
|
rootFilePath,
|
|
@@ -4,9 +4,10 @@ exports.NoEmptyServers = void 0;
|
|
|
4
4
|
const NoEmptyServers = () => {
|
|
5
5
|
return {
|
|
6
6
|
DefinitionRoot(root, { report, location }) {
|
|
7
|
-
if (!root.servers) {
|
|
7
|
+
if (!root.hasOwnProperty('servers')) {
|
|
8
8
|
report({
|
|
9
9
|
message: 'Servers must be present.',
|
|
10
|
+
location: location.child(['openapi']).key()
|
|
10
11
|
});
|
|
11
12
|
return;
|
|
12
13
|
}
|
|
@@ -5,13 +5,22 @@ const _1 = require(".");
|
|
|
5
5
|
const utils_1 = require("../utils");
|
|
6
6
|
const ConfigRoot = {
|
|
7
7
|
properties: {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
8
|
+
organization: { type: 'string' },
|
|
9
|
+
apis: 'ConfigApis',
|
|
10
|
+
lint: 'RootConfigLint',
|
|
11
|
+
'features.openapi': 'ConfigReferenceDocs',
|
|
12
|
+
'features.mockServer': 'ConfigMockServer',
|
|
13
|
+
},
|
|
14
|
+
};
|
|
15
|
+
const ConfigApis = {
|
|
16
|
+
properties: {},
|
|
17
|
+
additionalProperties: 'ConfigApisProperties',
|
|
18
|
+
};
|
|
19
|
+
const ConfigApisProperties = {
|
|
20
|
+
properties: {
|
|
21
|
+
root: { type: 'string' },
|
|
13
22
|
lint: 'ConfigLint',
|
|
14
|
-
|
|
23
|
+
'features.openapi': 'ConfigReferenceDocs',
|
|
15
24
|
},
|
|
16
25
|
};
|
|
17
26
|
const ConfigHTTP = {
|
|
@@ -26,10 +35,6 @@ const ConfigHTTP = {
|
|
|
26
35
|
};
|
|
27
36
|
const ConfigLint = {
|
|
28
37
|
properties: {
|
|
29
|
-
plugins: {
|
|
30
|
-
type: 'array',
|
|
31
|
-
items: { type: 'string' },
|
|
32
|
-
},
|
|
33
38
|
extends: {
|
|
34
39
|
type: 'array',
|
|
35
40
|
items: {
|
|
@@ -56,6 +61,12 @@ const ConfigLint = {
|
|
|
56
61
|
},
|
|
57
62
|
},
|
|
58
63
|
};
|
|
64
|
+
const RootConfigLint = {
|
|
65
|
+
properties: Object.assign({ plugins: {
|
|
66
|
+
type: 'array',
|
|
67
|
+
items: { type: 'string' },
|
|
68
|
+
} }, ConfigLint.properties),
|
|
69
|
+
};
|
|
59
70
|
const ConfigLanguage = {
|
|
60
71
|
properties: {
|
|
61
72
|
label: { type: 'string' },
|
|
@@ -445,10 +456,20 @@ const ConfigReferenceDocs = {
|
|
|
445
456
|
},
|
|
446
457
|
additionalProperties: { type: 'string' },
|
|
447
458
|
};
|
|
459
|
+
const ConfigMockServer = {
|
|
460
|
+
properties: {
|
|
461
|
+
strictExamples: { type: 'boolean' },
|
|
462
|
+
errorIfForcedExampleNotFound: { type: 'boolean' },
|
|
463
|
+
},
|
|
464
|
+
};
|
|
448
465
|
exports.ConfigTypes = {
|
|
449
466
|
ConfigRoot,
|
|
467
|
+
ConfigApis,
|
|
468
|
+
ConfigApisProperties,
|
|
469
|
+
RootConfigLint,
|
|
450
470
|
ConfigLint,
|
|
451
471
|
ConfigReferenceDocs,
|
|
472
|
+
ConfigMockServer,
|
|
452
473
|
ConfigHTTP,
|
|
453
474
|
ConfigLanguage,
|
|
454
475
|
ConfigLabels,
|