@redocly/openapi-core
Version:
See https://github.com/Redocly/redocly-cli
179 lines (157 loc) • 5.17 kB
text/typescript
import { Oas2Types } from './types/oas2';
import { Oas3Types } from './types/oas3';
import { Oas3_1Types } from './types/oas3_1';
import { AsyncApi2Types } from './types/asyncapi2';
import { AsyncApi3Types } from './types/asyncapi3';
import { Arazzo1Types } from './types/arazzo';
import { Overlay1Types } from './types/overlay';
import { isPlainObject } from './utils';
import { VERSION_PATTERN } from './typings/arazzo';
import type {
BuiltInAsync2RuleId,
BuiltInAsync3RuleId,
BuiltInArazzo1RuleId,
BuiltInOAS2RuleId,
BuiltInOAS3RuleId,
BuiltInOverlay1RuleId,
} from './types/redocly-yaml';
import type {
Oas3Rule,
Oas3Preprocessor,
Oas2Rule,
Oas2Preprocessor,
Async2Preprocessor,
Async2Rule,
Async3Preprocessor,
Async3Rule,
Arazzo1Preprocessor,
Arazzo1Rule,
Overlay1Preprocessor,
Overlay1Rule,
} from './visitors';
export enum SpecVersion {
OAS2 = 'oas2',
OAS3_0 = 'oas3_0',
OAS3_1 = 'oas3_1',
Async2 = 'async2',
Async3 = 'async3',
Arazzo1 = 'arazzo1',
Overlay1 = 'overlay1',
}
export enum SpecMajorVersion {
OAS2 = 'oas2',
OAS3 = 'oas3',
Async2 = 'async2',
Async3 = 'async3',
Arazzo1 = 'arazzo1',
Overlay1 = 'overlay1',
}
const typesMap = {
[SpecVersion.OAS2]: Oas2Types,
[SpecVersion.OAS3_0]: Oas3Types,
[SpecVersion.OAS3_1]: Oas3_1Types,
[SpecVersion.Async2]: AsyncApi2Types,
[SpecVersion.Async3]: AsyncApi3Types,
[SpecVersion.Arazzo1]: Arazzo1Types,
[SpecVersion.Overlay1]: Overlay1Types,
};
export type RuleMap<Key extends string, RuleConfig, T> = Record<
T extends 'built-in' ? Key : string,
RuleConfig
>;
export type Oas3RuleSet<T = undefined> = RuleMap<
BuiltInOAS3RuleId | 'struct' | 'assertions',
Oas3Rule,
T
>;
export type Oas2RuleSet<T = undefined> = RuleMap<
BuiltInOAS2RuleId | 'struct' | 'assertions',
Oas2Rule,
T
>;
export type Async2RuleSet<T = undefined> = RuleMap<
BuiltInAsync2RuleId | 'struct' | 'assertions',
Async2Rule,
T
>;
export type Async3RuleSet<T = undefined> = RuleMap<
BuiltInAsync3RuleId | 'struct' | 'assertions',
Async3Rule,
T
>;
export type Arazzo1RuleSet<T = undefined> = RuleMap<
BuiltInArazzo1RuleId | 'struct' | 'assertions',
Arazzo1Rule,
T
>;
export type Overlay1RuleSet<T = undefined> = RuleMap<
BuiltInOverlay1RuleId | 'struct' | 'assertions',
Overlay1Rule,
T
>;
export type Oas3PreprocessorsSet = Record<string, Oas3Preprocessor>;
export type Oas2PreprocessorsSet = Record<string, Oas2Preprocessor>;
export type Async2PreprocessorsSet = Record<string, Async2Preprocessor>;
export type Async3PreprocessorsSet = Record<string, Async3Preprocessor>;
export type Arazzo1PreprocessorsSet = Record<string, Arazzo1Preprocessor>;
export type Overlay1PreprocessorsSet = Record<string, Overlay1Preprocessor>;
export type Oas3DecoratorsSet = Record<string, Oas3Preprocessor>;
export type Oas2DecoratorsSet = Record<string, Oas2Preprocessor>;
export type Async2DecoratorsSet = Record<string, Async2Preprocessor>;
export type Async3DecoratorsSet = Record<string, Async3Preprocessor>;
export type Arazzo1DecoratorsSet = Record<string, Arazzo1Preprocessor>;
export type Overlay1DecoratorsSet = Record<string, Overlay1Preprocessor>;
export function detectSpec(root: unknown): SpecVersion {
if (!isPlainObject(root)) {
throw new Error(`Document must be JSON object, got ${typeof root}`);
}
if (root.openapi && typeof root.openapi !== 'string') {
throw new Error(`Invalid OpenAPI version: should be a string but got "${typeof root.openapi}"`);
}
if (typeof root.openapi === 'string' && root.openapi.startsWith('3.0')) {
return SpecVersion.OAS3_0;
}
if (typeof root.openapi === 'string' && root.openapi.startsWith('3.1')) {
return SpecVersion.OAS3_1;
}
if (root.swagger && root.swagger === '2.0') {
return SpecVersion.OAS2;
}
if (root.openapi || root.swagger) {
throw new Error(`Unsupported OpenAPI version: ${root.openapi || root.swagger}`);
}
if (typeof root.asyncapi === 'string' && root.asyncapi.startsWith('2.')) {
return SpecVersion.Async2;
}
if (typeof root.asyncapi === 'string' && root.asyncapi.startsWith('3.')) {
return SpecVersion.Async3;
}
if (root.asyncapi) {
throw new Error(`Unsupported AsyncAPI version: ${root.asyncapi}`);
}
if (typeof root.arazzo === 'string' && VERSION_PATTERN.test(root.arazzo)) {
return SpecVersion.Arazzo1;
}
if (typeof root.overlay === 'string' && VERSION_PATTERN.test(root.overlay)) {
return SpecVersion.Overlay1;
}
throw new Error(`Unsupported specification`);
}
export function getMajorSpecVersion(version: SpecVersion): SpecMajorVersion {
if (version === SpecVersion.OAS2) {
return SpecMajorVersion.OAS2;
} else if (version === SpecVersion.Async2) {
return SpecMajorVersion.Async2;
} else if (version === SpecVersion.Async3) {
return SpecMajorVersion.Async3;
} else if (version === SpecVersion.Arazzo1) {
return SpecMajorVersion.Arazzo1;
} else if (version === SpecVersion.Overlay1) {
return SpecMajorVersion.Overlay1;
} else {
return SpecMajorVersion.OAS3;
}
}
export function getTypes(spec: SpecVersion) {
return typesMap[spec];
}