MCPcopy
hub / github.com/anomalyco/opencode / compile

Function compile

packages/httpapi-codegen/src/index.ts:76–213  ·  view source on GitHub ↗
(
  api: HttpApi.HttpApi<Id, Groups>,
  options?: {
    readonly groupNames?: Readonly<Record<string, string>>
    readonly endpointNames?: Readonly<Record<string, string>>
    readonly omitEndpoints?: ReadonlySet<string>
  },
)

Source from the content-addressed store, hash-verified

74const manifestName = ".httpapi-codegen.json"
75
76export function compile<Id extends string, Groups extends HttpApiGroup.Any>(
77 api: HttpApi.HttpApi<Id, Groups>,
78 options?: {
79 readonly groupNames?: Readonly<Record<string, string>>
80 readonly endpointNames?: Readonly<Record<string, string>>
81 readonly omitEndpoints?: ReadonlySet<string>
82 },
83): Contract {
84 const endpoints: Array<Endpoint> = []
85 const portable = new Map<SchemaAST.AST, boolean>()
86
87 HttpApi.reflect(api, {
88 onGroup() {},
89 onEndpoint({ endpoint, errors, group, middleware }) {
90 if (options?.omitEndpoints?.has(endpoint.name)) return
91 const groupName = options?.groupNames?.[group.identifier] ?? group.identifier
92 const name = `${groupName}.${endpoint.name}`
93 const required = Array.from(middleware).find((item) => item.requiredForClient)
94 if (required !== undefined) {
95 throw new GenerationError({ reason: `Client middleware requires adapter: ${required.key}` })
96 }
97
98 const successSchemas = Array.from(endpoint.success)
99 if (successSchemas.length === 0) successSchemas.push(HttpApiSchema.NoContent)
100 if (successSchemas.length > 1) throw new GenerationError({ reason: `Multiple success schemas: ${name}` })
101
102 const params = normalizeTransport(endpoint.params, "params", endpoint, name)
103 const query = normalizeTransport(endpoint.query, "query", endpoint, name)
104 const headers = normalizeTransport(endpoint.headers, "headers", endpoint, name)
105 const sourcePayloads = Array.from(endpoint.payload.values()).flatMap(({ schemas }) => schemas)
106 if (sourcePayloads.length > 1) {
107 throw new GenerationError({ reason: `Multiple payload schemas: ${name}` })
108 }
109 const payloads = sourcePayloads.map((schema) => normalizeTransport(schema, "payload", endpoint, name)!)
110 const success = normalizeTransport(successSchemas[0], "success", endpoint, name)!
111 const errorSchemas = Array.from(errors).flatMap(([status, schemas]) =>
112 schemas.map((schema) => ({ status, ...normalizeTransport(schema, "error", endpoint, name)! })),
113 )
114 const inputs = [
115 ...inputFields(params?.schema, "params", name),
116 ...inputFields(query?.schema, "query", name),
117 ...inputFields(headers?.schema, "headers", name),
118 ...payloads.flatMap((item) => inputFields(item.schema, "payload", name)),
119 ]
120 const names = new Set<string>()
121 for (const field of inputs) {
122 if (names.has(field.name)) throw new GenerationError({ reason: `Input field collision: ${field.name}` })
123 names.add(field.name)
124 }
125
126 const schemaPaths: Array<readonly [string, Schema.Top]> = [
127 ...(params === undefined ? [] : [[`${name}.params`, params.schema] as const]),
128 ...(query === undefined ? [] : [[`${name}.query`, query.schema] as const]),
129 ...(headers === undefined ? [] : [[`${name}.headers`, headers.schema] as const]),
130 ...payloads.map((item) => [`${name}.payload`, item.schema] as const),
131 ...responseSchemas(success.schema, `${name}.success`),
132 ...errorSchemas.map((item) => [`${name}.error.${item.status}`, item.schema] as const),
133 ]

Callers 6

build.tsFile · 0.90
generate.test.tsFile · 0.90
generateFunction · 0.70
client.tsFile · 0.50
streamRequestWithFunction · 0.50

Calls 3

uniqueModuleFunction · 0.85
addMethod · 0.65
fromMethod · 0.45

Tested by

no test coverage detected