@kaito-http/core 3.0.3 → 4.0.0-beta.10
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/dist/cors/cors.cjs +85 -17
- package/dist/cors/cors.d.cts +122 -26
- package/dist/cors/cors.d.ts +122 -26
- package/dist/cors/cors.js +85 -17
- package/dist/index.cjs +223 -124
- package/dist/index.d.cts +104 -83
- package/dist/index.d.ts +104 -83
- package/dist/index.js +223 -120
- package/dist/stream/stream.cjs +2 -4
- package/dist/stream/stream.d.cts +1 -1
- package/dist/stream/stream.d.ts +1 -1
- package/dist/stream/stream.js +2 -4
- package/package.json +25 -20
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { z, ZodTypeDef } from 'zod';
|
|
2
|
+
import { KaitoSSEResponse } from './stream/stream.cjs';
|
|
3
|
+
|
|
1
4
|
declare class WrappedError<T> extends Error {
|
|
2
|
-
readonly data: T;
|
|
3
5
|
static maybe<T>(maybeError: T): (T & Error) | WrappedError<T>;
|
|
4
6
|
static from<T>(data: T): WrappedError<T>;
|
|
7
|
+
readonly data: T;
|
|
5
8
|
private constructor();
|
|
6
9
|
}
|
|
7
10
|
declare class KaitoError extends Error {
|
|
@@ -24,8 +27,6 @@ declare class KaitoRequest {
|
|
|
24
27
|
get request(): Request;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
type KaitoMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
|
|
28
|
-
|
|
29
30
|
/**
|
|
30
31
|
* This class is merely a wrapper around a `Headers` object and a status code.
|
|
31
32
|
* It's used while the router is executing a route to store any mutations to the status
|
|
@@ -45,8 +46,7 @@ type KaitoMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIO
|
|
|
45
46
|
* ```
|
|
46
47
|
*/
|
|
47
48
|
declare class KaitoHead {
|
|
48
|
-
private
|
|
49
|
-
private _status;
|
|
49
|
+
#private;
|
|
50
50
|
constructor();
|
|
51
51
|
get headers(): Headers;
|
|
52
52
|
/**
|
|
@@ -84,11 +84,15 @@ type ErroredAPIResponse = {
|
|
|
84
84
|
type SuccessfulAPIResponse<T> = {
|
|
85
85
|
success: true;
|
|
86
86
|
data: T;
|
|
87
|
-
message: 'OK';
|
|
88
87
|
};
|
|
89
88
|
type APIResponse<T> = ErroredAPIResponse | SuccessfulAPIResponse<T>;
|
|
90
89
|
type AnyResponse = APIResponse<unknown>;
|
|
91
90
|
type MakeOptional<T, K extends keyof T> = T extends T ? Omit<T, K> & Partial<Pick<T, K>> : never;
|
|
91
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
92
|
+
type KaitoMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
93
|
+
type NotReadonly<T> = {
|
|
94
|
+
-readonly [K in keyof T]: T[K];
|
|
95
|
+
};
|
|
92
96
|
type ExtractRouteParams<T extends string> = string extends T ? Record<string, string> : T extends `${string}:${infer Param}/${infer Rest}` ? {
|
|
93
97
|
[k in Param | keyof ExtractRouteParams<Rest>]: string;
|
|
94
98
|
} : T extends `${string}:${infer Param}` ? {
|
|
@@ -105,91 +109,103 @@ type ExtractRouteParams<T extends string> = string extends T ? Record<string, st
|
|
|
105
109
|
* @param head - The kaito head object, which contains getters and setters for headers and status
|
|
106
110
|
* @returns The context for your routes
|
|
107
111
|
*/
|
|
108
|
-
type GetContext<Result> = (req: KaitoRequest, head: KaitoHead) =>
|
|
109
|
-
/**
|
|
110
|
-
* A helper function to create typed necessary functions
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```ts
|
|
114
|
-
* const {router, getContext} = createUtilities(async (req, res) => {
|
|
115
|
-
* // Return context here
|
|
116
|
-
* })
|
|
117
|
-
*
|
|
118
|
-
* const app = router().get('/', async () => "hello");
|
|
119
|
-
*
|
|
120
|
-
* const server = createKaitoHandler({
|
|
121
|
-
* router: app,
|
|
122
|
-
* getContext,
|
|
123
|
-
* // ...
|
|
124
|
-
* });
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
declare function createUtilities<Context>(getContext: GetContext<Context>): {
|
|
128
|
-
getContext: GetContext<Context>;
|
|
129
|
-
router: () => Router<Context, Context, never>;
|
|
130
|
-
};
|
|
131
|
-
interface Parsable<Output = any, Input = Output> {
|
|
132
|
-
_input: Input;
|
|
133
|
-
parse: (value: unknown) => Output;
|
|
134
|
-
}
|
|
135
|
-
type InferParsable<T> = T extends Parsable<infer Output, infer Input> ? {
|
|
136
|
-
input: Input;
|
|
137
|
-
output: Output;
|
|
138
|
-
} : never;
|
|
139
|
-
declare function parsable<T>(parse: (value: unknown) => T): Parsable<T, T>;
|
|
112
|
+
type GetContext<Result> = (req: KaitoRequest, head: KaitoHead) => MaybePromise<Result>;
|
|
140
113
|
|
|
141
|
-
type
|
|
114
|
+
type RouteRunData<Params, Context, QueryOutput, BodyOutput> = {
|
|
142
115
|
ctx: Context;
|
|
143
116
|
body: BodyOutput;
|
|
144
117
|
query: QueryOutput;
|
|
145
|
-
params:
|
|
118
|
+
params: Params;
|
|
119
|
+
};
|
|
120
|
+
type AnyQuery = {
|
|
121
|
+
[key in string]: any;
|
|
146
122
|
};
|
|
147
|
-
type
|
|
148
|
-
type
|
|
149
|
-
type
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
123
|
+
type Through<From, To, RequiredParams extends Record<string, unknown>> = (context: From, params: RequiredParams) => Promise<To>;
|
|
124
|
+
type SSEOutputSpec<Result> = {
|
|
125
|
+
type: 'sse';
|
|
126
|
+
schema: z.Schema<Result>;
|
|
127
|
+
description?: string;
|
|
128
|
+
};
|
|
129
|
+
type JSONOutputSpec<Result> = {
|
|
130
|
+
type: 'json';
|
|
131
|
+
schema: z.Schema<Result>;
|
|
132
|
+
description?: string;
|
|
133
|
+
};
|
|
134
|
+
type OutputSpec<Result> = {
|
|
135
|
+
description?: string;
|
|
136
|
+
body: NoInfer<Result extends KaitoSSEResponse<infer R> ? SSEOutputSpec<R> : JSONOutputSpec<Result>>;
|
|
137
|
+
};
|
|
138
|
+
type Route<ContextTo, Result, Path extends string, AdditionalParams extends Record<string, unknown>, Method extends KaitoMethod, Query, Body> = {
|
|
139
|
+
body?: z.Schema<Body>;
|
|
140
|
+
query?: {
|
|
141
|
+
[Key in keyof Query]: z.Schema<Query[Key]>;
|
|
142
|
+
};
|
|
153
143
|
path: Path;
|
|
154
144
|
method: Method;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
145
|
+
openapi?: OutputSpec<NoInfer<Result>>;
|
|
146
|
+
router: Router<unknown, ContextTo, AdditionalParams, AnyRoute>;
|
|
147
|
+
run(data: RouteRunData<ExtractRouteParams<Path> & AdditionalParams, ContextTo, Query, Body>): Promise<Result> | Result;
|
|
158
148
|
};
|
|
159
|
-
type AnyRoute
|
|
149
|
+
type AnyRoute = Route<any, any, any, any, any, any, any>;
|
|
160
150
|
|
|
161
|
-
type PrefixRoutesPathInner<R extends AnyRoute, Prefix extends `/${string}`> = R extends Route<infer
|
|
151
|
+
type PrefixRoutesPathInner<R extends AnyRoute, Prefix extends `/${string}`> = R extends Route<infer ContextTo, infer Result, infer Path, infer AdditionalParams, infer Method, infer Query, infer BodyOutput> ? Route<ContextTo, Result, `${Prefix}${Path extends '/' ? '' : Path}`, AdditionalParams, Method, Query, BodyOutput> : never;
|
|
162
152
|
type PrefixRoutesPath<Prefix extends `/${string}`, R extends AnyRoute> = R extends R ? PrefixRoutesPathInner<R, Prefix> : never;
|
|
163
|
-
type RouterState<
|
|
153
|
+
type RouterState<ContextFrom, ContextTo, RequiredParams extends Record<string, unknown>, Routes extends AnyRoute> = {
|
|
164
154
|
routes: Set<Routes>;
|
|
165
|
-
through: (context:
|
|
155
|
+
through: (context: unknown, params: RequiredParams) => Promise<ContextTo>;
|
|
156
|
+
config: KaitoConfig<ContextFrom>;
|
|
157
|
+
paramsSchema: z.Schema<RequiredParams> | null;
|
|
166
158
|
};
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Accepts a router instance, and returns a union of all the routes in the router
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* const app = router.get('/', () => 'Hello, world!');
|
|
165
|
+
*
|
|
166
|
+
* type Routes = InferRoutes<typeof app>;
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
type InferRoutes<R extends Router<any, any, any, any>> = R extends Router<any, any, any, infer R extends AnyRoute> ? R : never;
|
|
170
|
+
declare class Router<ContextFrom, ContextTo, RequiredParams extends Record<string, unknown>, R extends AnyRoute> {
|
|
169
171
|
private readonly state;
|
|
170
|
-
static create: <Context>() => Router<Context, Context, never>;
|
|
171
|
-
|
|
172
|
-
constructor(options: RouterState<R, ContextFrom, ContextTo>);
|
|
172
|
+
static create: <Context>(config: KaitoConfig<Context>) => Router<Context, Context, {}, never>;
|
|
173
|
+
protected constructor(state: RouterState<ContextFrom, ContextTo, RequiredParams, R>);
|
|
173
174
|
get routes(): Set<R>;
|
|
174
|
-
add
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
private add;
|
|
176
|
+
params: this extends Router<infer ContextFrom, infer ContextTo, infer Params extends Record<string, unknown>, infer R extends AnyRoute> ? [keyof Params] extends [never] ? <NextParams extends Record<string, unknown> = {}>(spec: {
|
|
177
|
+
[Key in keyof NextParams]: z.ZodType<NextParams[Key], ZodTypeDef, string>;
|
|
178
|
+
}) => Router<ContextFrom, ContextTo, NextParams, R> : 'You cannot define params() on a router that has already had params defined, as routes that already consume params can break.' : never;
|
|
179
|
+
readonly merge: <PathPrefix extends `/${string}`, NextRequiredParams extends Record<string, unknown>, OtherRoutes extends AnyRoute>(pathPrefix: keyof NextRequiredParams extends keyof ExtractRouteParams<PathPrefix> | keyof RequiredParams ? PathPrefix : `Missing ${Exclude<Extract<keyof NextRequiredParams, string>, keyof RequiredParams>}${string}`, other: Router<ContextFrom, unknown, NextRequiredParams, OtherRoutes>) => Router<ContextFrom, ContextTo, RequiredParams, Extract<R | PrefixRoutesPath<PathPrefix, Extract<OtherRoutes, AnyRoute>>, AnyRoute>>;
|
|
180
|
+
protected static getFindRoute: <R_1>(routes: Map<KaitoMethod, Map<string, R_1>>) => (method: KaitoMethod, path: string) => {
|
|
181
|
+
route?: never;
|
|
182
|
+
params?: never;
|
|
183
|
+
} | {
|
|
184
|
+
route: R_1;
|
|
185
|
+
params: Record<string, string>;
|
|
186
|
+
};
|
|
187
|
+
private static buildQuerySchema;
|
|
188
|
+
serve: () => (request: Request) => Promise<Response>;
|
|
189
|
+
openapi: (highLevelSpec: {
|
|
190
|
+
info: {
|
|
191
|
+
version: string;
|
|
192
|
+
title: string;
|
|
193
|
+
description?: string;
|
|
194
|
+
};
|
|
195
|
+
servers?: Partial<Record<(`https://` | `http://`) | ({} & string), string>>;
|
|
196
|
+
}) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Response, "/openapi.json", RequiredParams, "GET", {}, never>>;
|
|
177
197
|
private readonly method;
|
|
178
|
-
get: <Result, Path extends string, Query extends
|
|
179
|
-
post: <Result, Path extends string, Query extends
|
|
180
|
-
put: <Result, Path extends string, Query extends
|
|
181
|
-
patch: <Result, Path extends string, Query extends
|
|
182
|
-
delete: <Result, Path extends string, Query extends
|
|
183
|
-
head: <Result, Path extends string, Query extends
|
|
184
|
-
options: <Result, Path extends string, Query extends
|
|
185
|
-
through: <NextContext>(through: (context: ContextTo) =>
|
|
198
|
+
get: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "GET", Query, Body>, "body" | "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "GET", Query, Body>>;
|
|
199
|
+
post: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "POST", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "POST", Query, Body>>;
|
|
200
|
+
put: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "PUT", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "PUT", Query, Body>>;
|
|
201
|
+
patch: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "PATCH", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "PATCH", Query, Body>>;
|
|
202
|
+
delete: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "DELETE", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "DELETE", Query, Body>>;
|
|
203
|
+
head: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "HEAD", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "HEAD", Query, Body>>;
|
|
204
|
+
options: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "OPTIONS", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "OPTIONS", Query, Body>>;
|
|
205
|
+
through: <NextContext>(through: (context: ContextTo, params: RequiredParams) => MaybePromise<NextContext>) => Router<ContextFrom, NextContext, RequiredParams, R>;
|
|
186
206
|
}
|
|
187
207
|
|
|
188
|
-
type
|
|
189
|
-
/**
|
|
190
|
-
* The root router to mount on this handler.
|
|
191
|
-
*/
|
|
192
|
-
router: Router<ContextFrom, unknown, any>;
|
|
208
|
+
type KaitoConfig<ContextFrom> = {
|
|
193
209
|
/**
|
|
194
210
|
* A function that is called to get the context for a request.
|
|
195
211
|
*
|
|
@@ -197,7 +213,7 @@ type HandlerConfig<ContextFrom> = {
|
|
|
197
213
|
*
|
|
198
214
|
* It's fine for this function to throw; if it does, the error is passed to the `onError` function.
|
|
199
215
|
*/
|
|
200
|
-
getContext
|
|
216
|
+
getContext?: GetContext<ContextFrom>;
|
|
201
217
|
/**
|
|
202
218
|
* A function that is called when an error occurs inside a route handler.
|
|
203
219
|
*
|
|
@@ -209,10 +225,7 @@ type HandlerConfig<ContextFrom> = {
|
|
|
209
225
|
* @param arg - The error thrown, and the KaitoRequest instance
|
|
210
226
|
* @returns A KaitoError or an object with a status and message
|
|
211
227
|
*/
|
|
212
|
-
onError
|
|
213
|
-
error: Error;
|
|
214
|
-
req: KaitoRequest;
|
|
215
|
-
}) => Promise<KaitoError | {
|
|
228
|
+
onError?: (error: Error, req: KaitoRequest) => MaybePromise<KaitoError | {
|
|
216
229
|
status: number;
|
|
217
230
|
message: string;
|
|
218
231
|
}>;
|
|
@@ -228,7 +241,7 @@ type HandlerConfig<ContextFrom> = {
|
|
|
228
241
|
* }
|
|
229
242
|
* ```
|
|
230
243
|
*/
|
|
231
|
-
before?: (req: Request) =>
|
|
244
|
+
before?: (req: Request) => MaybePromise<Response | void | undefined>;
|
|
232
245
|
/**
|
|
233
246
|
* Transforms the response before it is sent to the client. Very useful for settings headers like CORS.
|
|
234
247
|
*
|
|
@@ -248,8 +261,16 @@ type HandlerConfig<ContextFrom> = {
|
|
|
248
261
|
* }
|
|
249
262
|
* ```
|
|
250
263
|
*/
|
|
251
|
-
transform?: (req: Request, res: Response) =>
|
|
264
|
+
transform?: (req: Request, res: Response) => MaybePromise<Response | void | undefined>;
|
|
252
265
|
};
|
|
253
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Create a helper function for instantiating a Kaito router
|
|
268
|
+
*
|
|
269
|
+
* This is the starting point for any Kaito application
|
|
270
|
+
*
|
|
271
|
+
* @param config - The configuration for the router
|
|
272
|
+
* @returns A new Kaito router
|
|
273
|
+
*/
|
|
274
|
+
declare function create<Context = null>(config?: KaitoConfig<Context>): Router<Context, Context, {}, never>;
|
|
254
275
|
|
|
255
|
-
export { type APIResponse, type
|
|
276
|
+
export { type APIResponse, type AnyQuery, type AnyResponse, type AnyRoute, type ErroredAPIResponse, type ExtractRouteParams, type GetContext, type InferRoutes, type JSONOutputSpec, type KaitoConfig, KaitoError, KaitoHead, type KaitoMethod, KaitoRequest, type MakeOptional, type MaybePromise, type NotReadonly, type OutputSpec, type Route, type RouteRunData, Router, type RouterState, type SSEOutputSpec, type SuccessfulAPIResponse, type Through, WrappedError, create, isNodeLikeDev };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import { z, ZodTypeDef } from 'zod';
|
|
2
|
+
import { KaitoSSEResponse } from './stream/stream.js';
|
|
3
|
+
|
|
1
4
|
declare class WrappedError<T> extends Error {
|
|
2
|
-
readonly data: T;
|
|
3
5
|
static maybe<T>(maybeError: T): (T & Error) | WrappedError<T>;
|
|
4
6
|
static from<T>(data: T): WrappedError<T>;
|
|
7
|
+
readonly data: T;
|
|
5
8
|
private constructor();
|
|
6
9
|
}
|
|
7
10
|
declare class KaitoError extends Error {
|
|
@@ -24,8 +27,6 @@ declare class KaitoRequest {
|
|
|
24
27
|
get request(): Request;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
|
-
type KaitoMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS' | 'CONNECT' | 'TRACE';
|
|
28
|
-
|
|
29
30
|
/**
|
|
30
31
|
* This class is merely a wrapper around a `Headers` object and a status code.
|
|
31
32
|
* It's used while the router is executing a route to store any mutations to the status
|
|
@@ -45,8 +46,7 @@ type KaitoMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIO
|
|
|
45
46
|
* ```
|
|
46
47
|
*/
|
|
47
48
|
declare class KaitoHead {
|
|
48
|
-
private
|
|
49
|
-
private _status;
|
|
49
|
+
#private;
|
|
50
50
|
constructor();
|
|
51
51
|
get headers(): Headers;
|
|
52
52
|
/**
|
|
@@ -84,11 +84,15 @@ type ErroredAPIResponse = {
|
|
|
84
84
|
type SuccessfulAPIResponse<T> = {
|
|
85
85
|
success: true;
|
|
86
86
|
data: T;
|
|
87
|
-
message: 'OK';
|
|
88
87
|
};
|
|
89
88
|
type APIResponse<T> = ErroredAPIResponse | SuccessfulAPIResponse<T>;
|
|
90
89
|
type AnyResponse = APIResponse<unknown>;
|
|
91
90
|
type MakeOptional<T, K extends keyof T> = T extends T ? Omit<T, K> & Partial<Pick<T, K>> : never;
|
|
91
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
92
|
+
type KaitoMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS';
|
|
93
|
+
type NotReadonly<T> = {
|
|
94
|
+
-readonly [K in keyof T]: T[K];
|
|
95
|
+
};
|
|
92
96
|
type ExtractRouteParams<T extends string> = string extends T ? Record<string, string> : T extends `${string}:${infer Param}/${infer Rest}` ? {
|
|
93
97
|
[k in Param | keyof ExtractRouteParams<Rest>]: string;
|
|
94
98
|
} : T extends `${string}:${infer Param}` ? {
|
|
@@ -105,91 +109,103 @@ type ExtractRouteParams<T extends string> = string extends T ? Record<string, st
|
|
|
105
109
|
* @param head - The kaito head object, which contains getters and setters for headers and status
|
|
106
110
|
* @returns The context for your routes
|
|
107
111
|
*/
|
|
108
|
-
type GetContext<Result> = (req: KaitoRequest, head: KaitoHead) =>
|
|
109
|
-
/**
|
|
110
|
-
* A helper function to create typed necessary functions
|
|
111
|
-
*
|
|
112
|
-
* @example
|
|
113
|
-
* ```ts
|
|
114
|
-
* const {router, getContext} = createUtilities(async (req, res) => {
|
|
115
|
-
* // Return context here
|
|
116
|
-
* })
|
|
117
|
-
*
|
|
118
|
-
* const app = router().get('/', async () => "hello");
|
|
119
|
-
*
|
|
120
|
-
* const server = createKaitoHandler({
|
|
121
|
-
* router: app,
|
|
122
|
-
* getContext,
|
|
123
|
-
* // ...
|
|
124
|
-
* });
|
|
125
|
-
* ```
|
|
126
|
-
*/
|
|
127
|
-
declare function createUtilities<Context>(getContext: GetContext<Context>): {
|
|
128
|
-
getContext: GetContext<Context>;
|
|
129
|
-
router: () => Router<Context, Context, never>;
|
|
130
|
-
};
|
|
131
|
-
interface Parsable<Output = any, Input = Output> {
|
|
132
|
-
_input: Input;
|
|
133
|
-
parse: (value: unknown) => Output;
|
|
134
|
-
}
|
|
135
|
-
type InferParsable<T> = T extends Parsable<infer Output, infer Input> ? {
|
|
136
|
-
input: Input;
|
|
137
|
-
output: Output;
|
|
138
|
-
} : never;
|
|
139
|
-
declare function parsable<T>(parse: (value: unknown) => T): Parsable<T, T>;
|
|
112
|
+
type GetContext<Result> = (req: KaitoRequest, head: KaitoHead) => MaybePromise<Result>;
|
|
140
113
|
|
|
141
|
-
type
|
|
114
|
+
type RouteRunData<Params, Context, QueryOutput, BodyOutput> = {
|
|
142
115
|
ctx: Context;
|
|
143
116
|
body: BodyOutput;
|
|
144
117
|
query: QueryOutput;
|
|
145
|
-
params:
|
|
118
|
+
params: Params;
|
|
119
|
+
};
|
|
120
|
+
type AnyQuery = {
|
|
121
|
+
[key in string]: any;
|
|
146
122
|
};
|
|
147
|
-
type
|
|
148
|
-
type
|
|
149
|
-
type
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
123
|
+
type Through<From, To, RequiredParams extends Record<string, unknown>> = (context: From, params: RequiredParams) => Promise<To>;
|
|
124
|
+
type SSEOutputSpec<Result> = {
|
|
125
|
+
type: 'sse';
|
|
126
|
+
schema: z.Schema<Result>;
|
|
127
|
+
description?: string;
|
|
128
|
+
};
|
|
129
|
+
type JSONOutputSpec<Result> = {
|
|
130
|
+
type: 'json';
|
|
131
|
+
schema: z.Schema<Result>;
|
|
132
|
+
description?: string;
|
|
133
|
+
};
|
|
134
|
+
type OutputSpec<Result> = {
|
|
135
|
+
description?: string;
|
|
136
|
+
body: NoInfer<Result extends KaitoSSEResponse<infer R> ? SSEOutputSpec<R> : JSONOutputSpec<Result>>;
|
|
137
|
+
};
|
|
138
|
+
type Route<ContextTo, Result, Path extends string, AdditionalParams extends Record<string, unknown>, Method extends KaitoMethod, Query, Body> = {
|
|
139
|
+
body?: z.Schema<Body>;
|
|
140
|
+
query?: {
|
|
141
|
+
[Key in keyof Query]: z.Schema<Query[Key]>;
|
|
142
|
+
};
|
|
153
143
|
path: Path;
|
|
154
144
|
method: Method;
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
145
|
+
openapi?: OutputSpec<NoInfer<Result>>;
|
|
146
|
+
router: Router<unknown, ContextTo, AdditionalParams, AnyRoute>;
|
|
147
|
+
run(data: RouteRunData<ExtractRouteParams<Path> & AdditionalParams, ContextTo, Query, Body>): Promise<Result> | Result;
|
|
158
148
|
};
|
|
159
|
-
type AnyRoute
|
|
149
|
+
type AnyRoute = Route<any, any, any, any, any, any, any>;
|
|
160
150
|
|
|
161
|
-
type PrefixRoutesPathInner<R extends AnyRoute, Prefix extends `/${string}`> = R extends Route<infer
|
|
151
|
+
type PrefixRoutesPathInner<R extends AnyRoute, Prefix extends `/${string}`> = R extends Route<infer ContextTo, infer Result, infer Path, infer AdditionalParams, infer Method, infer Query, infer BodyOutput> ? Route<ContextTo, Result, `${Prefix}${Path extends '/' ? '' : Path}`, AdditionalParams, Method, Query, BodyOutput> : never;
|
|
162
152
|
type PrefixRoutesPath<Prefix extends `/${string}`, R extends AnyRoute> = R extends R ? PrefixRoutesPathInner<R, Prefix> : never;
|
|
163
|
-
type RouterState<
|
|
153
|
+
type RouterState<ContextFrom, ContextTo, RequiredParams extends Record<string, unknown>, Routes extends AnyRoute> = {
|
|
164
154
|
routes: Set<Routes>;
|
|
165
|
-
through: (context:
|
|
155
|
+
through: (context: unknown, params: RequiredParams) => Promise<ContextTo>;
|
|
156
|
+
config: KaitoConfig<ContextFrom>;
|
|
157
|
+
paramsSchema: z.Schema<RequiredParams> | null;
|
|
166
158
|
};
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
/**
|
|
160
|
+
* Accepts a router instance, and returns a union of all the routes in the router
|
|
161
|
+
*
|
|
162
|
+
* @example
|
|
163
|
+
* ```ts
|
|
164
|
+
* const app = router.get('/', () => 'Hello, world!');
|
|
165
|
+
*
|
|
166
|
+
* type Routes = InferRoutes<typeof app>;
|
|
167
|
+
* ```
|
|
168
|
+
*/
|
|
169
|
+
type InferRoutes<R extends Router<any, any, any, any>> = R extends Router<any, any, any, infer R extends AnyRoute> ? R : never;
|
|
170
|
+
declare class Router<ContextFrom, ContextTo, RequiredParams extends Record<string, unknown>, R extends AnyRoute> {
|
|
169
171
|
private readonly state;
|
|
170
|
-
static create: <Context>() => Router<Context, Context, never>;
|
|
171
|
-
|
|
172
|
-
constructor(options: RouterState<R, ContextFrom, ContextTo>);
|
|
172
|
+
static create: <Context>(config: KaitoConfig<Context>) => Router<Context, Context, {}, never>;
|
|
173
|
+
protected constructor(state: RouterState<ContextFrom, ContextTo, RequiredParams, R>);
|
|
173
174
|
get routes(): Set<R>;
|
|
174
|
-
add
|
|
175
|
-
|
|
176
|
-
|
|
175
|
+
private add;
|
|
176
|
+
params: this extends Router<infer ContextFrom, infer ContextTo, infer Params extends Record<string, unknown>, infer R extends AnyRoute> ? [keyof Params] extends [never] ? <NextParams extends Record<string, unknown> = {}>(spec: {
|
|
177
|
+
[Key in keyof NextParams]: z.ZodType<NextParams[Key], ZodTypeDef, string>;
|
|
178
|
+
}) => Router<ContextFrom, ContextTo, NextParams, R> : 'You cannot define params() on a router that has already had params defined, as routes that already consume params can break.' : never;
|
|
179
|
+
readonly merge: <PathPrefix extends `/${string}`, NextRequiredParams extends Record<string, unknown>, OtherRoutes extends AnyRoute>(pathPrefix: keyof NextRequiredParams extends keyof ExtractRouteParams<PathPrefix> | keyof RequiredParams ? PathPrefix : `Missing ${Exclude<Extract<keyof NextRequiredParams, string>, keyof RequiredParams>}${string}`, other: Router<ContextFrom, unknown, NextRequiredParams, OtherRoutes>) => Router<ContextFrom, ContextTo, RequiredParams, Extract<R | PrefixRoutesPath<PathPrefix, Extract<OtherRoutes, AnyRoute>>, AnyRoute>>;
|
|
180
|
+
protected static getFindRoute: <R_1>(routes: Map<KaitoMethod, Map<string, R_1>>) => (method: KaitoMethod, path: string) => {
|
|
181
|
+
route?: never;
|
|
182
|
+
params?: never;
|
|
183
|
+
} | {
|
|
184
|
+
route: R_1;
|
|
185
|
+
params: Record<string, string>;
|
|
186
|
+
};
|
|
187
|
+
private static buildQuerySchema;
|
|
188
|
+
serve: () => (request: Request) => Promise<Response>;
|
|
189
|
+
openapi: (highLevelSpec: {
|
|
190
|
+
info: {
|
|
191
|
+
version: string;
|
|
192
|
+
title: string;
|
|
193
|
+
description?: string;
|
|
194
|
+
};
|
|
195
|
+
servers?: Partial<Record<(`https://` | `http://`) | ({} & string), string>>;
|
|
196
|
+
}) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Response, "/openapi.json", RequiredParams, "GET", {}, never>>;
|
|
177
197
|
private readonly method;
|
|
178
|
-
get: <Result, Path extends string, Query extends
|
|
179
|
-
post: <Result, Path extends string, Query extends
|
|
180
|
-
put: <Result, Path extends string, Query extends
|
|
181
|
-
patch: <Result, Path extends string, Query extends
|
|
182
|
-
delete: <Result, Path extends string, Query extends
|
|
183
|
-
head: <Result, Path extends string, Query extends
|
|
184
|
-
options: <Result, Path extends string, Query extends
|
|
185
|
-
through: <NextContext>(through: (context: ContextTo) =>
|
|
198
|
+
get: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "GET", Query, Body>, "body" | "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "GET", Query, Body>>;
|
|
199
|
+
post: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "POST", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "POST", Query, Body>>;
|
|
200
|
+
put: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "PUT", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "PUT", Query, Body>>;
|
|
201
|
+
patch: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "PATCH", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "PATCH", Query, Body>>;
|
|
202
|
+
delete: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "DELETE", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "DELETE", Query, Body>>;
|
|
203
|
+
head: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "HEAD", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "HEAD", Query, Body>>;
|
|
204
|
+
options: <Result, Path extends string, Query extends AnyQuery = {}, Body = never>(path: Path, route: ((data: RouteRunData<ExtractRouteParams<Path> & RequiredParams, ContextTo, Query, Body>) => Result | Promise<Result>) | Omit<Route<ContextTo, Result, Path, RequiredParams, "OPTIONS", Query, Body>, "path" | "method" | "router">) => Router<ContextFrom, ContextTo, RequiredParams, R | Route<ContextTo, Result, Path, RequiredParams, "OPTIONS", Query, Body>>;
|
|
205
|
+
through: <NextContext>(through: (context: ContextTo, params: RequiredParams) => MaybePromise<NextContext>) => Router<ContextFrom, NextContext, RequiredParams, R>;
|
|
186
206
|
}
|
|
187
207
|
|
|
188
|
-
type
|
|
189
|
-
/**
|
|
190
|
-
* The root router to mount on this handler.
|
|
191
|
-
*/
|
|
192
|
-
router: Router<ContextFrom, unknown, any>;
|
|
208
|
+
type KaitoConfig<ContextFrom> = {
|
|
193
209
|
/**
|
|
194
210
|
* A function that is called to get the context for a request.
|
|
195
211
|
*
|
|
@@ -197,7 +213,7 @@ type HandlerConfig<ContextFrom> = {
|
|
|
197
213
|
*
|
|
198
214
|
* It's fine for this function to throw; if it does, the error is passed to the `onError` function.
|
|
199
215
|
*/
|
|
200
|
-
getContext
|
|
216
|
+
getContext?: GetContext<ContextFrom>;
|
|
201
217
|
/**
|
|
202
218
|
* A function that is called when an error occurs inside a route handler.
|
|
203
219
|
*
|
|
@@ -209,10 +225,7 @@ type HandlerConfig<ContextFrom> = {
|
|
|
209
225
|
* @param arg - The error thrown, and the KaitoRequest instance
|
|
210
226
|
* @returns A KaitoError or an object with a status and message
|
|
211
227
|
*/
|
|
212
|
-
onError
|
|
213
|
-
error: Error;
|
|
214
|
-
req: KaitoRequest;
|
|
215
|
-
}) => Promise<KaitoError | {
|
|
228
|
+
onError?: (error: Error, req: KaitoRequest) => MaybePromise<KaitoError | {
|
|
216
229
|
status: number;
|
|
217
230
|
message: string;
|
|
218
231
|
}>;
|
|
@@ -228,7 +241,7 @@ type HandlerConfig<ContextFrom> = {
|
|
|
228
241
|
* }
|
|
229
242
|
* ```
|
|
230
243
|
*/
|
|
231
|
-
before?: (req: Request) =>
|
|
244
|
+
before?: (req: Request) => MaybePromise<Response | void | undefined>;
|
|
232
245
|
/**
|
|
233
246
|
* Transforms the response before it is sent to the client. Very useful for settings headers like CORS.
|
|
234
247
|
*
|
|
@@ -248,8 +261,16 @@ type HandlerConfig<ContextFrom> = {
|
|
|
248
261
|
* }
|
|
249
262
|
* ```
|
|
250
263
|
*/
|
|
251
|
-
transform?: (req: Request, res: Response) =>
|
|
264
|
+
transform?: (req: Request, res: Response) => MaybePromise<Response | void | undefined>;
|
|
252
265
|
};
|
|
253
|
-
|
|
266
|
+
/**
|
|
267
|
+
* Create a helper function for instantiating a Kaito router
|
|
268
|
+
*
|
|
269
|
+
* This is the starting point for any Kaito application
|
|
270
|
+
*
|
|
271
|
+
* @param config - The configuration for the router
|
|
272
|
+
* @returns A new Kaito router
|
|
273
|
+
*/
|
|
274
|
+
declare function create<Context = null>(config?: KaitoConfig<Context>): Router<Context, Context, {}, never>;
|
|
254
275
|
|
|
255
|
-
export { type APIResponse, type
|
|
276
|
+
export { type APIResponse, type AnyQuery, type AnyResponse, type AnyRoute, type ErroredAPIResponse, type ExtractRouteParams, type GetContext, type InferRoutes, type JSONOutputSpec, type KaitoConfig, KaitoError, KaitoHead, type KaitoMethod, KaitoRequest, type MakeOptional, type MaybePromise, type NotReadonly, type OutputSpec, type Route, type RouteRunData, Router, type RouterState, type SSEOutputSpec, type SuccessfulAPIResponse, type Through, WrappedError, create, isNodeLikeDev };
|