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

125 lines 4.74 kB
import { attachExtensions } from "./attach-extensions.js"; export async function resolveSSEModule() { const [streams, events, sse] = await Promise.all([ tryImportStreams(), tryImportEvents(), tryImportSSE(), ]); if (streams === undefined || events === undefined || sse === undefined) { return undefined; } return { isSSEStream: (program, type) => { if (type.kind !== "Model") return false; // Check if this is a stream - we rely on contentType filtering in the caller const streamOf = streams.getStreamOf(program, type); return !!streamOf; }, getSSEStreamType: (program, type) => { if (type.kind !== "Model") return undefined; return streams.getStreamOf(program, type); }, attachSSEItemSchema: (program, options, streamType, emitObject, getSchemaForType) => { // Check if the stream type is a union with @events decorator if (streamType.kind !== "Union") return; const isEventsUnion = events.isEvents(program, streamType); if (!isEventsUnion) return; // Get event definitions const [eventDefinitions, diagnostics] = events.unsafe_getEventDefinitions(program, streamType); if (diagnostics && diagnostics.length) { // TODO: Handle diagnostics return; } if (!eventDefinitions || eventDefinitions.length === 0) return; // Build the itemSchema structure // The itemSchema should have a oneOf with all event variants const oneOfSchemas = []; for (const eventDef of eventDefinitions) { const variant = eventDef.root; const eventType = eventDef.eventType; const payloadType = eventDef.payloadType; const payloadContentType = eventDef.payloadContentType || "application/json"; // Check if this is a terminal event const isTerminal = sse.isTerminalEvent(program, variant); // Build the oneOf variant schema const variantSchema = { properties: { data: { contentMediaType: payloadContentType, }, }, }; if (isTerminal) { // If the variant type is a string literal, use it as const if (variant.type.kind === "String") { variantSchema.properties.data.const = variant.type.value; variantSchema.properties.data.contentMediaType = payloadContentType; } } else { // For non-terminal events, add the event type if (eventType) { variantSchema.properties.event = { const: eventType, }; } // Add contentSchema for the payload variantSchema.properties.data.contentSchema = getSchemaForType(payloadType); } // Attach any extensions from the union variant attachExtensions(program, variant, variantSchema); oneOfSchemas.push(variantSchema); } // Set the itemSchema with the base structure and oneOf emitObject.itemSchema = { type: "object", properties: { event: { type: "string", }, data: { type: "string", }, }, required: ["event"], oneOf: oneOfSchemas, }; }, }; } async function tryImportStreams() { try { const module = await import("@typespec/streams"); return module; } catch { return undefined; } } async function tryImportEvents() { try { const eventsModule = await import("@typespec/events"); const experimentalModule = await import("@typespec/events/experimental"); return { ...eventsModule, ...experimentalModule }; } catch { return undefined; } } async function tryImportSSE() { try { const module = await import("@typespec/sse"); return module; } catch { return undefined; } } //# sourceMappingURL=sse-module.js.map