@kozojs/core 0.3.0 → 0.3.2
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/lib/index.d.ts +652 -0
- package/lib/index.js +207 -34
- package/lib/index.js.map +1 -0
- package/lib/middleware/index.d.ts +160 -0
- package/lib/middleware/index.js +189 -16
- package/lib/middleware/index.js.map +1 -0
- package/package.json +9 -2
- package/lib/chunk-W44TTZNJ.js +0 -205
package/lib/index.d.ts
ADDED
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
import * as hono from 'hono';
|
|
2
|
+
import { Context } from 'hono';
|
|
3
|
+
import { Hono } from 'hono/quick';
|
|
4
|
+
import { IncomingMessage, ServerResponse, Server } from 'node:http';
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
export { z } from 'zod';
|
|
7
|
+
import { TSchema, Static } from '@sinclair/typebox';
|
|
8
|
+
import { ValidateFunction } from 'ajv';
|
|
9
|
+
export { CorsOptions, FileSystemRoutingOptions, HttpBadRequestError, HttpConflictError, HttpError, HttpForbiddenError, HttpInternalServerError, HttpNotFoundError, HttpUnauthorizedError, LoggerOptions, ManifestHttpMethod, ManifestRoute, RateLimitOptions, RoutesManifest, applyFileSystemRouting, clearRateLimitStore, cors, createFileSystemRouting, errorHandler, logger, rateLimit } from './middleware/index.js';
|
|
10
|
+
|
|
11
|
+
type SchemaType = z.ZodType<any> | TSchema;
|
|
12
|
+
type RouteSchema = {
|
|
13
|
+
body?: SchemaType;
|
|
14
|
+
query?: SchemaType;
|
|
15
|
+
params?: SchemaType;
|
|
16
|
+
response?: SchemaType | Record<number, SchemaType>;
|
|
17
|
+
};
|
|
18
|
+
type InferSchema<T> = T extends z.ZodType<any> ? z.infer<T> : T extends TSchema ? Static<T> : unknown;
|
|
19
|
+
/** Infer the response data type from a schema's response field */
|
|
20
|
+
type InferResponse<T> = T extends SchemaType ? InferSchema<T> : T extends Record<number, SchemaType> ? InferSchema<T[200]> : unknown;
|
|
21
|
+
type KozoContext<S extends RouteSchema = {}, TServices extends Services = Services> = {
|
|
22
|
+
services: TServices;
|
|
23
|
+
body: InferSchema<S['body']>;
|
|
24
|
+
query: InferSchema<S['query']>;
|
|
25
|
+
params: InferSchema<S['params']>;
|
|
26
|
+
req: any;
|
|
27
|
+
json: (data: any) => Response;
|
|
28
|
+
text: (data: string, status?: number, headers?: any) => Response;
|
|
29
|
+
};
|
|
30
|
+
type KozoHandler<S extends RouteSchema = {}, TServices extends Services = Services> = (ctx: KozoContext<S, TServices>) => any | Promise<any>;
|
|
31
|
+
interface Services {
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
interface KozoEnv {
|
|
35
|
+
Variables: {
|
|
36
|
+
services: Services;
|
|
37
|
+
user?: unknown;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Context object passed to native route handlers (used with `nativeListen`).
|
|
42
|
+
*
|
|
43
|
+
* Offers the same type inference as `KozoContext` but operates directly on
|
|
44
|
+
* Node.js primitives — no Hono adapter, no Web API Request/Response.
|
|
45
|
+
*
|
|
46
|
+
* @typeParam S - Route schema (body, query, params, response)
|
|
47
|
+
* @typeParam TSvc - Services type (injected at constructor)
|
|
48
|
+
*/
|
|
49
|
+
interface NativeKozoContext<S extends RouteSchema = {}, TSvc extends Services = Services> {
|
|
50
|
+
/** Raw Node.js incoming request */
|
|
51
|
+
readonly req: IncomingMessage;
|
|
52
|
+
/** Raw Node.js server response */
|
|
53
|
+
readonly res: ServerResponse;
|
|
54
|
+
/** Route parameters — typed from schema.params */
|
|
55
|
+
readonly params: InferSchema<S['params']>;
|
|
56
|
+
/** Parsed query string — typed from schema.query */
|
|
57
|
+
readonly query: InferSchema<S['query']>;
|
|
58
|
+
/** Parsed request body — typed from schema.body */
|
|
59
|
+
readonly body: InferSchema<S['body']>;
|
|
60
|
+
/** Injected services — typed from Kozo<TServices> */
|
|
61
|
+
readonly services: TSvc;
|
|
62
|
+
/** Send a JSON response (default status 200). Uses fast-json-stringify if schema.response is defined. */
|
|
63
|
+
json(data: InferResponse<S['response']>, status?: number): void;
|
|
64
|
+
/** Send a plain text response. */
|
|
65
|
+
text(data: string, status?: number): void;
|
|
66
|
+
/** Send an HTML response (SSR page rendering). */
|
|
67
|
+
html(data: string, status?: number): void;
|
|
68
|
+
/** Set a response header. Returns `this` for chaining. */
|
|
69
|
+
header(name: string, value: string): this;
|
|
70
|
+
/** Redirect to another URL (default 302). */
|
|
71
|
+
redirect(url: string, status?: number): void;
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Handler function type for native routes (used with `nativeListen`).
|
|
75
|
+
*
|
|
76
|
+
* @typeParam S - Route schema
|
|
77
|
+
* @typeParam TSvc - Services shape
|
|
78
|
+
*/
|
|
79
|
+
type NativeKozoHandler<S extends RouteSchema = {}, TSvc extends Services = Services> = (ctx: NativeKozoContext<S, TSvc>) => void | Promise<void>;
|
|
80
|
+
interface HandlerContext<TBody = unknown, TParams extends Record<string, string> = Record<string, string>, TQuery extends Record<string, string> = Record<string, string>> {
|
|
81
|
+
body: TBody;
|
|
82
|
+
params: TParams;
|
|
83
|
+
query: TQuery;
|
|
84
|
+
headers: Record<string, string>;
|
|
85
|
+
services: Services;
|
|
86
|
+
user?: unknown;
|
|
87
|
+
c: any;
|
|
88
|
+
}
|
|
89
|
+
type RouteHandler<TBody = unknown> = (ctx: HandlerContext<TBody>) => Promise<unknown> | unknown;
|
|
90
|
+
interface RouteMeta {
|
|
91
|
+
summary?: string;
|
|
92
|
+
description?: string;
|
|
93
|
+
tags?: string[];
|
|
94
|
+
auth?: boolean;
|
|
95
|
+
rateLimit?: {
|
|
96
|
+
max: number;
|
|
97
|
+
window: number;
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
interface RouteModule {
|
|
101
|
+
default: RouteHandler;
|
|
102
|
+
schema?: RouteSchema;
|
|
103
|
+
meta?: RouteMeta;
|
|
104
|
+
middleware?: Array<(ctx: HandlerContext) => Promise<void> | void>;
|
|
105
|
+
}
|
|
106
|
+
type HttpMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
|
|
107
|
+
interface RouteDefinition {
|
|
108
|
+
path: string;
|
|
109
|
+
method: HttpMethod;
|
|
110
|
+
filePath: string;
|
|
111
|
+
module: RouteModule;
|
|
112
|
+
}
|
|
113
|
+
interface OpenAPIConfigRef {
|
|
114
|
+
info: {
|
|
115
|
+
title: string;
|
|
116
|
+
version: string;
|
|
117
|
+
description?: string;
|
|
118
|
+
};
|
|
119
|
+
servers?: Array<{
|
|
120
|
+
url: string;
|
|
121
|
+
description?: string;
|
|
122
|
+
}>;
|
|
123
|
+
tags?: Array<{
|
|
124
|
+
name: string;
|
|
125
|
+
description?: string;
|
|
126
|
+
}>;
|
|
127
|
+
}
|
|
128
|
+
interface KozoConfig<TServices extends Services = Services> {
|
|
129
|
+
routesDir?: string;
|
|
130
|
+
services?: TServices;
|
|
131
|
+
port?: number;
|
|
132
|
+
mode?: 'safe' | 'turbo';
|
|
133
|
+
runtime?: 'node' | 'bun';
|
|
134
|
+
target?: 'node' | 'edge' | 'cloudflare' | 'vercel' | 'netlify';
|
|
135
|
+
monitoring?: {
|
|
136
|
+
enable: boolean;
|
|
137
|
+
metrics: ('req/sec' | 'latency' | 'errors')[];
|
|
138
|
+
port?: number;
|
|
139
|
+
};
|
|
140
|
+
basePath?: string;
|
|
141
|
+
openapi?: OpenAPIConfigRef;
|
|
142
|
+
onError?: (error: Error, ctx: any) => any;
|
|
143
|
+
onNotFound?: (ctx: any) => any;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Client Generator Options
|
|
148
|
+
*/
|
|
149
|
+
interface ClientGeneratorOptions {
|
|
150
|
+
/** Include Zod schemas for client-side validation (default: true) */
|
|
151
|
+
includeValidation?: boolean;
|
|
152
|
+
/** Base URL for the API (default: '') */
|
|
153
|
+
baseUrl?: string;
|
|
154
|
+
/** Enable runtime validation by default (default: false) */
|
|
155
|
+
validateByDefault?: boolean;
|
|
156
|
+
/** Custom headers to include in all requests */
|
|
157
|
+
defaultHeaders?: Record<string, string>;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Route information for client generation
|
|
161
|
+
*/
|
|
162
|
+
interface RouteInfo {
|
|
163
|
+
method: string;
|
|
164
|
+
path: string;
|
|
165
|
+
schema: RouteSchema;
|
|
166
|
+
/** Optional: store the Zod schema instance for type extraction */
|
|
167
|
+
zodSchemas?: {
|
|
168
|
+
body?: any;
|
|
169
|
+
query?: any;
|
|
170
|
+
params?: any;
|
|
171
|
+
response?: any;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Generate typed client code from routes
|
|
176
|
+
*/
|
|
177
|
+
declare function generateTypedClient(routes: RouteInfo[], options?: ClientGeneratorOptions): string;
|
|
178
|
+
|
|
179
|
+
type DatabaseProvider = 'postgresql' | 'mysql' | 'sqlite';
|
|
180
|
+
type DatabaseInstance = Record<string, unknown>;
|
|
181
|
+
/**
|
|
182
|
+
* Shutdown configuration options
|
|
183
|
+
*/
|
|
184
|
+
interface ShutdownOptions {
|
|
185
|
+
/** Maximum time to wait for in-flight requests to complete (default: 30000ms) */
|
|
186
|
+
timeoutMs?: number;
|
|
187
|
+
/** Callback fired when shutdown starts */
|
|
188
|
+
onShutdownStart?: (inflightCount: number) => void;
|
|
189
|
+
/** Callback fired when all requests complete before timeout */
|
|
190
|
+
onShutdownComplete?: () => void;
|
|
191
|
+
/** Callback fired when shutdown times out */
|
|
192
|
+
onShutdownTimeout?: (remainingInflight: number) => void;
|
|
193
|
+
/** Database instance to close (optional) */
|
|
194
|
+
database?: DatabaseInstance;
|
|
195
|
+
/** Database provider type (required if database is provided) */
|
|
196
|
+
databaseProvider?: DatabaseProvider;
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Internal state for tracking in-flight requests
|
|
200
|
+
*/
|
|
201
|
+
interface InflightTracker {
|
|
202
|
+
count: number;
|
|
203
|
+
requests: Set<Promise<unknown>>;
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Create an in-flight request tracker
|
|
207
|
+
*/
|
|
208
|
+
declare function createInflightTracker(): InflightTracker;
|
|
209
|
+
/**
|
|
210
|
+
* Track a request - call at the start of each request
|
|
211
|
+
*/
|
|
212
|
+
declare function trackRequest(tracker: InflightTracker): () => void;
|
|
213
|
+
/**
|
|
214
|
+
* Shutdown state machine
|
|
215
|
+
*/
|
|
216
|
+
type ShutdownState = 'running' | 'shutting-down' | 'shutdown';
|
|
217
|
+
/**
|
|
218
|
+
* Graceful shutdown manager
|
|
219
|
+
*/
|
|
220
|
+
declare class ShutdownManager {
|
|
221
|
+
private state;
|
|
222
|
+
private abortController;
|
|
223
|
+
private server;
|
|
224
|
+
private tracker;
|
|
225
|
+
private database;
|
|
226
|
+
private databaseProvider;
|
|
227
|
+
constructor();
|
|
228
|
+
/**
|
|
229
|
+
* Get current shutdown state
|
|
230
|
+
*/
|
|
231
|
+
getState(): ShutdownState;
|
|
232
|
+
/**
|
|
233
|
+
* Check if server is shutting down
|
|
234
|
+
*/
|
|
235
|
+
isShuttingDown(): boolean;
|
|
236
|
+
/**
|
|
237
|
+
* Get current in-flight request count
|
|
238
|
+
*/
|
|
239
|
+
getInflightCount(): number;
|
|
240
|
+
/**
|
|
241
|
+
* Set the server instance for shutdown
|
|
242
|
+
*/
|
|
243
|
+
setServer(server: Server): void;
|
|
244
|
+
/**
|
|
245
|
+
* Set database for cleanup
|
|
246
|
+
*/
|
|
247
|
+
setDatabase(db: DatabaseInstance, provider: DatabaseProvider): void;
|
|
248
|
+
/**
|
|
249
|
+
* Get the AbortController signal for request cancellation
|
|
250
|
+
*/
|
|
251
|
+
getAbortSignal(): AbortSignal | undefined;
|
|
252
|
+
/**
|
|
253
|
+
* Create a request tracker middleware
|
|
254
|
+
* Returns an untrack function to call when request completes
|
|
255
|
+
*/
|
|
256
|
+
trackRequest(): () => void;
|
|
257
|
+
/**
|
|
258
|
+
* Initiate graceful shutdown
|
|
259
|
+
*/
|
|
260
|
+
shutdown(options?: ShutdownOptions): Promise<void>;
|
|
261
|
+
/**
|
|
262
|
+
* Wait for all in-flight requests to complete
|
|
263
|
+
*/
|
|
264
|
+
private drainRequests;
|
|
265
|
+
/**
|
|
266
|
+
* Close database connections based on provider
|
|
267
|
+
*/
|
|
268
|
+
private closeDatabase;
|
|
269
|
+
}
|
|
270
|
+
/**
|
|
271
|
+
* Create a shutdown manager instance
|
|
272
|
+
*/
|
|
273
|
+
declare function createShutdownManager(): ShutdownManager;
|
|
274
|
+
|
|
275
|
+
interface Plugin {
|
|
276
|
+
name: string;
|
|
277
|
+
version?: string;
|
|
278
|
+
install: (app: Kozo) => void | Promise<void>;
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Kozo - High-performance TypeScript framework with Zod schemas
|
|
282
|
+
*
|
|
283
|
+
* @typeParam TServices - Shape of the services object injected into every handler.
|
|
284
|
+
* Pass it once at construction: `createKozo<{ db: Database }>({ services: { db } })`
|
|
285
|
+
* and all handler contexts will have `ctx.services.db` fully typed.
|
|
286
|
+
*/
|
|
287
|
+
declare class Kozo<TServices extends Services = Services> {
|
|
288
|
+
private app;
|
|
289
|
+
private services;
|
|
290
|
+
private routes;
|
|
291
|
+
/** Routes registered directly with the uWS C++ radix router. */
|
|
292
|
+
private uwsRoutes;
|
|
293
|
+
private shutdownManager;
|
|
294
|
+
private _routesDir?;
|
|
295
|
+
constructor(config?: KozoConfig<TServices>);
|
|
296
|
+
use(plugin: Plugin): this;
|
|
297
|
+
/**
|
|
298
|
+
* Load routes from the file system using the configured routesDir.
|
|
299
|
+
* Each route file is dynamically imported, its schema compiled, and handler registered.
|
|
300
|
+
* This is a no-op if routesDir is not configured.
|
|
301
|
+
*/
|
|
302
|
+
loadRoutes(routesDir?: string): Promise<this>;
|
|
303
|
+
generateClient(baseUrl?: string): string;
|
|
304
|
+
generateClient(options?: ClientGeneratorOptions): string;
|
|
305
|
+
get<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S, TServices>): this;
|
|
306
|
+
post<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S, TServices>): this;
|
|
307
|
+
put<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S, TServices>): this;
|
|
308
|
+
patch<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S, TServices>): this;
|
|
309
|
+
delete<S extends RouteSchema>(path: string, schema: S, handler: KozoHandler<S, TServices>): this;
|
|
310
|
+
private register;
|
|
311
|
+
/**
|
|
312
|
+
* Start a uWebSockets.js HTTP server.
|
|
313
|
+
*
|
|
314
|
+
* All routes are registered directly with uWS's C++ radix trie router —
|
|
315
|
+
* zero JS routing overhead per request. The C++ HTTP parser (µHttpParser)
|
|
316
|
+
* eliminates all IncomingMessage/ServerResponse allocations.
|
|
317
|
+
*
|
|
318
|
+
* Throws if uWebSockets.js is not installed.
|
|
319
|
+
* Returns { port, server } so callers can close the server when done.
|
|
320
|
+
*/
|
|
321
|
+
nativeListen(port?: number): Promise<{
|
|
322
|
+
port: number;
|
|
323
|
+
server: Server;
|
|
324
|
+
}>;
|
|
325
|
+
listen(port?: number): Promise<void>;
|
|
326
|
+
/**
|
|
327
|
+
* Graceful shutdown — drains in-flight requests before closing.
|
|
328
|
+
* Use getShutdownManager().setDatabase(db, provider) to register DB cleanup.
|
|
329
|
+
*/
|
|
330
|
+
shutdown(options?: ShutdownOptions): Promise<void>;
|
|
331
|
+
getShutdownManager(): ShutdownManager;
|
|
332
|
+
getApp(): Hono;
|
|
333
|
+
get fetch(): (request: Request, Env?: unknown, executionCtx?: hono.ExecutionContext) => Response | Promise<Response>;
|
|
334
|
+
}
|
|
335
|
+
declare function createKozo<TServices extends Services = Services>(config?: KozoConfig<TServices>): Kozo<TServices>;
|
|
336
|
+
|
|
337
|
+
type CompiledHandler = (c: Context) => Promise<Response> | Response;
|
|
338
|
+
type UserHandler = (c: any) => any;
|
|
339
|
+
type CompiledRoute = {
|
|
340
|
+
validateBody?: ValidateFunction;
|
|
341
|
+
validateQuery?: ValidateFunction;
|
|
342
|
+
validateParams?: ValidateFunction;
|
|
343
|
+
serialize?: (data: any) => string;
|
|
344
|
+
errors?: any;
|
|
345
|
+
};
|
|
346
|
+
declare class SchemaCompiler {
|
|
347
|
+
static compile(schema: RouteSchema): CompiledRoute;
|
|
348
|
+
}
|
|
349
|
+
declare function compileRouteHandler(handler: UserHandler, schema: RouteSchema, services: Services, compiled: CompiledRoute): CompiledHandler;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Build a NativeKozoContext for a native route handler.
|
|
353
|
+
*
|
|
354
|
+
* Called by the native handler compiler (`compiler.ts`) when the route
|
|
355
|
+
* is registered via `nativeRoute()`. Not intended for direct use.
|
|
356
|
+
*
|
|
357
|
+
* @internal
|
|
358
|
+
*/
|
|
359
|
+
declare function buildNativeContext<S extends RouteSchema, TSvc extends Services>(req: IncomingMessage, res: ServerResponse, params: Record<string, string>, body: any, services: TSvc, serialize?: (data: any) => string): NativeKozoContext<S, TSvc>;
|
|
360
|
+
|
|
361
|
+
/** Fast number → string for Content-Length. Cached for values < 10 000. */
|
|
362
|
+
declare function fastCL(n: number): string;
|
|
363
|
+
/**
|
|
364
|
+
* Write a 200 JSON response.
|
|
365
|
+
*
|
|
366
|
+
* IMPORTANT: `body` MUST be ASCII-safe (i.e. produced by JSON.stringify
|
|
367
|
+
* or fast-json-stringify). We use `body.length` instead of
|
|
368
|
+
* `Buffer.byteLength(body)` — valid because JSON serializers escape
|
|
369
|
+
* non-ASCII to `\uXXXX`, keeping the output 7-bit clean.
|
|
370
|
+
*/
|
|
371
|
+
declare function fastWriteJson(res: ServerResponse, body: string): void;
|
|
372
|
+
/**
|
|
373
|
+
* Write a plain text response.
|
|
374
|
+
*/
|
|
375
|
+
declare function fastWriteText(res: ServerResponse, body: string, status?: number): void;
|
|
376
|
+
/**
|
|
377
|
+
* Write an HTML response (SSR page rendering).
|
|
378
|
+
*/
|
|
379
|
+
declare function fastWriteHtml(res: ServerResponse, body: string, status?: number): void;
|
|
380
|
+
/**
|
|
381
|
+
* Write a JSON response with a custom status code.
|
|
382
|
+
*/
|
|
383
|
+
declare function fastWriteJsonStatus(res: ServerResponse, body: string, status: number): void;
|
|
384
|
+
/**
|
|
385
|
+
* Write a pre-built 404 Not Found response (zero allocation).
|
|
386
|
+
*/
|
|
387
|
+
declare function fastWrite404(res: ServerResponse): void;
|
|
388
|
+
/**
|
|
389
|
+
* Write a pre-built 500 Internal Server Error response (zero allocation).
|
|
390
|
+
*/
|
|
391
|
+
declare function fastWrite500(res: ServerResponse): void;
|
|
392
|
+
/**
|
|
393
|
+
* Write a 400 validation error response.
|
|
394
|
+
* Allocates only the error body string.
|
|
395
|
+
*/
|
|
396
|
+
declare function fastWrite400(field: string, errors: any, res: ServerResponse): void;
|
|
397
|
+
/**
|
|
398
|
+
* Write a KozoError as an RFC 7807 problem+json response.
|
|
399
|
+
* Falls back to 500 for unknown errors.
|
|
400
|
+
*/
|
|
401
|
+
declare function fastWriteError(err: unknown, res: ServerResponse): void;
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Kozo Error System - RFC 7807 Problem Details
|
|
405
|
+
*
|
|
406
|
+
* Standardized error format for all validation and runtime errors.
|
|
407
|
+
* Pre-serialized templates + frozen ResponseInit objects eliminate
|
|
408
|
+
* per-request allocations on the hot path.
|
|
409
|
+
*
|
|
410
|
+
* @see https://datatracker.ietf.org/doc/html/rfc7807
|
|
411
|
+
*/
|
|
412
|
+
interface ValidationError {
|
|
413
|
+
field: string;
|
|
414
|
+
message: string;
|
|
415
|
+
code: string;
|
|
416
|
+
value?: unknown;
|
|
417
|
+
}
|
|
418
|
+
interface ProblemDetails {
|
|
419
|
+
type: string;
|
|
420
|
+
title: string;
|
|
421
|
+
status: number;
|
|
422
|
+
detail?: string;
|
|
423
|
+
instance?: string;
|
|
424
|
+
errors?: ValidationError[];
|
|
425
|
+
}
|
|
426
|
+
declare const ERROR_RESPONSES: {
|
|
427
|
+
readonly VALIDATION_FAILED: {
|
|
428
|
+
readonly type: "https://kozo.dev/errors/validation-failed";
|
|
429
|
+
readonly title: "Validation Failed";
|
|
430
|
+
readonly status: 400;
|
|
431
|
+
};
|
|
432
|
+
readonly INVALID_BODY: {
|
|
433
|
+
readonly type: "https://kozo.dev/errors/invalid-body";
|
|
434
|
+
readonly title: "Invalid Request Body";
|
|
435
|
+
readonly status: 400;
|
|
436
|
+
};
|
|
437
|
+
readonly INVALID_QUERY: {
|
|
438
|
+
readonly type: "https://kozo.dev/errors/invalid-query";
|
|
439
|
+
readonly title: "Invalid Query Parameters";
|
|
440
|
+
readonly status: 400;
|
|
441
|
+
};
|
|
442
|
+
readonly INVALID_PARAMS: {
|
|
443
|
+
readonly type: "https://kozo.dev/errors/invalid-params";
|
|
444
|
+
readonly title: "Invalid Path Parameters";
|
|
445
|
+
readonly status: 400;
|
|
446
|
+
};
|
|
447
|
+
readonly INTERNAL_ERROR: {
|
|
448
|
+
readonly type: "https://kozo.dev/errors/internal-error";
|
|
449
|
+
readonly title: "Internal Server Error";
|
|
450
|
+
readonly status: 500;
|
|
451
|
+
};
|
|
452
|
+
readonly NOT_FOUND: {
|
|
453
|
+
readonly type: "https://kozo.dev/errors/not-found";
|
|
454
|
+
readonly title: "Resource Not Found";
|
|
455
|
+
readonly status: 404;
|
|
456
|
+
};
|
|
457
|
+
readonly UNAUTHORIZED: {
|
|
458
|
+
readonly type: "https://kozo.dev/errors/unauthorized";
|
|
459
|
+
readonly title: "Unauthorized";
|
|
460
|
+
readonly status: 401;
|
|
461
|
+
};
|
|
462
|
+
readonly FORBIDDEN: {
|
|
463
|
+
readonly type: "https://kozo.dev/errors/forbidden";
|
|
464
|
+
readonly title: "Forbidden";
|
|
465
|
+
readonly status: 403;
|
|
466
|
+
};
|
|
467
|
+
};
|
|
468
|
+
/**
|
|
469
|
+
* Convert Ajv validation errors to standardized format
|
|
470
|
+
*/
|
|
471
|
+
declare function formatAjvErrors(errors: any[] | null | undefined): ValidationError[];
|
|
472
|
+
/**
|
|
473
|
+
* Convert Zod validation errors to standardized format
|
|
474
|
+
*/
|
|
475
|
+
declare function formatZodErrors(errors: any): ValidationError[];
|
|
476
|
+
/**
|
|
477
|
+
* Build a 400 Validation Failed response.
|
|
478
|
+
* Called on every invalid request — kept as lean as possible.
|
|
479
|
+
*/
|
|
480
|
+
declare function validationErrorResponse(field: string, ajvErrors: any[] | null | undefined, instance?: string): Response;
|
|
481
|
+
/**
|
|
482
|
+
* Build a 500 Internal Server Error response.
|
|
483
|
+
*/
|
|
484
|
+
declare function internalErrorResponse(err: Error, instance?: string): Response;
|
|
485
|
+
declare function notFoundResponse(instance?: string): Response;
|
|
486
|
+
declare function unauthorizedResponse(instance?: string): Response;
|
|
487
|
+
declare function forbiddenResponse(instance?: string): Response;
|
|
488
|
+
declare class KozoError extends Error {
|
|
489
|
+
readonly statusCode: number;
|
|
490
|
+
readonly code: string;
|
|
491
|
+
constructor(message: string, statusCode: number, code: string);
|
|
492
|
+
toResponse(instance?: string): Response;
|
|
493
|
+
}
|
|
494
|
+
declare class ValidationFailedError extends KozoError {
|
|
495
|
+
readonly errors: ValidationError[];
|
|
496
|
+
constructor(message: string, errors?: ValidationError[]);
|
|
497
|
+
toResponse(instance?: string): Response;
|
|
498
|
+
}
|
|
499
|
+
declare class NotFoundError extends KozoError {
|
|
500
|
+
constructor(message?: string);
|
|
501
|
+
}
|
|
502
|
+
declare class UnauthorizedError extends KozoError {
|
|
503
|
+
constructor(message?: string);
|
|
504
|
+
}
|
|
505
|
+
declare class ForbiddenError extends KozoError {
|
|
506
|
+
constructor(message?: string);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
interface OpenAPIInfo {
|
|
510
|
+
title: string;
|
|
511
|
+
version: string;
|
|
512
|
+
description?: string;
|
|
513
|
+
contact?: {
|
|
514
|
+
name?: string;
|
|
515
|
+
url?: string;
|
|
516
|
+
email?: string;
|
|
517
|
+
};
|
|
518
|
+
license?: {
|
|
519
|
+
name: string;
|
|
520
|
+
url?: string;
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
interface OpenAPIConfig {
|
|
524
|
+
info: OpenAPIInfo;
|
|
525
|
+
servers?: Array<{
|
|
526
|
+
url: string;
|
|
527
|
+
description?: string;
|
|
528
|
+
}>;
|
|
529
|
+
tags?: Array<{
|
|
530
|
+
name: string;
|
|
531
|
+
description?: string;
|
|
532
|
+
}>;
|
|
533
|
+
security?: Array<Record<string, string[]>>;
|
|
534
|
+
}
|
|
535
|
+
interface OpenAPISpec {
|
|
536
|
+
openapi: '3.1.0';
|
|
537
|
+
info: OpenAPIInfo;
|
|
538
|
+
servers?: Array<{
|
|
539
|
+
url: string;
|
|
540
|
+
description?: string;
|
|
541
|
+
}>;
|
|
542
|
+
tags?: Array<{
|
|
543
|
+
name: string;
|
|
544
|
+
description?: string;
|
|
545
|
+
}>;
|
|
546
|
+
paths: Record<string, PathItem>;
|
|
547
|
+
components: {
|
|
548
|
+
schemas: Record<string, SchemaObject>;
|
|
549
|
+
securitySchemes?: Record<string, SecurityScheme>;
|
|
550
|
+
};
|
|
551
|
+
security?: Array<Record<string, string[]>>;
|
|
552
|
+
}
|
|
553
|
+
interface PathItem {
|
|
554
|
+
[method: string]: OperationObject;
|
|
555
|
+
}
|
|
556
|
+
interface OperationObject {
|
|
557
|
+
operationId?: string;
|
|
558
|
+
summary?: string;
|
|
559
|
+
description?: string;
|
|
560
|
+
tags?: string[];
|
|
561
|
+
parameters?: ParameterObject[];
|
|
562
|
+
requestBody?: RequestBodyObject;
|
|
563
|
+
responses: Record<string, ResponseObject>;
|
|
564
|
+
security?: Array<Record<string, string[]>>;
|
|
565
|
+
}
|
|
566
|
+
interface ParameterObject {
|
|
567
|
+
name: string;
|
|
568
|
+
in: 'query' | 'path' | 'header' | 'cookie';
|
|
569
|
+
required?: boolean;
|
|
570
|
+
schema: SchemaObject;
|
|
571
|
+
description?: string;
|
|
572
|
+
}
|
|
573
|
+
interface RequestBodyObject {
|
|
574
|
+
required?: boolean;
|
|
575
|
+
content: {
|
|
576
|
+
'application/json': {
|
|
577
|
+
schema: SchemaObject;
|
|
578
|
+
};
|
|
579
|
+
};
|
|
580
|
+
}
|
|
581
|
+
interface ResponseObject {
|
|
582
|
+
description: string;
|
|
583
|
+
content?: {
|
|
584
|
+
'application/json': {
|
|
585
|
+
schema: SchemaObject;
|
|
586
|
+
};
|
|
587
|
+
};
|
|
588
|
+
}
|
|
589
|
+
interface SchemaObject {
|
|
590
|
+
type?: string;
|
|
591
|
+
format?: string;
|
|
592
|
+
properties?: Record<string, SchemaObject>;
|
|
593
|
+
items?: SchemaObject;
|
|
594
|
+
required?: string[];
|
|
595
|
+
enum?: unknown[];
|
|
596
|
+
minimum?: number;
|
|
597
|
+
maximum?: number;
|
|
598
|
+
minLength?: number;
|
|
599
|
+
maxLength?: number;
|
|
600
|
+
pattern?: string;
|
|
601
|
+
description?: string;
|
|
602
|
+
default?: unknown;
|
|
603
|
+
nullable?: boolean;
|
|
604
|
+
oneOf?: SchemaObject[];
|
|
605
|
+
anyOf?: SchemaObject[];
|
|
606
|
+
allOf?: SchemaObject[];
|
|
607
|
+
additionalProperties?: SchemaObject | boolean;
|
|
608
|
+
$ref?: string;
|
|
609
|
+
}
|
|
610
|
+
interface SecurityScheme {
|
|
611
|
+
type: 'apiKey' | 'http' | 'oauth2' | 'openIdConnect';
|
|
612
|
+
scheme?: string;
|
|
613
|
+
bearerFormat?: string;
|
|
614
|
+
name?: string;
|
|
615
|
+
in?: 'query' | 'header' | 'cookie';
|
|
616
|
+
}
|
|
617
|
+
declare class OpenAPIGenerator {
|
|
618
|
+
private config;
|
|
619
|
+
private schemas;
|
|
620
|
+
private schemaCounter;
|
|
621
|
+
constructor(config: OpenAPIConfig);
|
|
622
|
+
/**
|
|
623
|
+
* Generate OpenAPI spec from routes
|
|
624
|
+
*/
|
|
625
|
+
generate(routes: RouteDefinition[]): OpenAPISpec;
|
|
626
|
+
/**
|
|
627
|
+
* Convert Hono path params to OpenAPI format
|
|
628
|
+
* :id -> {id}
|
|
629
|
+
*/
|
|
630
|
+
private honoPathToOpenApi;
|
|
631
|
+
/**
|
|
632
|
+
* Convert route to OpenAPI operation
|
|
633
|
+
*/
|
|
634
|
+
private routeToOperation;
|
|
635
|
+
/**
|
|
636
|
+
* Generate operation ID from path and method
|
|
637
|
+
*/
|
|
638
|
+
private generateOperationId;
|
|
639
|
+
/**
|
|
640
|
+
* Extract tag from path (first segment)
|
|
641
|
+
*/
|
|
642
|
+
private extractTag;
|
|
643
|
+
/**
|
|
644
|
+
* Get HTTP status description
|
|
645
|
+
*/
|
|
646
|
+
private getStatusDescription;
|
|
647
|
+
private capitalize;
|
|
648
|
+
}
|
|
649
|
+
declare function generateSwaggerHtml(specUrl: string, title?: string): string;
|
|
650
|
+
declare function createOpenAPIGenerator(config: OpenAPIConfig): OpenAPIGenerator;
|
|
651
|
+
|
|
652
|
+
export { type ClientGeneratorOptions, type CompiledRoute, ERROR_RESPONSES, ForbiddenError, type InferResponse, type InferSchema, type InflightTracker, Kozo, type KozoConfig, type KozoContext, type KozoEnv, KozoError, type KozoHandler, type NativeKozoContext, type NativeKozoHandler, NotFoundError, type OpenAPIConfig, OpenAPIGenerator, type OpenAPIInfo, type OpenAPISpec, type ProblemDetails, type RouteInfo, type RouteSchema, SchemaCompiler, type Services, ShutdownManager, type ShutdownOptions, type ShutdownState, UnauthorizedError, type ValidationError, ValidationFailedError, buildNativeContext, compileRouteHandler, createInflightTracker, createKozo, createOpenAPIGenerator, createShutdownManager, fastCL, fastWrite400, fastWrite404, fastWrite500, fastWriteError, fastWriteHtml, fastWriteJson, fastWriteJsonStatus, fastWriteText, forbiddenResponse, formatAjvErrors, formatZodErrors, generateSwaggerHtml, generateTypedClient, internalErrorResponse, notFoundResponse, trackRequest, unauthorizedResponse, validationErrorResponse };
|