(
groups: ReadonlyArray<Group>,
outputTypes?: Readonly<Record<string, { readonly name: string; readonly import: string }>>,
)
| 419 | } |
| 420 | |
| 421 | function renderPromiseTypes( |
| 422 | groups: ReadonlyArray<Group>, |
| 423 | outputTypes?: Readonly<Record<string, { readonly name: string; readonly import: string }>>, |
| 424 | ) { |
| 425 | const types = new Map<SchemaAST.AST, string>() |
| 426 | const typeOf = (schema: Schema.Top, decoded = false) => { |
| 427 | const projected = decoded ? Schema.toType(schema) : Schema.toEncoded(schema) |
| 428 | const cached = types.get(projected.ast) |
| 429 | if (cached !== undefined) return cached |
| 430 | const type = structuralType(projected) |
| 431 | types.set(projected.ast, type) |
| 432 | return type |
| 433 | } |
| 434 | const errors = new Map( |
| 435 | groups.flatMap((group) => |
| 436 | group.endpoints.flatMap((endpoint) => |
| 437 | endpoint.errors.flatMap((error) => { |
| 438 | const tagged = declaredErrorFields(error.schema) |
| 439 | return tagged === undefined ? [] : [[tagged.tag, tagged] as const] |
| 440 | }), |
| 441 | ), |
| 442 | ), |
| 443 | ) |
| 444 | const errorTypes = Array.from(errors.values()).map((error) => { |
| 445 | const fields = error.fields |
| 446 | .map(([name, schema, optional]) => `readonly ${JSON.stringify(name)}${optional ? "?" : ""}: ${typeOf(schema)}`) |
| 447 | .join("; ") |
| 448 | return `export type ${error.identifier} = { readonly ${JSON.stringify(error.key)}: ${JSON.stringify(error.tag)}; ${fields} }\nexport const is${error.identifier} = (value: unknown): value is ${error.identifier} => typeof value === "object" && value !== null && ${JSON.stringify(error.key)} in value && value[${JSON.stringify(error.key)}] === ${JSON.stringify(error.tag)}` |
| 449 | }) |
| 450 | const operations = groups |
| 451 | .flatMap((group) => |
| 452 | group.endpoints.flatMap((endpoint) => { |
| 453 | const prefix = promiseTypePrefix(group.identifier, endpoint.operation.name) |
| 454 | const schemas = { |
| 455 | params: endpoint.params, |
| 456 | query: endpoint.query, |
| 457 | headers: endpoint.headers, |
| 458 | payload: endpoint.payloads[0], |
| 459 | } |
| 460 | const input = endpoint.input |
| 461 | .map((field) => { |
| 462 | const schema = schemas[field.source] |
| 463 | if (schema === undefined) |
| 464 | throw new GenerationError({ reason: `Missing input schema: ${prefix}.${field.name}` }) |
| 465 | return `readonly ${JSON.stringify(field.name)}${field.optional ? "?" : ""}: (${typeOf(schema, field.source === "query")})[${JSON.stringify(field.name)}]` |
| 466 | }) |
| 467 | .join("; ") |
| 468 | const successSchema = endpoint.successes[0] |
| 469 | const success = |
| 470 | outputTypes?.[`${group.identifier}.${endpoint.operation.name}`]?.name ?? |
| 471 | typeOf( |
| 472 | isStreamSchema(successSchema) && successSchema._tag === "StreamSse" |
| 473 | ? successSchema.sseMode === "data" |
| 474 | ? streamEncodedDataSchema(successSchema) |
| 475 | : successSchema.events |
| 476 | : successSchema, |
| 477 | ) |
| 478 | return [ |
no test coverage detected