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