@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
JavaScript
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