lib/transform/discriminatorTransformer.ts (85 lines of code) (raw):

import { copyInfo } from "@azure-tools/openapi-tools-common"; import { LiveValidatorLoggingLevels } from "../liveValidation/liveValidator"; import { isRefLike, JsonLoader } from "../swagger/jsonLoader"; import { refSelfSymbol, Schema } from "../swagger/swaggerTypes"; import { xmsDiscriminatorValue } from "../util/constants"; import { allOfTransformer } from "./allOfTransformer"; import { getNameFromRef } from "./context"; import { GlobalTransformer, TransformerType } from "./transformer"; const getDiscriminatorRoot = ( sch: Schema, visited: Map<Schema, string | null>, baseSchemas: Set<Schema>, jsonLoader: JsonLoader ): string | null => { if (sch.discriminator !== undefined) { return sch[refSelfSymbol] ?? null; } if (sch.allOf === undefined) { return null; } let root = visited.get(sch); if (root !== undefined) { return root; } visited.set(sch, null); for (let subSch of sch.allOf) { if (!isRefLike(subSch)) { continue; } subSch = jsonLoader.resolveRefObj(subSch); root = getDiscriminatorRoot(subSch, visited, baseSchemas, jsonLoader); if (root !== null) { baseSchemas.add(subSch); visited.set(sch, root); return root; } } return null; }; const getDiscriminatorValue = (sch: Schema) => { const discriminatorValue = sch[xmsDiscriminatorValue] ?? getNameFromRef(sch); if (discriminatorValue === undefined) { throw new Error("undefined discriminatorValue!"); } return discriminatorValue; }; export const discriminatorTransformer: GlobalTransformer = { type: TransformerType.Global, before: [allOfTransformer], transform({ objSchemas, baseSchemas, jsonLoader, logging }) { const visited = new Map<Schema, string | null>(); for (const sch of objSchemas) { try { const rootRef = getDiscriminatorRoot(sch, visited, baseSchemas, jsonLoader); if (rootRef === null) { if (sch[xmsDiscriminatorValue] !== undefined) { sch._missingDiscriminator = true; } continue; } const baseSch = jsonLoader.resolveRefObj({ $ref: rootRef } as Schema); const $ref = sch[refSelfSymbol]; const discriminatorValue = getDiscriminatorValue(sch); if (baseSch.discriminatorMap === undefined) { baseSch.discriminatorMap = { [getDiscriminatorValue(baseSch)]: null, }; copyInfo(baseSch, baseSch.discriminatorMap); } baseSch.discriminatorMap[discriminatorValue] = { $ref } as unknown as Schema; } catch (e) { if (logging) { logging( `Fail to transform ${sch}. ErrorMessage:${e?.message};ErrorStack:${e?.stack}.`, LiveValidatorLoggingLevels.error ); } else { console.log( `Fail to transform ${sch}. ErrorMessage:${e?.message};ErrorStack:${e?.stack}.` ); } } } }, };