@redocly/openapi-core
Advanced tools
Comparing version 1.0.0-beta.87 to 1.0.0-beta.88
@@ -88,2 +88,24 @@ import { outdent } from 'outdent'; | ||
it('should correctly fallback to the closest parent node if node value is null', () => { | ||
const loc = { | ||
reportOnKey: false, | ||
pointer: '#/servers', | ||
source: new Source( | ||
'foobar.yaml', | ||
outdent` | ||
openapi: 3.0.2 | ||
servers: | ||
info: | ||
license: | ||
name: MIT | ||
url: https://google.com | ||
`, | ||
), | ||
}; | ||
const preciseLocation = getLineColLocation(loc); | ||
expect(preciseLocation.start).toEqual({ line: 2, col: 1 }); | ||
expect(preciseLocation.end).toEqual({ line: 2, col: 9 }); | ||
}); | ||
it('should return first line for empty doc', () => { | ||
@@ -90,0 +112,0 @@ const loc = { |
@@ -81,4 +81,3 @@ import { OasVersion, Oas3PreprocessorsSet, OasMajorVersion, Oas3DecoratorsSet, Oas2RuleSet, Oas2PreprocessorsSet, Oas2DecoratorsSet, Oas3RuleSet } from '../oas-types'; | ||
export declare const AVAILABLE_REGIONS: Region[]; | ||
export declare type RawConfig = { | ||
referenceDocs?: any; | ||
export declare type DeprecatedRawConfig = { | ||
apiDefinitions?: Record<string, string>; | ||
@@ -88,3 +87,19 @@ lint?: LintRawConfig; | ||
region?: Region; | ||
referenceDocs?: any; | ||
}; | ||
export declare type Api = { | ||
root: string; | ||
lint?: LintRawConfig; | ||
'features.openapi'?: any; | ||
'features.mockServer'?: any; | ||
}; | ||
export declare type RawConfig = { | ||
apis?: Record<string, Api>; | ||
lint?: LintRawConfig; | ||
resolve?: RawResolveConfig; | ||
region?: Region; | ||
'features.openapi'?: any; | ||
'features.mockServer'?: any; | ||
organization?: string; | ||
}; | ||
export declare class LintConfig { | ||
@@ -129,4 +144,3 @@ rawConfig: LintRawConfig; | ||
configFile?: string | undefined; | ||
referenceDocs: any; | ||
apiDefinitions: Record<string, string>; | ||
apis: Record<string, Api>; | ||
lint: LintConfig; | ||
@@ -136,3 +150,31 @@ resolve: ResolveConfig; | ||
region?: Region; | ||
'features.openapi': Record<string, any>; | ||
'features.mockServer'?: Record<string, any>; | ||
organization?: string; | ||
constructor(rawConfig: RawConfig, configFile?: string | undefined); | ||
} | ||
export declare function getMergedConfig(config: Config, entrypointAlias?: string): Config; | ||
export declare function getMergedLintConfig(config: Config, entrypointAlias?: string): { | ||
rules: { | ||
[x: string]: RuleConfig; | ||
}; | ||
preprocessors: { | ||
[x: string]: PreprocessorConfig; | ||
}; | ||
decorators: { | ||
[x: string]: PreprocessorConfig; | ||
}; | ||
plugins?: (string | Plugin)[] | undefined; | ||
extends?: string[] | undefined; | ||
doNotResolveExamples?: boolean | undefined; | ||
oas2Rules?: Record<string, RuleConfig> | undefined; | ||
oas3_0Rules?: Record<string, RuleConfig> | undefined; | ||
oas3_1Rules?: Record<string, RuleConfig> | undefined; | ||
oas2Preprocessors?: Record<string, PreprocessorConfig> | undefined; | ||
oas3_0Preprocessors?: Record<string, PreprocessorConfig> | undefined; | ||
oas3_1Preprocessors?: Record<string, PreprocessorConfig> | undefined; | ||
oas2Decorators?: Record<string, PreprocessorConfig> | undefined; | ||
oas3_0Decorators?: Record<string, PreprocessorConfig> | undefined; | ||
oas3_1Decorators?: Record<string, PreprocessorConfig> | undefined; | ||
}; | ||
export declare function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): RawConfig; |
"use strict"; | ||
var __rest = (this && this.__rest) || function (s, e) { | ||
var t = {}; | ||
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | ||
t[p] = s[p]; | ||
if (s != null && typeof Object.getOwnPropertySymbols === "function") | ||
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | ||
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) | ||
t[p[i]] = s[p[i]]; | ||
} | ||
return t; | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.Config = exports.LintConfig = exports.AVAILABLE_REGIONS = exports.DOMAINS = exports.DEFAULT_REGION = exports.IGNORE_FILE = void 0; | ||
exports.transformConfig = exports.getMergedLintConfig = exports.getMergedConfig = exports.Config = exports.LintConfig = exports.AVAILABLE_REGIONS = exports.DOMAINS = exports.DEFAULT_REGION = exports.IGNORE_FILE = void 0; | ||
const fs = require("fs"); | ||
@@ -21,3 +32,2 @@ const path = require("path"); | ||
}; | ||
exports.AVAILABLE_REGIONS = Object.keys(exports.DOMAINS); | ||
// FIXME: temporary fix for our lab environments | ||
@@ -30,2 +40,3 @@ if (REDOCLY_DOMAIN === null || REDOCLY_DOMAIN === void 0 ? void 0 : REDOCLY_DOMAIN.endsWith('.redocly.host')) { | ||
} | ||
exports.AVAILABLE_REGIONS = Object.keys(exports.DOMAINS); | ||
class LintConfig { | ||
@@ -243,5 +254,6 @@ constructor(rawConfig, configFile) { | ||
this.configFile = configFile; | ||
this.apiDefinitions = rawConfig.apiDefinitions || {}; | ||
this.apis = rawConfig.apis || {}; | ||
this.lint = new LintConfig(rawConfig.lint || {}, configFile); | ||
this.referenceDocs = rawConfig.referenceDocs || {}; | ||
this['features.openapi'] = rawConfig['features.openapi'] || {}; | ||
this['features.mockServer'] = rawConfig['features.mockServer'] || {}; | ||
this.resolve = { | ||
@@ -254,2 +266,3 @@ http: { | ||
this.region = rawConfig.region; | ||
this.organization = rawConfig.organization; | ||
} | ||
@@ -405,1 +418,46 @@ } | ||
} | ||
function getMergedConfig(config, entrypointAlias) { | ||
var _a, _b; | ||
return entrypointAlias | ||
? 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']) })) | ||
: config; | ||
} | ||
exports.getMergedConfig = getMergedConfig; | ||
function getMergedLintConfig(config, entrypointAlias) { | ||
var _a, _b, _c, _d; | ||
const apiLint = entrypointAlias | ||
? (_a = config.apis[entrypointAlias]) === null || _a === void 0 ? void 0 : _a.lint | ||
: {}; | ||
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) }); | ||
return mergedLint; | ||
} | ||
exports.getMergedLintConfig = getMergedLintConfig; | ||
function transformApiDefinitionsToApis(apiDefinitions = {}) { | ||
let apis = {}; | ||
for (const [apiName, apiPath] of Object.entries(apiDefinitions)) { | ||
apis[apiName] = { root: apiPath }; | ||
} | ||
return apis; | ||
} | ||
function transformConfig(rawConfig) { | ||
if (rawConfig.apis && rawConfig.apiDefinitions) { | ||
throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n"); | ||
} | ||
if (rawConfig['features.openapi'] && rawConfig.referenceDocs) { | ||
throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n"); | ||
} | ||
const _a = rawConfig, { apiDefinitions, referenceDocs } = _a, rest = __rest(_a, ["apiDefinitions", "referenceDocs"]); | ||
// TODO: put links to the changelog and uncomment this after successful release of ReferenceDocs/Redoc, Portal and Workflows | ||
// if (apiDefinitions) { | ||
// process.stderr.write( | ||
// `The ${yellow('apiDefinitions')} field is deprecated. Use ${green('apis')} instead, see changelog: <link>\n` | ||
// ); | ||
// } | ||
// if (referenceDocs) { | ||
// process.stderr.write( | ||
// `The ${yellow('referenceDocs')} field is deprecated. Use ${green('features.openapi')} instead, see changelog: <link>\n` | ||
// ); | ||
// } | ||
return Object.assign({ 'features.openapi': referenceDocs, apis: transformApiDefinitionsToApis(apiDefinitions) }, rest); | ||
} | ||
exports.transformConfig = transformConfig; |
@@ -1,4 +0,5 @@ | ||
import { Config } from './config'; | ||
export declare function loadConfig(configPath?: string, customExtends?: string[]): Promise<Config>; | ||
import { Config, RawConfig } from './config'; | ||
export declare function loadConfig(configPath?: string | undefined, customExtends?: string[]): Promise<Config>; | ||
export declare const CONFIG_FILE_NAMES: string[]; | ||
export declare function findConfig(): string | undefined; | ||
export declare function findConfig(dir?: string): string | undefined; | ||
export declare function getConfig(configPath?: string | undefined): Promise<RawConfig>; |
@@ -12,4 +12,5 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.findConfig = exports.CONFIG_FILE_NAMES = exports.loadConfig = void 0; | ||
exports.getConfig = exports.findConfig = exports.CONFIG_FILE_NAMES = exports.loadConfig = void 0; | ||
const fs = require("fs"); | ||
const path = require("path"); | ||
const redocly_1 = require("../redocly"); | ||
@@ -19,17 +20,6 @@ const utils_1 = require("../utils"); | ||
const builtIn_1 = require("./builtIn"); | ||
function loadConfig(configPath, customExtends) { | ||
function loadConfig(configPath = findConfig(), customExtends) { | ||
var _a, _b; | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (configPath === undefined) { | ||
configPath = findConfig(); | ||
} | ||
let rawConfig = {}; | ||
if (configPath !== undefined) { | ||
try { | ||
rawConfig = (yield utils_1.loadYaml(configPath)); | ||
} | ||
catch (e) { | ||
throw new Error(`Error parsing config file at \`${configPath}\`: ${e.message}`); | ||
} | ||
} | ||
const rawConfig = yield getConfig(configPath); | ||
if (customExtends !== undefined) { | ||
@@ -69,6 +59,8 @@ rawConfig.lint = rawConfig.lint || {}; | ||
exports.CONFIG_FILE_NAMES = ['redocly.yaml', 'redocly.yml', '.redocly.yaml', '.redocly.yml']; | ||
function findConfig() { | ||
function findConfig(dir) { | ||
if (!fs.hasOwnProperty('existsSync')) | ||
return; | ||
const existingConfigFiles = exports.CONFIG_FILE_NAMES.map((name) => fs.existsSync(name) && name).filter(Boolean); | ||
const existingConfigFiles = exports.CONFIG_FILE_NAMES | ||
.map(name => dir ? path.resolve(dir, name) : name) | ||
.filter(fs.existsSync); | ||
if (existingConfigFiles.length > 1) { | ||
@@ -84,1 +76,15 @@ throw new Error(` | ||
exports.findConfig = findConfig; | ||
function getConfig(configPath = findConfig()) { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
if (!configPath) | ||
return {}; | ||
try { | ||
const rawConfig = (yield utils_1.loadYaml(configPath)); | ||
return config_1.transformConfig(rawConfig); | ||
} | ||
catch (e) { | ||
throw new Error(`Error parsing config file at '${configPath}': ${e.message}`); | ||
} | ||
}); | ||
} | ||
exports.getConfig = getConfig; |
@@ -145,5 +145,8 @@ "use strict"; | ||
const mapping = currentNode.mappings.find((m) => m.key.value === key); | ||
if (!mapping) | ||
break; | ||
currentNode = mapping; | ||
if (!(mapping === null || mapping === void 0 ? void 0 : mapping.value)) | ||
break; | ||
currentNode = mapping === null || mapping === void 0 ? void 0 : mapping.value; | ||
break; // If node has value - return value, if not - return node itself | ||
currentNode = mapping.value; | ||
} | ||
@@ -150,0 +153,0 @@ else if (currentNode.kind === yamlAst.Kind.SEQ) { |
@@ -6,3 +6,3 @@ export { BundleOutputFormat, readFileFromUrl, slash } from './utils'; | ||
export { ConfigTypes } from './types/redocly-yaml'; | ||
export { Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3Schema, Oas3_1Schema, Oas3Tag, Oas3_1Webhooks, Referenced } from './typings/openapi'; | ||
export { Oas3Definition, Oas3_1Definition, Oas3Components, Oas3PathItem, Oas3Paths, Oas3ComponentName, Oas3Schema, Oas3_1Schema, Oas3Tag, Oas3_1Webhooks, Referenced, } from './typings/openapi'; | ||
export { Oas2Definition } from './typings/swagger'; | ||
@@ -12,4 +12,4 @@ export { StatsAccumulator, StatsName } from './typings/common'; | ||
export { Stats } from './rules/other/stats'; | ||
export { Config, LintConfig, RawConfig, IGNORE_FILE, Region } from './config/config'; | ||
export { loadConfig, findConfig, CONFIG_FILE_NAMES } from './config/load'; | ||
export { Config, LintConfig, RawConfig, IGNORE_FILE, Region, getMergedConfig, transformConfig, } from './config/config'; | ||
export { loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES } from './config/load'; | ||
export { RedoclyClient, isRedoclyRegistryURL } from './redocly'; | ||
@@ -16,0 +16,0 @@ export { Source, BaseResolver, Document, resolveDocument, ResolveError, YamlParseError, makeDocumentFromString, } from './resolve'; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
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; | ||
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; | ||
var utils_1 = require("./utils"); | ||
@@ -23,4 +23,7 @@ Object.defineProperty(exports, "readFileFromUrl", { enumerable: true, get: function () { return utils_1.readFileFromUrl; } }); | ||
Object.defineProperty(exports, "IGNORE_FILE", { enumerable: true, get: function () { return config_1.IGNORE_FILE; } }); | ||
Object.defineProperty(exports, "getMergedConfig", { enumerable: true, get: function () { return config_1.getMergedConfig; } }); | ||
Object.defineProperty(exports, "transformConfig", { enumerable: true, get: function () { return config_1.transformConfig; } }); | ||
var load_1 = require("./config/load"); | ||
Object.defineProperty(exports, "loadConfig", { enumerable: true, get: function () { return load_1.loadConfig; } }); | ||
Object.defineProperty(exports, "getConfig", { enumerable: true, get: function () { return load_1.getConfig; } }); | ||
Object.defineProperty(exports, "findConfig", { enumerable: true, get: function () { return load_1.findConfig; } }); | ||
@@ -27,0 +30,0 @@ Object.defineProperty(exports, "CONFIG_FILE_NAMES", { enumerable: true, get: function () { return load_1.CONFIG_FILE_NAMES; } }); |
@@ -7,5 +7,6 @@ "use strict"; | ||
DefinitionRoot(root, { report, location }) { | ||
if (!root.servers) { | ||
if (!root.hasOwnProperty('servers')) { | ||
report({ | ||
message: 'Servers must be present.', | ||
location: location.child(['openapi']).key() | ||
}); | ||
@@ -12,0 +13,0 @@ return; |
{ | ||
"name": "@redocly/openapi-core", | ||
"version": "1.0.0-beta.87", | ||
"version": "1.0.0-beta.88", | ||
"description": "", | ||
@@ -5,0 +5,0 @@ "main": "lib/index.js", |
@@ -5,2 +5,3 @@ import { loadConfig, findConfig } from '../load'; | ||
const fs = require('fs'); | ||
const path = require('path'); | ||
@@ -70,2 +71,8 @@ describe('loadConfig', () => { | ||
}); | ||
it('should find a nested config ', async () => { | ||
jest.spyOn(fs, 'existsSync').mockImplementation((name) => name === 'dir/redocly.yaml'); | ||
jest.spyOn(path, 'resolve').mockImplementationOnce((dir, name) => `${dir}/${name}`); | ||
const configName = findConfig('dir'); | ||
expect(configName).toStrictEqual('dir/redocly.yaml'); | ||
}); | ||
}); |
@@ -5,6 +5,4 @@ import * as fs from 'fs'; | ||
import { red, blue } from 'colorette'; | ||
import { parseYaml, stringifyYaml } from '../js-yaml'; | ||
import { notUndefined, slash } from '../utils'; | ||
import { | ||
@@ -20,5 +18,3 @@ OasVersion, | ||
} from '../oas-types'; | ||
import { ProblemSeverity, NormalizedProblem } from '../walk'; | ||
import recommended from './recommended'; | ||
@@ -135,3 +131,2 @@ import { NodeType } from '../types'; | ||
}; | ||
export const AVAILABLE_REGIONS = Object.keys(DOMAINS) as Region[]; | ||
@@ -145,5 +140,5 @@ // FIXME: temporary fix for our lab environments | ||
} | ||
export const AVAILABLE_REGIONS = Object.keys(DOMAINS) as Region[]; | ||
export type RawConfig = { | ||
referenceDocs?: any; | ||
export type DeprecatedRawConfig = { | ||
apiDefinitions?: Record<string, string>; | ||
@@ -153,4 +148,22 @@ lint?: LintRawConfig; | ||
region?: Region; | ||
referenceDocs?: any; | ||
} | ||
export type Api = { | ||
root: string; | ||
lint?: LintRawConfig; | ||
'features.openapi'?: any; | ||
'features.mockServer'?: any; | ||
}; | ||
export type RawConfig = { | ||
apis?: Record<string, Api>; | ||
lint?: LintRawConfig; | ||
resolve?: RawResolveConfig; | ||
region?: Region; | ||
'features.openapi'?: any; | ||
'features.mockServer'?: any; | ||
organization?: string; | ||
}; | ||
export class LintConfig { | ||
@@ -406,4 +419,3 @@ plugins: Plugin[]; | ||
export class Config { | ||
referenceDocs: any; | ||
apiDefinitions: Record<string, string>; | ||
apis: Record<string, Api>; | ||
lint: LintConfig; | ||
@@ -413,6 +425,10 @@ resolve: ResolveConfig; | ||
region?: Region; | ||
'features.openapi': Record<string, any>; | ||
'features.mockServer'?: Record<string, any>; | ||
organization?: string; | ||
constructor(public rawConfig: RawConfig, public configFile?: string) { | ||
this.apiDefinitions = rawConfig.apiDefinitions || {}; | ||
this.apis = rawConfig.apis || {}; | ||
this.lint = new LintConfig(rawConfig.lint || {}, configFile); | ||
this.referenceDocs = rawConfig.referenceDocs || {}; | ||
this['features.openapi'] = rawConfig['features.openapi'] || {}; | ||
this['features.mockServer'] = rawConfig['features.mockServer'] || {}; | ||
this.resolve = { | ||
@@ -425,2 +441,3 @@ http: { | ||
this.region = rawConfig.region; | ||
this.organization = rawConfig.organization; | ||
} | ||
@@ -432,3 +449,2 @@ } | ||
const { pluginId, configName } = parsePresetName(presetName); | ||
const plugin = plugins.find((p) => p.id === pluginId); | ||
@@ -636,1 +652,70 @@ if (!plugin) { | ||
} | ||
export function getMergedConfig(config: Config, entrypointAlias?: string): Config { | ||
return entrypointAlias | ||
? new Config({ | ||
...config.rawConfig, | ||
lint: getMergedLintConfig(config, entrypointAlias), | ||
'features.openapi': { | ||
...config['features.openapi'], | ||
...config.apis[entrypointAlias]?.['features.openapi'], | ||
}, | ||
'features.mockServer': { | ||
...config['features.mockServer'], | ||
...config.apis[entrypointAlias]?.['features.mockServer'], | ||
}, | ||
// TODO: merge everything else here | ||
}) | ||
: config; | ||
} | ||
export function getMergedLintConfig( | ||
config: Config, | ||
entrypointAlias?: string | ||
) { | ||
const apiLint = entrypointAlias | ||
? config.apis[entrypointAlias]?.lint | ||
: {}; | ||
const mergedLint = { | ||
...config.rawConfig.lint, | ||
...apiLint, | ||
rules: { ...config.rawConfig.lint?.rules, ...apiLint?.rules }, | ||
preprocessors: { ...config.rawConfig.lint?.preprocessors, ...apiLint?.preprocessors }, | ||
decorators: { ...config.rawConfig.lint?.decorators, ...apiLint?.decorators }, | ||
}; | ||
return mergedLint; | ||
} | ||
function transformApiDefinitionsToApis(apiDefinitions: Record<string, string> = {}): Record<string, Api> { | ||
let apis: Record<string, Api> = {}; | ||
for (const [apiName, apiPath] of Object.entries(apiDefinitions)) { | ||
apis[apiName] = { root: apiPath }; | ||
} | ||
return apis; | ||
} | ||
export function transformConfig(rawConfig: DeprecatedRawConfig | RawConfig): RawConfig { | ||
if ((rawConfig as RawConfig).apis && (rawConfig as DeprecatedRawConfig).apiDefinitions) { | ||
throw new Error("Do not use 'apiDefinitions' field. Use 'apis' instead.\n"); | ||
} | ||
if ((rawConfig as RawConfig)['features.openapi'] && (rawConfig as DeprecatedRawConfig).referenceDocs) { | ||
throw new Error("Do not use 'referenceDocs' field. Use 'features.openapi' instead.\n"); | ||
} | ||
const { apiDefinitions, referenceDocs, ...rest } = rawConfig as DeprecatedRawConfig & RawConfig; | ||
// TODO: put links to the changelog and uncomment this after successful release of ReferenceDocs/Redoc, Portal and Workflows | ||
// if (apiDefinitions) { | ||
// process.stderr.write( | ||
// `The ${yellow('apiDefinitions')} field is deprecated. Use ${green('apis')} instead, see changelog: <link>\n` | ||
// ); | ||
// } | ||
// if (referenceDocs) { | ||
// process.stderr.write( | ||
// `The ${yellow('referenceDocs')} field is deprecated. Use ${green('features.openapi')} instead, see changelog: <link>\n` | ||
// ); | ||
// } | ||
return { | ||
'features.openapi': referenceDocs, | ||
apis: transformApiDefinitionsToApis(apiDefinitions), | ||
...rest, | ||
}; | ||
} |
import * as fs from 'fs'; | ||
import * as path from 'path'; | ||
import { RedoclyClient } from '../redocly'; | ||
import { loadYaml } from '../utils'; | ||
import { Config, DOMAINS, RawConfig, Region } from './config'; | ||
import { Config, DOMAINS, RawConfig, Region, transformConfig } from './config'; | ||
import { defaultPlugin } from './builtIn'; | ||
export async function loadConfig(configPath?: string, customExtends?: string[]): Promise<Config> { | ||
if (configPath === undefined) { | ||
configPath = findConfig(); | ||
} | ||
let rawConfig: RawConfig = {}; | ||
export async function loadConfig(configPath: string | undefined = findConfig(), customExtends?: string[]): Promise<Config> { | ||
const rawConfig = await getConfig(configPath); | ||
if (configPath !== undefined) { | ||
try { | ||
rawConfig = (await loadYaml(configPath)) as RawConfig; | ||
} catch (e) { | ||
throw new Error(`Error parsing config file at \`${configPath}\`: ${e.message}`); | ||
} | ||
} | ||
if (customExtends !== undefined) { | ||
@@ -51,3 +41,2 @@ rawConfig.lint = rawConfig.lint || {}; | ||
} | ||
return new Config( | ||
@@ -67,8 +56,7 @@ { | ||
export function findConfig(): string | undefined { | ||
export function findConfig(dir?: string): string | undefined { | ||
if (!fs.hasOwnProperty('existsSync')) return; | ||
const existingConfigFiles = CONFIG_FILE_NAMES.map((name) => fs.existsSync(name) && name).filter( | ||
Boolean, | ||
) as Array<string | never>; | ||
const existingConfigFiles = CONFIG_FILE_NAMES | ||
.map(name => dir ? path.resolve(dir, name) : name) | ||
.filter(fs.existsSync); | ||
if (existingConfigFiles.length > 1) { | ||
@@ -83,1 +71,11 @@ throw new Error(` | ||
} | ||
export async function getConfig(configPath: string | undefined = findConfig()) { | ||
if (!configPath) return {}; | ||
try { | ||
const rawConfig = (await loadYaml(configPath)) as RawConfig; | ||
return transformConfig(rawConfig); | ||
} catch (e) { | ||
throw new Error(`Error parsing config file at '${configPath}': ${e.message}`); | ||
} | ||
} |
@@ -186,4 +186,6 @@ import { gray, red, options as colorOptions } from 'colorette'; | ||
const mapping = currentNode.mappings.find((m) => m.key.value === key); | ||
if (!mapping?.value) break; | ||
currentNode = mapping?.value as YAMLNode; | ||
if (!mapping) break; | ||
currentNode = mapping as YAMLNode; | ||
if (!mapping?.value) break; // If node has value - return value, if not - return node itself | ||
currentNode = mapping.value as YAMLNode; | ||
} else if (currentNode.kind === yamlAst.Kind.SEQ) { | ||
@@ -190,0 +192,0 @@ const elem = currentNode.items[parseInt(key, 10)] as YAMLNode; |
@@ -17,3 +17,3 @@ export { BundleOutputFormat, readFileFromUrl, slash } from './utils'; | ||
Oas3_1Webhooks, | ||
Referenced | ||
Referenced, | ||
} from './typings/openapi'; | ||
@@ -25,5 +25,13 @@ export { Oas2Definition } from './typings/swagger'; | ||
export { Config, LintConfig, RawConfig, IGNORE_FILE, Region } from './config/config'; | ||
export { | ||
Config, | ||
LintConfig, | ||
RawConfig, | ||
IGNORE_FILE, | ||
Region, | ||
getMergedConfig, | ||
transformConfig, | ||
} from './config/config'; | ||
export { loadConfig, findConfig, CONFIG_FILE_NAMES } from './config/load'; | ||
export { loadConfig, getConfig, findConfig, CONFIG_FILE_NAMES } from './config/load'; | ||
export { RedoclyClient, isRedoclyRegistryURL } from './redocly'; | ||
@@ -30,0 +38,0 @@ |
@@ -195,4 +195,4 @@ import { outdent } from 'outdent'; | ||
Object { | ||
"pointer": "#/", | ||
"reportOnKey": false, | ||
"pointer": "#/openapi", | ||
"reportOnKey": true, | ||
"source": "foobar.yaml", | ||
@@ -263,4 +263,4 @@ }, | ||
Object { | ||
"pointer": "#/", | ||
"reportOnKey": false, | ||
"pointer": "#/openapi", | ||
"reportOnKey": true, | ||
"source": "foobar.yaml", | ||
@@ -267,0 +267,0 @@ }, |
@@ -6,5 +6,6 @@ import { Oas3Rule } from '../../visitors'; | ||
DefinitionRoot(root, { report, location }) { | ||
if (!root.servers) { | ||
if (!root.hasOwnProperty('servers')) { | ||
report({ | ||
message: 'Servers must be present.', | ||
location: location.child(['openapi']).key() | ||
}); | ||
@@ -11,0 +12,0 @@ return; |
@@ -31,3 +31,2 @@ import * as fs from 'fs'; | ||
const contents = await fs.promises.readFile(filename, 'utf-8'); | ||
return parseYaml(contents); | ||
@@ -34,0 +33,0 @@ } |
Sorry, the diff of this file is not supported yet
2002521
25832