Compare commits

...

1 Commits

Author SHA1 Message Date
𝓛𝓲𝓽𝓽𝓵𝓮 𝓕𝓻𝓪𝓷𝓴 8a8b572e9f fix(sdk): preserve SSE event payload types 2026-06-26 20:37:53 +00:00
4 changed files with 43 additions and 22 deletions
@@ -34,6 +34,8 @@ type OpenApiSchema = {
additionalProperties?: OpenApiSchema | boolean
allOf?: OpenApiSchema[]
anyOf?: OpenApiSchema[]
contentMediaType?: string
contentSchema?: OpenApiSchema
description?: string
enum?: Array<string | boolean>
items?: OpenApiSchema
@@ -88,6 +90,7 @@ function matchLegacyOpenApi(input: Record<string, unknown>) {
// payload and inside an annotated union arm. Resolve these by inlining the
// actual schema from any parent union that references them.
fixSelfReferencingComponents(spec)
collapseJsonSseComponents(spec)
// Effect's Schema.optional emits `anyOf: [T, {type:"null"}]` in OpenAPI,
// but the legacy SDK expected plain `T` for optional fields. Strip null
@@ -229,6 +232,26 @@ function collapseDuplicateComponents(spec: OpenApiSpec) {
}
}
function collapseJsonSseComponents(spec: OpenApiSpec) {
const schemas = spec.components?.schemas
if (!schemas) return
for (const [name, schema] of Object.entries(schemas)) {
const ref = schema.contentMediaType === "application/json" ? schema.contentSchema?.$ref : undefined
const target = ref?.replace("#/components/schemas/", "")
if (schema.type !== "string" || !target || !schemas[target]) continue
// Effect represents JSON SSE payloads as encoded string schemas, but the
// generated SDK's SSE client already decodes them. Keep the payload union
// under its stable, unsuffixed component name instead of exposing `string`.
const canonical = name.replace(/\d+$/, "")
if (target.replace(/\d+$/, "") !== canonical) continue
schemas[canonical] = schemas[target]
rewriteRefs(spec, name, canonical)
rewriteRefs(spec, target, canonical)
if (name !== canonical) delete schemas[name]
if (target !== canonical) delete schemas[target]
}
}
function normalizeComponentNames(spec: OpenApiSpec) {
const schemas = spec.components?.schemas
if (!schemas) return
@@ -99,6 +99,22 @@ describe("PublicApi OpenAPI v2 errors", () => {
})
})
test("exposes decoded SSE payload schemas", () => {
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
expect(spec.paths["/api/event"]?.get?.responses?.["200"]?.content?.["text/event-stream"]?.schema?.$ref).toBe(
"#/components/schemas/V2Event",
)
expect(spec.components.schemas.V2Event?.anyOf?.length).toBeGreaterThan(0)
expect(spec.components.schemas.V2Event1).toBeUndefined()
expect(
spec.paths["/api/session/{sessionID}/event"]?.get?.responses?.["200"]?.content?.["text/event-stream"]?.schema
?.properties?.data?.$ref,
).toBe("#/components/schemas/SessionDurableEvent")
expect(spec.components.schemas.SessionDurableEvent1).toBeUndefined()
})
test("preserves /api auth responses", () => {
const spec = OpenApi.fromApi(PublicApi) as OpenApiSpec
+2 -6
View File
@@ -2766,8 +2766,6 @@ export type SessionHistory = {
hasMore: boolean
}
export type SessionDurableEvent1 = string
export type SessionMessagesResponse = {
data: Array<SessionMessage>
cursor: {
@@ -2847,7 +2845,7 @@ export type QuestionRejected2 = {
}
}
export type V2Event1 =
export type V2Event =
| ModelsDevRefreshed
| IntegrationUpdated
| IntegrationConnectionUpdated
@@ -2937,8 +2935,6 @@ export type V2Event1 =
| ServerConnected
| GlobalDisposed
export type V2Event = string
export type ForbiddenError = {
_tag: "ForbiddenError"
message: string
@@ -11897,7 +11893,7 @@ export type V2SessionEventsResponses = {
200: {
id: string
event: string
data: SessionDurableEvent1
data: SessionDurableEvent
}
}
+2 -16
View File
@@ -11260,7 +11260,7 @@
"type": "string"
},
"data": {
"$ref": "#/components/schemas/SessionDurableEvent1"
"$ref": "#/components/schemas/SessionDurableEvent"
}
},
"required": ["id", "event", "data"],
@@ -23732,13 +23732,6 @@
"required": ["data", "hasMore"],
"additionalProperties": false
},
"SessionDurableEvent1": {
"type": "string",
"contentSchema": {
"$ref": "#/components/schemas/SessionDurableEvent"
},
"contentMediaType": "application/json"
},
"SessionMessagesResponse": {
"type": "object",
"properties": {
@@ -23975,7 +23968,7 @@
"required": ["id", "type", "data"],
"additionalProperties": false
},
"V2Event1": {
"V2Event": {
"anyOf": [
{
"$ref": "#/components/schemas/Models-devRefreshed"
@@ -24243,13 +24236,6 @@
}
]
},
"V2Event": {
"type": "string",
"contentSchema": {
"$ref": "#/components/schemas/V2Event1"
},
"contentMediaType": "application/json"
},
"ForbiddenError": {
"type": "object",
"properties": {