UNPKG

@typespec/openapi3

Version:

TypeSpec library for emitting OpenAPI 3.0 and OpenAPI 3.1 from the TypeSpec REST protocol binding and converting OpenAPI3 to TypeSpec

73 lines 3.33 kB
import { ArrayBuilder, createAssetEmitter, Placeholder, } from "@typespec/asset-emitter"; import { compilerAssert } from "@typespec/compiler"; import { OpenAPI31SchemaEmitter } from "./schema-emitter-3-1.js"; function createWrappedSchemaEmitterClass(metadataInfo, visibilityUsage, options, optionalDependencies) { return class extends OpenAPI32SchemaEmitter { constructor(emitter) { super(emitter, metadataInfo, visibilityUsage, options, optionalDependencies); } }; } export const createSchemaEmitter3_2 = ({ program, context, ...rest }) => { return createAssetEmitter(program, createWrappedSchemaEmitterClass(rest.metadataInfo, rest.visibilityUsage, rest.options, rest.optionalDependencies), context); }; /** * OpenAPI 3.2 schema emitter. Deals with emitting content of `components/schemas` section. * Extends OpenAPI 3.1 emitter with additional support for OpenAPI 3.2 features. */ export class OpenAPI32SchemaEmitter extends OpenAPI31SchemaEmitter { discriminatedUnion(union) { let schema; if (union.options.envelope === "none") { const items = new ArrayBuilder(); // Add named variants to the oneOf array for (const variant of union.variants.values()) { items.push(this.emitter.emitTypeReference(variant)); } // Add default variant to the oneOf array if it exists if (union.defaultVariant) { items.push(this.emitter.emitTypeReference(union.defaultVariant)); } // Build discriminator with mapping for named variants const mapping = this.getDiscriminatorMapping(union.variants); const discriminator = { propertyName: union.options.discriminatorPropertyName, mapping, }; // Add defaultMapping if there's a default variant if (union.defaultVariant) { const defaultRef = this.emitter.emitTypeReference(union.defaultVariant); compilerAssert(defaultRef.kind === "code", "Unexpected default ref schema. Should be kind: code"); discriminator.defaultMapping = defaultRef.value.$ref; } schema = { type: "object", oneOf: items, discriminator, }; } else { // For envelope variants, delegate to parent class implementation // as the default variant handling with envelopes is not yet specified in the issue return super.discriminatedUnion(union); } return this.applyConstraints(union.type, schema); } getDiscriminatorMapping(variants) { const mapping = {}; for (const [key, model] of variants.entries()) { const ref = this.emitter.emitTypeReference(model); compilerAssert(ref.kind === "code", "Unexpected ref schema. Should be kind: code"); if (ref.value instanceof Placeholder) { ref.value.onValue((resolvedValue) => { mapping[key] = resolvedValue.$ref; }); } else { mapping[key] = ref.value.$ref; } } return mapping; } } //# sourceMappingURL=schema-emitter-3-2.js.map