@redocly/openapi-core 1.0.0-beta.85 → 1.0.0-beta.88

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.
@@ -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,
@@ -44,7 +44,7 @@ export const yamlSerializer = {
44
44
  },
45
45
  };
46
46
 
47
- export function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin>) {
47
+ export function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin>, version: string = 'oas3') {
48
48
  const rulesConf: Record<string, RuleConfig> = {};
49
49
  const ruleId = 'test';
50
50
  Object.keys(rules).forEach((name) => {
@@ -56,7 +56,7 @@ export function makeConfigForRuleset(rules: Oas3RuleSet, plugin?: Partial<Plugin
56
56
  {
57
57
  ...plugin,
58
58
  id: ruleId,
59
- rules: { oas3: rules },
59
+ rules: { [version]: rules },
60
60
  },
61
61
  ],
62
62
  extends: [],
@@ -143,6 +143,90 @@ describe('walk order', () => {
143
143
  `);
144
144
  });
145
145
 
146
+ it('should run nested visitors correctly oas2', async () => {
147
+ const calls: string[] = [];
148
+
149
+ const testRuleSet: Oas3RuleSet = {
150
+ test: jest.fn(() => {
151
+ return {
152
+ Operation: {
153
+ enter: jest.fn((op) => calls.push(`enter operation: ${op.operationId}`)),
154
+ leave: jest.fn((op) => calls.push(`leave operation: ${op.operationId}`)),
155
+ Parameter: {
156
+ enter: jest.fn((param, _ctx, parents) =>
157
+ calls.push(
158
+ `enter operation ${parents.Operation.operationId} > param ${param.name}`,
159
+ ),
160
+ ),
161
+ leave: jest.fn((param, _ctx, parents) =>
162
+ calls.push(
163
+ `leave operation ${parents.Operation.operationId} > param ${param.name}`,
164
+ ),
165
+ ),
166
+ },
167
+ },
168
+ Parameter: {
169
+ enter: jest.fn((param) => calls.push(`enter param ${param.name}`)),
170
+ leave: jest.fn((param) => calls.push(`leave param ${param.name}`)),
171
+ },
172
+ };
173
+ }),
174
+ };
175
+
176
+ const document = parseYamlToDocument(
177
+ outdent`
178
+ swagger: "2.0"
179
+ info:
180
+ contact: {}
181
+ license: {}
182
+ paths:
183
+ /pet:
184
+ parameters:
185
+ - name: path-param
186
+ get:
187
+ operationId: get
188
+ parameters:
189
+ - name: get_a
190
+ - name: get_b
191
+ post:
192
+ operationId: post
193
+ parameters:
194
+ - name: post_a
195
+
196
+ `,
197
+ '',
198
+ );
199
+
200
+ await lintDocument({
201
+ externalRefResolver: new BaseResolver(),
202
+ document,
203
+ config: makeConfigForRuleset(testRuleSet, undefined, 'oas2'),
204
+ });
205
+
206
+ expect(calls).toMatchInlineSnapshot(`
207
+ Array [
208
+ "enter param path-param",
209
+ "leave param path-param",
210
+ "enter operation: get",
211
+ "enter operation get > param get_a",
212
+ "enter param get_a",
213
+ "leave param get_a",
214
+ "leave operation get > param get_a",
215
+ "enter operation get > param get_b",
216
+ "enter param get_b",
217
+ "leave param get_b",
218
+ "leave operation get > param get_b",
219
+ "leave operation: get",
220
+ "enter operation: post",
221
+ "enter operation post > param post_a",
222
+ "enter param post_a",
223
+ "leave param post_a",
224
+ "leave operation post > param post_a",
225
+ "leave operation: post",
226
+ ]
227
+ `);
228
+ });
229
+
146
230
  it('should resolve refs', async () => {
147
231
  const calls: string[] = [];
148
232
 
package/lib/bundle.js CHANGED
@@ -161,6 +161,7 @@ function makeBundleVisitor(version, dereference, skipRedoclyRegistryRefs, rootDo
161
161
  !dereference) {
162
162
  return;
163
163
  }
164
+ // do not bundle registry URL before push, otherwise we can't record dependencies
164
165
  if (skipRedoclyRegistryRefs && redocly_1.isRedoclyRegistryURL(node.$ref)) {
165
166
  return;
166
167
  }
@@ -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 RawConfig = {
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?: any;
87
+ };
88
+ export declare type Api = {
89
+ root: string;
90
+ lint?: LintRawConfig;
91
+ 'features.openapi'?: any;
92
+ 'features.mockServer'?: any;
93
+ };
94
+ export declare type RawConfig = {
95
+ apis?: Record<string, Api>;
96
+ lint?: LintRawConfig;
97
+ resolve?: RawResolveConfig;
98
+ region?: Region;
99
+ 'features.openapi'?: any;
100
+ 'features.mockServer'?: 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
- referenceDocs: any;
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
+ plugins?: (string | Plugin)[] | undefined;
164
+ extends?: string[] | undefined;
165
+ doNotResolveExamples?: boolean | undefined;
166
+ oas2Rules?: Record<string, RuleConfig> | undefined;
167
+ oas3_0Rules?: Record<string, RuleConfig> | undefined;
168
+ oas3_1Rules?: Record<string, RuleConfig> | undefined;
169
+ oas2Preprocessors?: Record<string, PreprocessorConfig> | undefined;
170
+ oas3_0Preprocessors?: Record<string, PreprocessorConfig> | undefined;
171
+ oas3_1Preprocessors?: Record<string, PreprocessorConfig> | undefined;
172
+ oas2Decorators?: Record<string, PreprocessorConfig> | undefined;
173
+ oas3_0Decorators?: Record<string, PreprocessorConfig> | undefined;
174
+ oas3_1Decorators?: Record<string, PreprocessorConfig> | undefined;
175
+ };
176
+ export declare function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): RawConfig;
@@ -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");
@@ -15,10 +26,9 @@ const IGNORE_BANNER = `# This file instructs Redocly's linter to ignore the rule
15
26
  exports.DEFAULT_REGION = 'us';
16
27
  const REDOCLY_DOMAIN = process.env.REDOCLY_DOMAIN;
17
28
  exports.DOMAINS = {
18
- us: 'redoc.ly',
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;
@@ -238,9 +249,10 @@ class Config {
238
249
  var _a, _b, _c;
239
250
  this.rawConfig = rawConfig;
240
251
  this.configFile = configFile;
241
- this.apiDefinitions = rawConfig.apiDefinitions || {};
252
+ this.apis = rawConfig.apis || {};
242
253
  this.lint = new LintConfig(rawConfig.lint || {}, configFile);
243
- this.referenceDocs = rawConfig.referenceDocs || {};
254
+ this['features.openapi'] = rawConfig['features.openapi'] || {};
255
+ this['features.mockServer'] = rawConfig['features.mockServer'] || {};
244
256
  this.resolve = {
245
257
  http: {
246
258
  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 +260,7 @@ class Config {
248
260
  },
249
261
  };
250
262
  this.region = rawConfig.region;
263
+ this.organization = rawConfig.organization;
251
264
  }
252
265
  }
253
266
  exports.Config = Config;
@@ -398,3 +411,48 @@ function assignExisting(target, obj) {
398
411
  }
399
412
  }
400
413
  }
414
+ function getMergedConfig(config, entrypointAlias) {
415
+ var _a, _b;
416
+ return entrypointAlias
417
+ ? 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']) }))
418
+ : config;
419
+ }
420
+ exports.getMergedConfig = getMergedConfig;
421
+ function getMergedLintConfig(config, entrypointAlias) {
422
+ var _a, _b, _c, _d;
423
+ const apiLint = entrypointAlias
424
+ ? (_a = config.apis[entrypointAlias]) === null || _a === void 0 ? void 0 : _a.lint
425
+ : {};
426
+ 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) });
427
+ return mergedLint;
428
+ }
429
+ exports.getMergedLintConfig = getMergedLintConfig;
430
+ function transformApiDefinitionsToApis(apiDefinitions = {}) {
431
+ let apis = {};
432
+ for (const [apiName, apiPath] of Object.entries(apiDefinitions)) {
433
+ apis[apiName] = { root: apiPath };
434
+ }
435
+ return apis;
436
+ }
437
+ function transformConfig(rawConfig) {
438
+ if (rawConfig.apis && rawConfig.apiDefinitions) {
439
+ throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n");
440
+ }
441
+ if (rawConfig['features.openapi'] && rawConfig.referenceDocs) {
442
+ throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n");
443
+ }
444
+ const _a = rawConfig, { apiDefinitions, referenceDocs } = _a, rest = __rest(_a, ["apiDefinitions", "referenceDocs"]);
445
+ // TODO: put links to the changelog and uncomment this after successful release of ReferenceDocs/Redoc, Portal and Workflows
446
+ // if (apiDefinitions) {
447
+ // process.stderr.write(
448
+ // `The ${yellow('apiDefinitions')} field is deprecated. Use ${green('apis')} instead, see changelog: <link>\n`
449
+ // );
450
+ // }
451
+ // if (referenceDocs) {
452
+ // process.stderr.write(
453
+ // `The ${yellow('referenceDocs')} field is deprecated. Use ${green('features.openapi')} instead, see changelog: <link>\n`
454
+ // );
455
+ // }
456
+ return Object.assign({ 'features.openapi': referenceDocs, apis: transformApiDefinitionsToApis(apiDefinitions) }, rest);
457
+ }
458
+ exports.transformConfig = transformConfig;
@@ -1,2 +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
+ export declare const CONFIG_FILE_NAMES: string[];
4
+ export declare function findConfig(dir?: string): string | undefined;
5
+ export declare function getConfig(configPath?: string | undefined): Promise<RawConfig>;
@@ -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.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
- if (configPath === undefined) {
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;
@@ -52,7 +42,7 @@ function loadConfig(configPath, customExtends) {
52
42
  },
53
43
  //support redocly.com domain for future compatibility
54
44
  ...(item.region === 'us' ? [{
55
- matches: `https://api.redocly.com/registry/**`,
45
+ matches: `https://api.redoc.ly/registry/**`,
56
46
  name: 'Authorization',
57
47
  envVariable: undefined,
58
48
  value: item.token,
@@ -63,12 +53,34 @@ function loadConfig(configPath, customExtends) {
63
53
  });
64
54
  }
65
55
  exports.loadConfig = loadConfig;
66
- function findConfig() {
67
- if (fs.existsSync('.redocly.yaml')) {
68
- return '.redocly.yaml';
69
- }
70
- else if (fs.existsSync('.redocly.yml')) {
71
- return '.redocly.yml';
56
+ exports.CONFIG_FILE_NAMES = ['redocly.yaml', 'redocly.yml', '.redocly.yaml', '.redocly.yml'];
57
+ function findConfig(dir) {
58
+ if (!fs.hasOwnProperty('existsSync'))
59
+ return;
60
+ const existingConfigFiles = exports.CONFIG_FILE_NAMES
61
+ .map(name => dir ? path.resolve(dir, name) : name)
62
+ .filter(fs.existsSync);
63
+ if (existingConfigFiles.length > 1) {
64
+ throw new Error(`
65
+ Multiple configuration files are not allowed.
66
+ Found the following files: ${existingConfigFiles.join(', ')}.
67
+ Please use 'redocly.yaml' instead.
68
+ `);
72
69
  }
73
- return undefined;
70
+ return existingConfigFiles[0];
71
+ }
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
+ });
74
85
  }
86
+ exports.getConfig = getConfig;
@@ -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 (!(mapping === null || mapping === void 0 ? void 0 : mapping.value))
145
+ if (!mapping)
146
146
  break;
147
- currentNode = mapping === null || mapping === void 0 ? void 0 : mapping.value;
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,14 +3,14 @@ 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 } from './config/load';
13
- export { RedoclyClient } from './redocly';
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
+ 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';
16
16
  export { unescapePointer, isRef } from './ref-utils';
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.RedoclyClient = 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,10 +20,16 @@ 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; } });
28
+ Object.defineProperty(exports, "findConfig", { enumerable: true, get: function () { return load_1.findConfig; } });
29
+ Object.defineProperty(exports, "CONFIG_FILE_NAMES", { enumerable: true, get: function () { return load_1.CONFIG_FILE_NAMES; } });
25
30
  var redocly_1 = require("./redocly");
