1/**
2 * Normalized OpenAPI operation model shared by the generator pipeline.
3 *
4 * This module records the shape produced after an OpenAPI document is resolved
5 * into stable generator inputs: document metadata, tags, security schemes,
6 * per-operation parameters, request bodies, response media types, derived
7 * schema references, path templates, and streaming capabilities. Renderers
8 * consume this representation to emit HttpClient or HttpApi modules without
9 * reinterpreting raw OpenAPI path-item structures.
10 *
11 * @since 4.0.0
12 */
13import type {
14 OpenAPISecurityRequirement,
15 OpenAPISpecExternalDocs,
16 OpenAPISpecLicense,
17 OpenAPISpecServer
18} from "effect/http-api/OpenApi"
19import type { HttpMethod } from "effect/http/HttpMethod"
20import type * as Types from "effect/Types"
21
22/**
23 * Root OpenAPI metadata preserved for generated client and HttpApi output.
24 *
25 * @category models
26 * @since 4.0.0
27 */
28export interface ParsedOpenApiMetadata {
29 readonly title: string
30 readonly version: string
31 readonly summary: string | undefined
32 readonly description: string | undefined
33 readonly license: OpenAPISpecLicense | undefined
34 readonly servers: ReadonlyArray<OpenAPISpecServer> | undefined
35}
36
37/**
38 * Tag metadata used to group and annotate generated operations.
39 *
40 * @category models
41 * @since 4.0.0
42 */
43export interface ParsedOpenApiTag {
44 readonly name: string
45 readonly description: string | undefined
46 readonly externalDocs: OpenAPISpecExternalDocs | undefined
47}
48
49/**
50 * Supported security scheme extracted from an OpenAPI components section.
51 *
52 * @category models
53 * @since 4.0.0
54 */
55export interface ParsedOpenApiSecurityScheme {
56 readonly name: string
57 readonly type: "basic" | "bearer" | "apiKey" | "http"
58 readonly description: string | undefined
59 readonly bearerFormat: string | undefined
60 readonly scheme: string | undefined
61 readonly key: string | undefined
62 readonly in: "header" | "query" | "cookie" | undefined
63}
64
65/**
66 * Normalized OpenAPI document consumed by the generator renderers.
67 *
68 * @category models
69 * @since 4.0.0
70 */
71export interface ParsedOpenApi {
72 readonly metadata: ParsedOpenApiMetadata
73 readonly tags: ReadonlyArray<ParsedOpenApiTag>
74 readonly securitySchemes: ReadonlyArray<ParsedOpenApiSecurityScheme>
75 readonly operations: ReadonlyArray<ParsedOperation>
76}
77
78/**
79 * Documentation and lifecycle metadata associated with an operation.
80 *
81 * @category models
82 * @since 4.0.0
83 */
84export interface ParsedOperationMetadata {
85 readonly summary: string | undefined
86 readonly description: string | undefined
87 readonly deprecated: boolean
88 readonly externalDocs: OpenAPISpecExternalDocs | undefined
89}
90
91/**
92 * Resolved OpenAPI parameter grouped by where it appears in the request.
93 *
94 * @category models
95 * @since 4.0.0
96 */
97export interface ParsedOperationParameter {
98 readonly name: string
99 readonly in: "path" | "query" | "header" | "cookie"
100 readonly required: boolean
101 readonly description: string | undefined
102 readonly schema: {}
103}
104
105/**
106 * Summary of the request body declaration before per-media schemas are rendered.
107 *
108 * @category models
109 * @since 4.0.0
110 */
111export interface ParsedOperationRequestBody {
112 readonly required: boolean
113 readonly contentTypes: Array<string>
114}
115
116/**
117 * Encoding strategy the generator can use for a request or response media type.
118 *
119 * @category models
120 * @since 4.0.0
121 */
122export type ParsedOperationMediaTypeEncoding =
123 | "json"
124 | "multipart"
125 | "form-url-encoded"
126 | "text"
127 | "binary"
128
129/**
130 * Media type whose schema can be represented in generated Effect code.
131 *
132 * @category models
133 * @since 4.0.0
134 */
135export type ParsedOperationMediaTypeSchema =
136 | {
137 readonly contentType: string
138 readonly encoding: ParsedOperationMediaTypeEncoding
139 readonly schema: string
140 readonly effectStream?: undefined
141 }
142 | {
143 readonly contentType: string
144 readonly encoding: "text"
145 readonly schema: string
146 readonly effectStream: "sse"
147 readonly errorSchema: string
148 }
149 | {
150 readonly contentType: string
151 readonly encoding: "binary"
152 readonly schema?: undefined
153 readonly effectStream: "uint8array"
154 }
155
156/**
157 * Parsed response metadata together with generated schema references.
158 *
159 * @category models
160 * @since 4.0.0
161 */
162export interface ParsedOperationResponse {
163 readonly status: string
164 readonly description: string | undefined
165 readonly contentTypes: Array<string>
166 readonly hasHeaders: boolean
167 readonly isEmpty: boolean
168 readonly representable: ReadonlyArray<ParsedOperationMediaTypeSchema>
169}
170
171/**
172 * Resolved security requirement applied to a parsed operation.
173 *
174 * @category models
175 * @since 4.0.0
176 */
177export type ParsedOperationSecurityRequirement = Readonly<OpenAPISecurityRequirement>
178
179/**
180 * Response state used only by the generated HttpClient renderers.
181 *
182 * @category models
183 * @since 4.0.0
184 */
185export interface ParsedOperationHttpClientResponses {
186 readonly successSchemas: ReadonlyMap<string, string>
187 readonly errorSchemas: ReadonlyMap<string, string>
188 readonly voidSuccessStatuses: ReadonlySet<string>
189 readonly voidErrorStatuses: ReadonlySet<string>
190 readonly sseSchema?: string
191 readonly sseSchemaMode: "data" | "event"
192 readonly binarySuccessStatuses: ReadonlySet<string>
193}
194
195/**
196 * Normalized operation model shared by all OpenAPI generator backends.
197 *
198 * @category models
199 * @since 4.0.0
200 */
201export interface ParsedOperation {
202 readonly id: string
203 readonly operationId: string | undefined
204 readonly path: string
205 readonly method: Lowercase<HttpMethod>
206 readonly tags: ReadonlyArray<string>
207 readonly metadata: ParsedOperationMetadata
208 readonly parameters: {
209 readonly path: ReadonlyArray<ParsedOperationParameter>
210 readonly query: ReadonlyArray<ParsedOperationParameter>
211 readonly header: ReadonlyArray<ParsedOperationParameter>
212 readonly cookie: ReadonlyArray<ParsedOperationParameter>
213 }
214 readonly requestBody: ParsedOperationRequestBody | undefined
215 readonly responses: ReadonlyArray<ParsedOperationResponse>
216 readonly defaultResponse: ParsedOperationResponse | undefined
217 readonly effectiveSecurity: ReadonlyArray<ParsedOperationSecurityRequirement>
218 readonly description: string | undefined
219 readonly params?: string
220 readonly paramsOptional: boolean
221 readonly urlParams: ReadonlyArray<string>
222 readonly headers: ReadonlyArray<string>
223 readonly cookies: ReadonlyArray<string>
224 readonly payload?: string
225 readonly payloadFormData: boolean
226 readonly payloadFormUrlEncoded: boolean
227 readonly pathSchema: string | undefined
228 readonly querySchema: string | undefined
229 readonly querySchemaOptional: boolean
230 readonly headersSchema: string | undefined
231 readonly headersSchemaOptional: boolean
232 readonly requestBodyRepresentable: ReadonlyArray<ParsedOperationMediaTypeSchema>
233 readonly pathIds: ReadonlyArray<string>
234 readonly pathTemplate: string
235 readonly httpClientResponses: ParsedOperationHttpClientResponses
236}
237
238/**
239 * Creates a mutable operation accumulator populated with parser defaults.
240 *
241 * @category constructors
242 * @since 4.0.0
243 */
244export const makeDeepMutable = (options: {
245 readonly id: string
246 readonly method: Lowercase<HttpMethod>
247 readonly pathIds: Array<string>
248 readonly pathTemplate: string
249 readonly description: string | undefined
250}): Types.DeepMutable<ParsedOperation> => ({
251 ...options,
252 operationId: undefined,
253 path: "",
254 tags: [],
255 metadata: {
256 summary: undefined,
257 description: options.description,
258 deprecated: false,
259 externalDocs: undefined
260 },
261 parameters: {
262 path: [],
263 query: [],
264 header: [],
265 cookie: []
266 },
267 requestBody: undefined,
268 responses: [],
269 defaultResponse: undefined,
270 effectiveSecurity: [],
271 urlParams: [],
272 headers: [],
273 cookies: [],
274 payloadFormData: false,
275 payloadFormUrlEncoded: false,
276 pathSchema: undefined,
277 querySchema: undefined,
278 querySchemaOptional: true,
279 headersSchema: undefined,
280 headersSchemaOptional: true,
281 requestBodyRepresentable: [],
282 httpClientResponses: {
283 successSchemas: new Map(),
284 errorSchemas: new Map(),
285 voidSuccessStatuses: new Set(),
286 voidErrorStatuses: new Set(),
287 sseSchemaMode: "data",
288 binarySuccessStatuses: new Set()
289 },
290 paramsOptional: true
291})