serverstruct 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +8 -0
- package/OPENAPI.md +286 -0
- package/OTEL.md +208 -0
- package/README.md +175 -121
- package/dist/openapi.cjs +242 -0
- package/dist/openapi.d.cts +241 -0
- package/dist/openapi.d.mts +241 -0
- package/dist/openapi.mjs +231 -0
- package/dist/openapi.scalar.cjs +13 -0
- package/dist/openapi.scalar.d.cts +8 -0
- package/dist/openapi.scalar.d.mts +8 -0
- package/dist/openapi.scalar.mjs +13 -0
- package/package.json +40 -4
- package/tsdown.config.mts +11 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { EventHandlerResponse, H3, H3Event, RouteOptions } from "h3";
|
|
2
|
+
import { output } from "zod";
|
|
3
|
+
import { CreateDocumentOptions, ZodOpenApiMediaTypeObject, ZodOpenApiMetadata, ZodOpenApiMetadata as ZodOpenApiMetadata$1, ZodOpenApiObject, ZodOpenApiOperationObject, ZodOpenApiPathsObject, ZodOpenApiRequestBodyObject, ZodOpenApiResponseObject, createDocument } from "zod-openapi";
|
|
4
|
+
|
|
5
|
+
//#region src/openapi.d.ts
|
|
6
|
+
/** Infer the Zod output type from `requestBody.content["application/json"].schema`. */
|
|
7
|
+
type InferBody<T> = T extends {
|
|
8
|
+
requestBody: {
|
|
9
|
+
content: {
|
|
10
|
+
"application/json": {
|
|
11
|
+
schema: infer S;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
} ? output<S> : unknown;
|
|
16
|
+
/** Infer the Zod output type from `requestParams.path`. */
|
|
17
|
+
type InferParams<T> = T extends {
|
|
18
|
+
requestParams: {
|
|
19
|
+
path: infer S;
|
|
20
|
+
};
|
|
21
|
+
} ? output<S> : Record<string, string>;
|
|
22
|
+
/** Infer the Zod output type from `requestParams.query`. */
|
|
23
|
+
type InferQuery<T> = T extends {
|
|
24
|
+
requestParams: {
|
|
25
|
+
query: infer S;
|
|
26
|
+
};
|
|
27
|
+
} ? output<S> : Record<string, string>;
|
|
28
|
+
/** Resolve a response object from `responses` by numeric status code, handling both numeric and string keys. */
|
|
29
|
+
type LookupResponseByStatus<R$1, Status extends number> = Status extends keyof R$1 ? R$1[Status] : `${Status}` extends keyof R$1 ? R$1[`${Status}`] : never;
|
|
30
|
+
/** Infer the Zod output type from `responses[status].content["application/json"].schema`. */
|
|
31
|
+
type InferResponse<T, Status extends number> = T extends {
|
|
32
|
+
responses: infer R;
|
|
33
|
+
} ? LookupResponseByStatus<R, Status> extends {
|
|
34
|
+
content: {
|
|
35
|
+
"application/json": {
|
|
36
|
+
schema: infer S;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
} ? output<S> : unknown : unknown;
|
|
40
|
+
/** Infer the Zod output type from `responses[status].headers`. Falls back to `Record<string, string>` when no headers schema is defined. */
|
|
41
|
+
type InferResponseHeaders<T, Status extends number> = T extends {
|
|
42
|
+
responses: infer R;
|
|
43
|
+
} ? LookupResponseByStatus<R, Status> extends {
|
|
44
|
+
headers: infer H;
|
|
45
|
+
} ? output<H> : Record<string, string> : Record<string, string>;
|
|
46
|
+
/** Extract the raw Zod schema from `requestBody.content["application/json"].schema`, or `undefined` if absent. */
|
|
47
|
+
type ExtractBodySchema<T> = T extends {
|
|
48
|
+
requestBody: {
|
|
49
|
+
content: {
|
|
50
|
+
"application/json": {
|
|
51
|
+
schema: infer S;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
} ? S extends {
|
|
56
|
+
_zod: any;
|
|
57
|
+
} ? S : undefined : undefined;
|
|
58
|
+
/** Extract the raw Zod schema from `requestParams.path`, or `undefined` if absent. */
|
|
59
|
+
type ExtractParamsSchema<T> = T extends {
|
|
60
|
+
requestParams: {
|
|
61
|
+
path: infer S;
|
|
62
|
+
};
|
|
63
|
+
} ? S extends {
|
|
64
|
+
_zod: any;
|
|
65
|
+
} ? S : undefined : undefined;
|
|
66
|
+
/** Extract the raw Zod schema from `requestParams.query`, or `undefined` if absent. */
|
|
67
|
+
type ExtractQuerySchema<T> = T extends {
|
|
68
|
+
requestParams: {
|
|
69
|
+
query: infer S;
|
|
70
|
+
};
|
|
71
|
+
} ? S extends {
|
|
72
|
+
_zod: any;
|
|
73
|
+
} ? S : undefined : undefined;
|
|
74
|
+
/** Extract the raw Zod schema from `requestParams.header`, or `undefined` if absent. */
|
|
75
|
+
type ExtractHeadersSchema<T> = T extends {
|
|
76
|
+
requestParams: {
|
|
77
|
+
header: infer S;
|
|
78
|
+
};
|
|
79
|
+
} ? S extends {
|
|
80
|
+
_zod: any;
|
|
81
|
+
} ? S : undefined : undefined;
|
|
82
|
+
/** Extract numeric status codes from `responses`, normalizing string keys like `"200"` to `200`. */
|
|
83
|
+
type ResponseStatusKeys<T> = T extends {
|
|
84
|
+
responses: infer R;
|
|
85
|
+
} ? keyof R extends infer K ? K extends number ? K : K extends `${infer N extends number}` ? N : never : never : never;
|
|
86
|
+
/**
|
|
87
|
+
* Typed context returned from operation registration.
|
|
88
|
+
*
|
|
89
|
+
* Provides access to raw Zod schemas for manual validation and
|
|
90
|
+
* convenience methods for extracting validated request data.
|
|
91
|
+
*
|
|
92
|
+
* - `schemas` — raw Zod schemas for use with h3 validation utilities (e.g. `getValidatedRouterParams`)
|
|
93
|
+
* - `params()` — validates and returns route parameters
|
|
94
|
+
* - `query()` — validates and returns query string parameters
|
|
95
|
+
* - `body()` — validates and returns the JSON request body
|
|
96
|
+
* - `reply()` — sets the response status, optional headers, and returns typed response data
|
|
97
|
+
*/
|
|
98
|
+
type RouterContext<T extends ZodOpenApiOperationObject = ZodOpenApiOperationObject> = {
|
|
99
|
+
schemas: {
|
|
100
|
+
params: ExtractParamsSchema<T>;
|
|
101
|
+
query: ExtractQuerySchema<T>;
|
|
102
|
+
headers: ExtractHeadersSchema<T>;
|
|
103
|
+
body: ExtractBodySchema<T>;
|
|
104
|
+
};
|
|
105
|
+
params(event: H3Event): Promise<InferParams<T>>;
|
|
106
|
+
query(event: H3Event): Promise<InferQuery<T>>;
|
|
107
|
+
body(event: H3Event): Promise<InferBody<T>>;
|
|
108
|
+
reply<S$1 extends ResponseStatusKeys<T>>(event: H3Event, status: S$1, data: InferResponse<T, S$1>, headers?: InferResponseHeaders<T, S$1>): InferResponse<T, S$1>;
|
|
109
|
+
};
|
|
110
|
+
declare const HTTP_METHODS: readonly ["get", "post", "put", "delete", "patch"];
|
|
111
|
+
type HttpMethod = (typeof HTTP_METHODS)[number];
|
|
112
|
+
/**
|
|
113
|
+
* Collects OpenAPI operation definitions for document generation.
|
|
114
|
+
*
|
|
115
|
+
* Register operations by HTTP method and path. The accumulated `paths`
|
|
116
|
+
* object can be passed to `createDocument()` to generate the OpenAPI spec.
|
|
117
|
+
*
|
|
118
|
+
* Each registration returns a typed {@link RouterContext} for use in route handlers.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* // Singleton via getbox DI
|
|
123
|
+
* const paths = box.get(OpenApiPaths);
|
|
124
|
+
*
|
|
125
|
+
* const getPost = paths.get("/posts/{id}", { ... });
|
|
126
|
+
*
|
|
127
|
+
* // Generate OpenAPI document
|
|
128
|
+
* createDocument({ openapi: "3.1.0", info: { ... }, paths: paths.paths });
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare class OpenApiPaths {
|
|
132
|
+
paths: ZodOpenApiPathsObject;
|
|
133
|
+
get<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
134
|
+
post<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
135
|
+
put<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
136
|
+
delete<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
137
|
+
patch<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
138
|
+
/** Register an operation for all standard HTTP methods (get, post, put, delete, patch). */
|
|
139
|
+
all<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
140
|
+
/** Register an operation for specific HTTP methods. */
|
|
141
|
+
on<T extends ZodOpenApiOperationObject>(methods: readonly HttpMethod[], path: string, operation: T): RouterContext<T>;
|
|
142
|
+
private register;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Combines OpenAPI path registration with H3 route registration.
|
|
146
|
+
*
|
|
147
|
+
* Each method registers the operation in {@link OpenApiPaths} (converting the
|
|
148
|
+
* H3 path syntax to OpenAPI format) and simultaneously registers the route
|
|
149
|
+
* handler on the H3 app. The handler receives the typed {@link RouterContext}.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* const router = createRouter(app, box.get(OpenApiPaths));
|
|
154
|
+
*
|
|
155
|
+
* router.get("/posts/:id", {
|
|
156
|
+
* operationId: "getPost",
|
|
157
|
+
* requestBody: jsonRequest(inputSchema),
|
|
158
|
+
* responses: {
|
|
159
|
+
* 200: jsonResponse(outputSchema, { description: "Success" }),
|
|
160
|
+
* },
|
|
161
|
+
* }, async (event, ctx) => {
|
|
162
|
+
* const body = await ctx.body(event);
|
|
163
|
+
* return ctx.reply(event, 200, { message: "ok" });
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
declare class OpenApiRouter {
|
|
168
|
+
protected app: H3;
|
|
169
|
+
protected paths: OpenApiPaths;
|
|
170
|
+
constructor(app: H3, paths: OpenApiPaths);
|
|
171
|
+
get<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
172
|
+
post<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
173
|
+
put<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
174
|
+
delete<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
175
|
+
patch<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
176
|
+
/** Register a route and operation for all standard HTTP methods. */
|
|
177
|
+
all<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
178
|
+
/** Register a route and operation for specific HTTP methods. */
|
|
179
|
+
on<T extends ZodOpenApiOperationObject>(methods: readonly HttpMethod[], path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
180
|
+
}
|
|
181
|
+
/** Create an {@link OpenApiRouter} that combines H3 route registration with OpenAPI path collection. */
|
|
182
|
+
declare function createRouter(app: H3, paths: OpenApiPaths): OpenApiRouter;
|
|
183
|
+
type Pretty<T> = { [K in keyof T]: T[K] } & {};
|
|
184
|
+
type Merge<T, U> = Omit<T, keyof U> & U;
|
|
185
|
+
type PrettyOmit<T, U extends keyof any> = Pretty<Omit<T, U>>;
|
|
186
|
+
type PrettyMerge<T, U> = Pretty<Merge<T, U>>;
|
|
187
|
+
/** Builder for OpenAPI metadata passed to `.meta()` on Zod schemas. */
|
|
188
|
+
declare const metadata: (meta: ZodOpenApiMetadata$1) => ZodOpenApiMetadata$1;
|
|
189
|
+
/**
|
|
190
|
+
* Build a typed `requestBody` object with `application/json` content.
|
|
191
|
+
*
|
|
192
|
+
* Additional media type options (e.g. `example`) can be passed via `opts.content`.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* jsonRequest(inputSchema)
|
|
197
|
+
* jsonRequest(inputSchema, { description: "Create a post", content: { example: { title: "Hello" } } })
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
declare function jsonRequest<S$1 extends {
|
|
201
|
+
_zod: any;
|
|
202
|
+
}, O extends PrettyMerge<ZodOpenApiRequestBodyObject, {
|
|
203
|
+
content?: PrettyOmit<ZodOpenApiMediaTypeObject, "schema">;
|
|
204
|
+
}>>(schema: S$1, opts?: O): PrettyMerge<ZodOpenApiRequestBodyObject, {
|
|
205
|
+
content: {
|
|
206
|
+
"application/json": PrettyMerge<{
|
|
207
|
+
schema: S$1;
|
|
208
|
+
}, O["content"]>;
|
|
209
|
+
};
|
|
210
|
+
}>;
|
|
211
|
+
/**
|
|
212
|
+
* Build a typed response object with `application/json` content.
|
|
213
|
+
*
|
|
214
|
+
* Additional media type options (e.g. `example`) can be passed via `opts.content`.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* jsonResponse(outputSchema, { description: "Success" })
|
|
219
|
+
* jsonResponse(outputSchema, {
|
|
220
|
+
* description: "Success",
|
|
221
|
+
* headers: z.object({ "x-request-id": z.string() }).meta({}),
|
|
222
|
+
* })
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
declare function jsonResponse<S$1 extends {
|
|
226
|
+
_zod: any;
|
|
227
|
+
}, H$1 extends {
|
|
228
|
+
_zod: any;
|
|
229
|
+
} | undefined, O extends PrettyMerge<ZodOpenApiResponseObject, {
|
|
230
|
+
content?: PrettyOmit<ZodOpenApiMediaTypeObject, "schema">;
|
|
231
|
+
headers?: H$1;
|
|
232
|
+
}>>(schema: S$1, opts: O): PrettyMerge<ZodOpenApiResponseObject, {
|
|
233
|
+
content: {
|
|
234
|
+
"application/json": PrettyMerge<{
|
|
235
|
+
schema: S$1;
|
|
236
|
+
}, O["content"]>;
|
|
237
|
+
};
|
|
238
|
+
headers: O["headers"];
|
|
239
|
+
}>;
|
|
240
|
+
//#endregion
|
|
241
|
+
export { type CreateDocumentOptions, OpenApiPaths, OpenApiRouter, RouterContext, type ZodOpenApiMetadata, type ZodOpenApiObject, createDocument, createRouter, jsonRequest, jsonResponse, metadata };
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { EventHandlerResponse, H3, H3Event, RouteOptions } from "h3";
|
|
2
|
+
import { CreateDocumentOptions, ZodOpenApiMediaTypeObject, ZodOpenApiMetadata, ZodOpenApiMetadata as ZodOpenApiMetadata$1, ZodOpenApiObject, ZodOpenApiOperationObject, ZodOpenApiPathsObject, ZodOpenApiRequestBodyObject, ZodOpenApiResponseObject, createDocument } from "zod-openapi";
|
|
3
|
+
import { output } from "zod";
|
|
4
|
+
|
|
5
|
+
//#region src/openapi.d.ts
|
|
6
|
+
/** Infer the Zod output type from `requestBody.content["application/json"].schema`. */
|
|
7
|
+
type InferBody<T> = T extends {
|
|
8
|
+
requestBody: {
|
|
9
|
+
content: {
|
|
10
|
+
"application/json": {
|
|
11
|
+
schema: infer S;
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
} ? output<S> : unknown;
|
|
16
|
+
/** Infer the Zod output type from `requestParams.path`. */
|
|
17
|
+
type InferParams<T> = T extends {
|
|
18
|
+
requestParams: {
|
|
19
|
+
path: infer S;
|
|
20
|
+
};
|
|
21
|
+
} ? output<S> : Record<string, string>;
|
|
22
|
+
/** Infer the Zod output type from `requestParams.query`. */
|
|
23
|
+
type InferQuery<T> = T extends {
|
|
24
|
+
requestParams: {
|
|
25
|
+
query: infer S;
|
|
26
|
+
};
|
|
27
|
+
} ? output<S> : Record<string, string>;
|
|
28
|
+
/** Resolve a response object from `responses` by numeric status code, handling both numeric and string keys. */
|
|
29
|
+
type LookupResponseByStatus<R$1, Status extends number> = Status extends keyof R$1 ? R$1[Status] : `${Status}` extends keyof R$1 ? R$1[`${Status}`] : never;
|
|
30
|
+
/** Infer the Zod output type from `responses[status].content["application/json"].schema`. */
|
|
31
|
+
type InferResponse<T, Status extends number> = T extends {
|
|
32
|
+
responses: infer R;
|
|
33
|
+
} ? LookupResponseByStatus<R, Status> extends {
|
|
34
|
+
content: {
|
|
35
|
+
"application/json": {
|
|
36
|
+
schema: infer S;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
} ? output<S> : unknown : unknown;
|
|
40
|
+
/** Infer the Zod output type from `responses[status].headers`. Falls back to `Record<string, string>` when no headers schema is defined. */
|
|
41
|
+
type InferResponseHeaders<T, Status extends number> = T extends {
|
|
42
|
+
responses: infer R;
|
|
43
|
+
} ? LookupResponseByStatus<R, Status> extends {
|
|
44
|
+
headers: infer H;
|
|
45
|
+
} ? output<H> : Record<string, string> : Record<string, string>;
|
|
46
|
+
/** Extract the raw Zod schema from `requestBody.content["application/json"].schema`, or `undefined` if absent. */
|
|
47
|
+
type ExtractBodySchema<T> = T extends {
|
|
48
|
+
requestBody: {
|
|
49
|
+
content: {
|
|
50
|
+
"application/json": {
|
|
51
|
+
schema: infer S;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
} ? S extends {
|
|
56
|
+
_zod: any;
|
|
57
|
+
} ? S : undefined : undefined;
|
|
58
|
+
/** Extract the raw Zod schema from `requestParams.path`, or `undefined` if absent. */
|
|
59
|
+
type ExtractParamsSchema<T> = T extends {
|
|
60
|
+
requestParams: {
|
|
61
|
+
path: infer S;
|
|
62
|
+
};
|
|
63
|
+
} ? S extends {
|
|
64
|
+
_zod: any;
|
|
65
|
+
} ? S : undefined : undefined;
|
|
66
|
+
/** Extract the raw Zod schema from `requestParams.query`, or `undefined` if absent. */
|
|
67
|
+
type ExtractQuerySchema<T> = T extends {
|
|
68
|
+
requestParams: {
|
|
69
|
+
query: infer S;
|
|
70
|
+
};
|
|
71
|
+
} ? S extends {
|
|
72
|
+
_zod: any;
|
|
73
|
+
} ? S : undefined : undefined;
|
|
74
|
+
/** Extract the raw Zod schema from `requestParams.header`, or `undefined` if absent. */
|
|
75
|
+
type ExtractHeadersSchema<T> = T extends {
|
|
76
|
+
requestParams: {
|
|
77
|
+
header: infer S;
|
|
78
|
+
};
|
|
79
|
+
} ? S extends {
|
|
80
|
+
_zod: any;
|
|
81
|
+
} ? S : undefined : undefined;
|
|
82
|
+
/** Extract numeric status codes from `responses`, normalizing string keys like `"200"` to `200`. */
|
|
83
|
+
type ResponseStatusKeys<T> = T extends {
|
|
84
|
+
responses: infer R;
|
|
85
|
+
} ? keyof R extends infer K ? K extends number ? K : K extends `${infer N extends number}` ? N : never : never : never;
|
|
86
|
+
/**
|
|
87
|
+
* Typed context returned from operation registration.
|
|
88
|
+
*
|
|
89
|
+
* Provides access to raw Zod schemas for manual validation and
|
|
90
|
+
* convenience methods for extracting validated request data.
|
|
91
|
+
*
|
|
92
|
+
* - `schemas` — raw Zod schemas for use with h3 validation utilities (e.g. `getValidatedRouterParams`)
|
|
93
|
+
* - `params()` — validates and returns route parameters
|
|
94
|
+
* - `query()` — validates and returns query string parameters
|
|
95
|
+
* - `body()` — validates and returns the JSON request body
|
|
96
|
+
* - `reply()` — sets the response status, optional headers, and returns typed response data
|
|
97
|
+
*/
|
|
98
|
+
type RouterContext<T extends ZodOpenApiOperationObject = ZodOpenApiOperationObject> = {
|
|
99
|
+
schemas: {
|
|
100
|
+
params: ExtractParamsSchema<T>;
|
|
101
|
+
query: ExtractQuerySchema<T>;
|
|
102
|
+
headers: ExtractHeadersSchema<T>;
|
|
103
|
+
body: ExtractBodySchema<T>;
|
|
104
|
+
};
|
|
105
|
+
params(event: H3Event): Promise<InferParams<T>>;
|
|
106
|
+
query(event: H3Event): Promise<InferQuery<T>>;
|
|
107
|
+
body(event: H3Event): Promise<InferBody<T>>;
|
|
108
|
+
reply<S$1 extends ResponseStatusKeys<T>>(event: H3Event, status: S$1, data: InferResponse<T, S$1>, headers?: InferResponseHeaders<T, S$1>): InferResponse<T, S$1>;
|
|
109
|
+
};
|
|
110
|
+
declare const HTTP_METHODS: readonly ["get", "post", "put", "delete", "patch"];
|
|
111
|
+
type HttpMethod = (typeof HTTP_METHODS)[number];
|
|
112
|
+
/**
|
|
113
|
+
* Collects OpenAPI operation definitions for document generation.
|
|
114
|
+
*
|
|
115
|
+
* Register operations by HTTP method and path. The accumulated `paths`
|
|
116
|
+
* object can be passed to `createDocument()` to generate the OpenAPI spec.
|
|
117
|
+
*
|
|
118
|
+
* Each registration returns a typed {@link RouterContext} for use in route handlers.
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* ```ts
|
|
122
|
+
* // Singleton via getbox DI
|
|
123
|
+
* const paths = box.get(OpenApiPaths);
|
|
124
|
+
*
|
|
125
|
+
* const getPost = paths.get("/posts/{id}", { ... });
|
|
126
|
+
*
|
|
127
|
+
* // Generate OpenAPI document
|
|
128
|
+
* createDocument({ openapi: "3.1.0", info: { ... }, paths: paths.paths });
|
|
129
|
+
* ```
|
|
130
|
+
*/
|
|
131
|
+
declare class OpenApiPaths {
|
|
132
|
+
paths: ZodOpenApiPathsObject;
|
|
133
|
+
get<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
134
|
+
post<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
135
|
+
put<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
136
|
+
delete<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
137
|
+
patch<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
138
|
+
/** Register an operation for all standard HTTP methods (get, post, put, delete, patch). */
|
|
139
|
+
all<T extends ZodOpenApiOperationObject>(path: string, operation: T): RouterContext<T>;
|
|
140
|
+
/** Register an operation for specific HTTP methods. */
|
|
141
|
+
on<T extends ZodOpenApiOperationObject>(methods: readonly HttpMethod[], path: string, operation: T): RouterContext<T>;
|
|
142
|
+
private register;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Combines OpenAPI path registration with H3 route registration.
|
|
146
|
+
*
|
|
147
|
+
* Each method registers the operation in {@link OpenApiPaths} (converting the
|
|
148
|
+
* H3 path syntax to OpenAPI format) and simultaneously registers the route
|
|
149
|
+
* handler on the H3 app. The handler receives the typed {@link RouterContext}.
|
|
150
|
+
*
|
|
151
|
+
* @example
|
|
152
|
+
* ```ts
|
|
153
|
+
* const router = createRouter(app, box.get(OpenApiPaths));
|
|
154
|
+
*
|
|
155
|
+
* router.get("/posts/:id", {
|
|
156
|
+
* operationId: "getPost",
|
|
157
|
+
* requestBody: jsonRequest(inputSchema),
|
|
158
|
+
* responses: {
|
|
159
|
+
* 200: jsonResponse(outputSchema, { description: "Success" }),
|
|
160
|
+
* },
|
|
161
|
+
* }, async (event, ctx) => {
|
|
162
|
+
* const body = await ctx.body(event);
|
|
163
|
+
* return ctx.reply(event, 200, { message: "ok" });
|
|
164
|
+
* });
|
|
165
|
+
* ```
|
|
166
|
+
*/
|
|
167
|
+
declare class OpenApiRouter {
|
|
168
|
+
protected app: H3;
|
|
169
|
+
protected paths: OpenApiPaths;
|
|
170
|
+
constructor(app: H3, paths: OpenApiPaths);
|
|
171
|
+
get<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
172
|
+
post<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
173
|
+
put<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
174
|
+
delete<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
175
|
+
patch<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
176
|
+
/** Register a route and operation for all standard HTTP methods. */
|
|
177
|
+
all<T extends ZodOpenApiOperationObject>(path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
178
|
+
/** Register a route and operation for specific HTTP methods. */
|
|
179
|
+
on<T extends ZodOpenApiOperationObject>(methods: readonly HttpMethod[], path: string, operation: T, handler: (event: H3Event, ctx: RouterContext<T>) => EventHandlerResponse, opts?: RouteOptions): this;
|
|
180
|
+
}
|
|
181
|
+
/** Create an {@link OpenApiRouter} that combines H3 route registration with OpenAPI path collection. */
|
|
182
|
+
declare function createRouter(app: H3, paths: OpenApiPaths): OpenApiRouter;
|
|
183
|
+
type Pretty<T> = { [K in keyof T]: T[K] } & {};
|
|
184
|
+
type Merge<T, U> = Omit<T, keyof U> & U;
|
|
185
|
+
type PrettyOmit<T, U extends keyof any> = Pretty<Omit<T, U>>;
|
|
186
|
+
type PrettyMerge<T, U> = Pretty<Merge<T, U>>;
|
|
187
|
+
/** Builder for OpenAPI metadata passed to `.meta()` on Zod schemas. */
|
|
188
|
+
declare const metadata: (meta: ZodOpenApiMetadata$1) => ZodOpenApiMetadata$1;
|
|
189
|
+
/**
|
|
190
|
+
* Build a typed `requestBody` object with `application/json` content.
|
|
191
|
+
*
|
|
192
|
+
* Additional media type options (e.g. `example`) can be passed via `opts.content`.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* ```ts
|
|
196
|
+
* jsonRequest(inputSchema)
|
|
197
|
+
* jsonRequest(inputSchema, { description: "Create a post", content: { example: { title: "Hello" } } })
|
|
198
|
+
* ```
|
|
199
|
+
*/
|
|
200
|
+
declare function jsonRequest<S$1 extends {
|
|
201
|
+
_zod: any;
|
|
202
|
+
}, O extends PrettyMerge<ZodOpenApiRequestBodyObject, {
|
|
203
|
+
content?: PrettyOmit<ZodOpenApiMediaTypeObject, "schema">;
|
|
204
|
+
}>>(schema: S$1, opts?: O): PrettyMerge<ZodOpenApiRequestBodyObject, {
|
|
205
|
+
content: {
|
|
206
|
+
"application/json": PrettyMerge<{
|
|
207
|
+
schema: S$1;
|
|
208
|
+
}, O["content"]>;
|
|
209
|
+
};
|
|
210
|
+
}>;
|
|
211
|
+
/**
|
|
212
|
+
* Build a typed response object with `application/json` content.
|
|
213
|
+
*
|
|
214
|
+
* Additional media type options (e.g. `example`) can be passed via `opts.content`.
|
|
215
|
+
*
|
|
216
|
+
* @example
|
|
217
|
+
* ```ts
|
|
218
|
+
* jsonResponse(outputSchema, { description: "Success" })
|
|
219
|
+
* jsonResponse(outputSchema, {
|
|
220
|
+
* description: "Success",
|
|
221
|
+
* headers: z.object({ "x-request-id": z.string() }).meta({}),
|
|
222
|
+
* })
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
declare function jsonResponse<S$1 extends {
|
|
226
|
+
_zod: any;
|
|
227
|
+
}, H$1 extends {
|
|
228
|
+
_zod: any;
|
|
229
|
+
} | undefined, O extends PrettyMerge<ZodOpenApiResponseObject, {
|
|
230
|
+
content?: PrettyOmit<ZodOpenApiMediaTypeObject, "schema">;
|
|
231
|
+
headers?: H$1;
|
|
232
|
+
}>>(schema: S$1, opts: O): PrettyMerge<ZodOpenApiResponseObject, {
|
|
233
|
+
content: {
|
|
234
|
+
"application/json": PrettyMerge<{
|
|
235
|
+
schema: S$1;
|
|
236
|
+
}, O["content"]>;
|
|
237
|
+
};
|
|
238
|
+
headers: O["headers"];
|
|
239
|
+
}>;
|
|
240
|
+
//#endregion
|
|
241
|
+
export { type CreateDocumentOptions, OpenApiPaths, OpenApiRouter, RouterContext, type ZodOpenApiMetadata, type ZodOpenApiObject, createDocument, createRouter, jsonRequest, jsonResponse, metadata };
|