UNPKG

@redocly/openapi-core

Version:

See https://github.com/Redocly/redocly-cli

120 lines 4.62 kB
import { rootRedoclyConfigSchema } from '@redocly/config'; import { BaseResolver, resolveDocument, makeDocumentFromString } from './resolve.js'; import { normalizeVisitors } from './visitors.js'; import { walkDocument } from './walk.js'; import { initRules } from './config/rules.js'; import { normalizeTypes } from './types/index.js'; import { releaseAjvInstance } from './rules/ajv.js'; import { getTypes } from './oas-types.js'; import { detectSpec, getMajorSpecVersion } from './detect-spec.js'; import { createConfigTypes } from './types/redocly-yaml.js'; import { Struct } from './rules/common/struct.js'; import { NoUnresolvedRefs } from './rules/common/no-unresolved-refs.js'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore FIXME: remove this once we remove `theme` from the schema delete rootRedoclyConfigSchema.properties.theme; export async function lint(opts) { const { ref, externalRefResolver = new BaseResolver(opts.config.resolve) } = opts; const document = (await externalRefResolver.resolveDocument(null, ref, true)); opts.collectSpecData?.(document.parsed); return lintDocument({ document, ...opts, externalRefResolver, }); } export async function lintFromString(opts) { const { source, absoluteRef, externalRefResolver = new BaseResolver(opts.config.resolve) } = opts; const document = makeDocumentFromString(source, absoluteRef || '/'); return lintDocument({ document, ...opts, externalRefResolver, }); } export async function lintDocument(opts) { releaseAjvInstance(); // FIXME: preprocessors can modify nodes which are then cached to ajv-instance by absolute path const { document, customTypes, externalRefResolver, config } = opts; const specVersion = detectSpec(document.parsed); const specMajorVersion = getMajorSpecVersion(specVersion); const rules = config.getRulesForSpecVersion(specMajorVersion); const types = normalizeTypes(config.extendTypes(customTypes ?? getTypes(specVersion), specVersion), config); const ctx = { problems: [], specVersion, config, visitorsData: {}, }; const preprocessors = initRules(rules, config, 'preprocessors', specVersion); const regularRules = initRules(rules, config, 'rules', specVersion); let resolvedRefMap = await resolveDocument({ rootDocument: document, rootType: types.Root, externalRefResolver, }); if (preprocessors.length > 0) { // Make additional pass to resolve refs defined in preprocessors. walkDocument({ document, rootType: types.Root, normalizedVisitors: normalizeVisitors(preprocessors, types), resolvedRefMap, ctx, }); resolvedRefMap = await resolveDocument({ rootDocument: document, rootType: types.Root, externalRefResolver, }); } const normalizedVisitors = normalizeVisitors(regularRules, types); walkDocument({ document, rootType: types.Root, normalizedVisitors, resolvedRefMap, ctx, }); return ctx.problems.map((problem) => config.addProblemToIgnore(problem)); } export async function lintConfig(opts) { const { severity, externalRefResolver = new BaseResolver(), config } = opts; if (!config.document) { throw new Error('Config document is not set.'); } const ctx = { problems: [], specVersion: 'oas3_0', // TODO: use config-specific version config, visitorsData: {}, }; const types = normalizeTypes(opts.externalConfigTypes || createConfigTypes(rootRedoclyConfigSchema, config)); const rules = [ { severity: severity || 'error', ruleId: 'configuration struct', visitor: Struct({ severity: 'error' }), }, { severity: severity || 'error', ruleId: 'configuration no-unresolved-refs', visitor: NoUnresolvedRefs({ severity: 'error' }), }, ]; const normalizedVisitors = normalizeVisitors(rules, types); const resolvedRefMap = config.resolvedRefMap || (await resolveDocument({ rootDocument: config.document, rootType: types.ConfigRoot, externalRefResolver, })); walkDocument({ document: config.document, rootType: types.ConfigRoot, normalizedVisitors, resolvedRefMap, ctx, }); return ctx.problems; } //# sourceMappingURL=lint.js.map