26
31
  Object.defineProperty(exports, "RedoclyClient", { enumerable: true, get: function () { return redocly_1.RedoclyClient; } });
32
+ Object.defineProperty(exports, "isRedoclyRegistryURL", { enumerable: true, get: function () { return redocly_1.isRedoclyRegistryURL; } });
27
33
  var resolve_1 = require("./resolve");
28
34
  Object.defineProperty(exports, "Source", { enumerable: true, get: function () { return resolve_1.Source; } });
29
35
  Object.defineProperty(exports, "BaseResolver", { enumerable: true, get: function () { return resolve_1.BaseResolver; } });
@@ -18,6 +18,7 @@ const registry_api_1 = require("./registry-api");
18
18
  const config_1 = require("../config/config");
19
19
  const utils_1 = require("../utils");
20
20
  const TOKEN_FILENAME = '.redocly-config.json';
21
+ let REDOCLY_DOMAIN; // workaround for the isRedoclyRegistryURL, see more below
21
22
  class RedoclyClient {
22
23
  constructor(region) {
23
24
  this.accessTokens = {};
@@ -26,6 +27,11 @@ class RedoclyClient {
26
27
  this.domain = region
27
28
  ? config_1.DOMAINS[region]
28
29
  : process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION];
30
+ /*
31
+ * We can't use process.env here because it is replaced by a const in some client-side bundles,
32
+ * which breaks assignment.
33
+ */
34
+ REDOCLY_DOMAIN = this.domain; // isRedoclyRegistryURL depends on the value to be set
29
35
  this.registryApi = new registry_api_1.RegistryApi(this.accessTokens, this.region);
30
36
  }
31
37
  loadRegion(region) {
@@ -143,17 +149,12 @@ class RedoclyClient {
143
149
  }
144
150
  exports.RedoclyClient = RedoclyClient;
145
151
  function isRedoclyRegistryURL(link) {
146
- const domain = process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION];
147
- if (!link.startsWith(`https://api.${domain}/registry/`))
148
- return false;
149
- const registryPath = link.replace(`https://api.${domain}/registry/`, '');
150
- const pathParts = registryPath.split('/');
151
- // we can be sure, that there is job UUID present
152
- // (org, definition, version, bundle, branch, job, "openapi.yaml" 🤦‍♂️)
153
- // so skip this link.
154
- // FIXME
155
- if (pathParts.length === 7)
152
+ const domain = REDOCLY_DOMAIN || process.env.REDOCLY_DOMAIN || config_1.DOMAINS[config_1.DEFAULT_REGION];
153
+ const legacyDomain = domain === 'redocly.com' ? 'redoc.ly' : domain;
154
+ if (!link.startsWith(`https://api.${domain}/registry/`) &&
155
+ !link.startsWith(`https://api.${legacyDomain}/registry/`)) {
156
156
  return false;
157
+ }
157
158
  return true;
158
159
  }
159
160
  exports.isRedoclyRegistryURL = isRedoclyRegistryURL;
@@ -8,7 +8,7 @@ const utils_2 = require("../../utils");
8
8
  const OasSpec = () => {
9
9
  return {
10
10
  any(node, { report, type, location, key, resolve, ignoreNextVisitorsOnNode }) {
11
- var _a, _b, _c;
11
+ var _a, _b, _c, _d;
12
12
  const nodeType = utils_1.oasTypeOf(node);
13
13
  if (type.items) {
14
14
  if (nodeType !== 'array') {
@@ -59,7 +59,7 @@ const OasSpec = () => {
59
59
  }
60
60
  if (!hasProperty)
61
61
  report({
62
- message: 'Must contain at least one of the following fields: path, components, webhooks.',
62
+ message: `Must contain at least one of the following fields: ${(_b = type.requiredOneOf) === null || _b === void 0 ? void 0 : _b.join(', ')}.`,
63
63
  location: [{ reportOnKey: true }],
64
64
  });
65
65
  }
@@ -109,8 +109,8 @@ const OasSpec = () => {
109
109
  location: propLocation,
110
110
  });
111
111
  }
112
- else if (propValueType === 'array' && ((_b = propSchema.items) === null || _b === void 0 ? void 0 : _b.type)) {
113
- const itemsType = (_c = propSchema.items) === null || _c === void 0 ? void 0 : _c.type;
112
+ else if (propValueType === 'array' && ((_c = propSchema.items) === null || _c === void 0 ? void 0 : _c.type)) {
113
+ const itemsType = (_d = propSchema.items) === null || _d === void 0 ? void 0 : _d.type;
114
114
  for (let i = 0; i < propValue.length; i++) {
115
115
  const item = propValue[i];
116
116
  if (!utils_1.matchesJsonSchemaType(item, itemsType, false)) {
@@ -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
  }
package/lib/types/oas2.js CHANGED
@@ -55,6 +55,7 @@ const PathMap = {
55
55
  const PathItem = {
56
56
  properties: {
57
57
  $ref: { type: 'string' },
58
+ parameters: _1.listOf('Parameter'),
58
59
  get: 'Operation',
59
60
  put: 'Operation',
60
61
  post: 'Operation',
@@ -62,7 +63,6 @@ const PathItem = {
62
63
  options: 'Operation',
63
64
  head: 'Operation',
64
65
  patch: 'Operation',
65
- parameters: _1.listOf('Parameter'),
66
66
  },
67
67
  };
68
68
  const Operation = {
package/lib/types/oas3.js CHANGED
@@ -125,6 +125,7 @@ const Parameter = {
125
125
  content: 'MediaTypeMap',
126
126
  },
127
127
  required: ['name', 'in'],
128
+ requiredOneOf: ['schema', 'content'],
128
129
  };
129
130
  const Callback = {
130
131
  properties: {},
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@redocly/openapi-core",
3
- "version": "1.0.0-beta.85",
3
+ "version": "1.0.0-beta.88",
4
4
  "description": "",
5
5
  "main": "lib/index.js",
6
6
  "engines": {
package/src/bundle.ts CHANGED
@@ -218,6 +218,7 @@ function makeBundleVisitor(
218
218
  return;
219
219
  }
220
220
 
221
+ // do not bundle registry URL before push, otherwise we can't record dependencies
221
222
  if (skipRedoclyRegistryRefs && isRedoclyRegistryURL(node.$ref)) {
222
223
  return;
223
224
  }