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 = Record< T extends 'built-in' ? Key : string, RuleConfig >; export type Oas3RuleSet = RuleMap< BuiltInOAS3RuleId | 'struct' | 'assertions', Oas3Rule, T >; export type Oas2RuleSet = RuleMap< BuiltInOAS2RuleId | 'struct' | 'assertions', Oas2Rule, T >; export type Async2RuleSet = RuleMap< BuiltInAsync2RuleId | 'struct' | 'assertions', Async2Rule, T >; export type Async3RuleSet = RuleMap< BuiltInAsync3RuleId | 'struct' | 'assertions', Async3Rule, T >; export type Arazzo1RuleSet = RuleMap< BuiltInArazzo1RuleId | 'struct' | 'assertions', Arazzo1Rule, T >; export type Overlay1RuleSet = RuleMap< BuiltInOverlay1RuleId | 'struct' | 'assertions', Overlay1Rule, T >; export type Oas3PreprocessorsSet = Record; export type Oas2PreprocessorsSet = Record; export type Async2PreprocessorsSet = Record; export type Async3PreprocessorsSet = Record; export type Arazzo1PreprocessorsSet = Record; export type Overlay1PreprocessorsSet = Record; export type Oas3DecoratorsSet = Record; export type Oas2DecoratorsSet = Record; export type Async2DecoratorsSet = Record; export type Async3DecoratorsSet = Record; export type Arazzo1DecoratorsSet = Record; export type Overlay1DecoratorsSet = Record; 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]; }