@kaito-http/core 2.7.2 → 2.8.1
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/declarations/src/router.d.ts +10 -9
- package/dist/declarations/src/util.d.ts +26 -0
- package/dist/kaito-http-core.cjs.dev.js +164 -127
- package/dist/kaito-http-core.cjs.prod.js +160 -123
- package/dist/kaito-http-core.esm.js +164 -128
- package/package.json +1 -1
|
@@ -14,13 +14,6 @@ export declare class Router<Context, R extends Routes> {
|
|
|
14
14
|
static create: <Context_1>() => Router<Context_1, []>;
|
|
15
15
|
private static handle;
|
|
16
16
|
constructor(routes: R);
|
|
17
|
-
/**
|
|
18
|
-
* Adds a new route to the router
|
|
19
|
-
* @param route The route specification to add to this router
|
|
20
|
-
* @returns A new router with this route added
|
|
21
|
-
* @deprecated Use `Router#add` instead
|
|
22
|
-
*/
|
|
23
|
-
old_add: <Result, Path extends string, Method extends KaitoMethod, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(route: Method extends "GET" ? Omit<Route<Context, Result, Path, Method, Query, BodyOutput, BodyDef, BodyInput>, "body"> : Route<Context, Result, Path, Method, Query, BodyOutput, BodyDef, BodyInput>) => Router<Context, [...R, Route<Context, Result, Path, Method, Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
24
17
|
/**
|
|
25
18
|
* Adds a new route to the router
|
|
26
19
|
* @param method The HTTP method to add a route for
|
|
@@ -29,7 +22,15 @@ export declare class Router<Context, R extends Routes> {
|
|
|
29
22
|
* @returns A new router with this route added
|
|
30
23
|
*/
|
|
31
24
|
add: <Result, Path extends string, Method extends KaitoMethod, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(method: Method, path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | (Method extends "GET" ? Omit<Route<Context, Result, Path, Method, Query, BodyOutput, BodyDef, BodyInput>, "path" | "body" | "method"> : Omit<Route<Context, Result, Path, Method, Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">)) => Router<Context, [...R, Route<Context, Result, Path, Method, Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
32
|
-
merge: <PathPrefix extends `/${string}`, OtherRoutes extends Routes>(pathPrefix: PathPrefix, other: Router<Context, OtherRoutes>) => Router<Context, [...R, ...PrefixRoutesPath<PathPrefix, OtherRoutes>]>;
|
|
33
|
-
|
|
25
|
+
readonly merge: <PathPrefix extends `/${string}`, OtherRoutes extends Routes>(pathPrefix: PathPrefix, other: Router<Context, OtherRoutes>) => Router<Context, [...R, ...PrefixRoutesPath<PathPrefix, OtherRoutes>]>;
|
|
26
|
+
freeze: (server: ServerConfig<Context, any>) => fmw.Instance<fmw.HTTPVersion.V1>;
|
|
27
|
+
private readonly method;
|
|
28
|
+
get: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "GET", Query, BodyOutput, BodyDef, BodyInput>, "path" | "body" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "GET", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
29
|
+
post: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "POST", Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "POST", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
30
|
+
put: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "PUT", Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "PUT", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
31
|
+
patch: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "PATCH", Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "PATCH", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
32
|
+
delete: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "DELETE", Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "DELETE", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
33
|
+
head: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "HEAD", Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "HEAD", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
34
|
+
options: <Result, Path extends string, Query extends AnyQueryDefinition = {}, BodyOutput = never, BodyDef extends z.ZodTypeDef = z.ZodTypeDef, BodyInput = BodyOutput>(path: Path, route: ((args: import("./route").RouteArgument<Path, Context, z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }> extends infer T extends object ? { [k in keyof T]: z.objectUtil.addQuestionMarks<{ [k_1 in keyof Query]: Query[k_1]["_output"]; }>[k]; } : never, BodyOutput>) => Promise<Result>) | Omit<Route<Context, Result, Path, "OPTIONS", Query, BodyOutput, BodyDef, BodyInput>, "path" | "method">) => Router<Context, [...R, Route<Context, Result, Path, "OPTIONS", Query, BodyOutput, BodyDef, BodyInput>]>;
|
|
34
35
|
}
|
|
35
36
|
export {};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { HTTPMethod } from 'find-my-way';
|
|
2
2
|
import type { KaitoRequest } from './req';
|
|
3
3
|
import type { KaitoResponse } from './res';
|
|
4
|
+
import { Router } from './router';
|
|
4
5
|
export type ExtractRouteParams<T extends string> = string extends T ? Record<string, string> : T extends `${string}:${infer Param}/${infer Rest}` ? {
|
|
5
6
|
[k in Param | keyof ExtractRouteParams<Rest>]: string;
|
|
6
7
|
} : T extends `${string}:${infer Param}` ? {
|
|
@@ -8,7 +9,32 @@ export type ExtractRouteParams<T extends string> = string extends T ? Record<str
|
|
|
8
9
|
} : {};
|
|
9
10
|
export type KaitoMethod = HTTPMethod | '*';
|
|
10
11
|
export type GetContext<Result> = (req: KaitoRequest, res: KaitoResponse) => Promise<Result>;
|
|
12
|
+
/**
|
|
13
|
+
* @deprecated use `createUtilities` instead
|
|
14
|
+
*/
|
|
11
15
|
export declare function createGetContext<Context>(callback: GetContext<Context>): GetContext<Context>;
|
|
16
|
+
/**
|
|
17
|
+
* A helper function to create typed necessary functions
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* const {router, getContext} = createUtilities(async (req, res) => {
|
|
22
|
+
* // Return context here
|
|
23
|
+
* })
|
|
24
|
+
*
|
|
25
|
+
* const app = router().get('/', async () => "hello");
|
|
26
|
+
*
|
|
27
|
+
* const server = createServer({
|
|
28
|
+
* router: app,
|
|
29
|
+
* getContext,
|
|
30
|
+
* // ...
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function createUtilities<Context>(getContext: GetContext<Context>): {
|
|
35
|
+
getContext: GetContext<Context>;
|
|
36
|
+
router: () => Router<Context, []>;
|
|
37
|
+
};
|
|
12
38
|
export type InferContext<T> = T extends (req: KaitoRequest, res: KaitoResponse) => Promise<infer U> ? U : never;
|
|
13
39
|
export declare function getLastEntryInMultiHeaderValue(headerValue: string | string[]): string;
|
|
14
40
|
type RemoveEndSlashes<T extends string> = T extends `${infer U}/` ? U : T;
|
|
@@ -7,9 +7,9 @@ var contentType = require('content-type');
|
|
|
7
7
|
var node_stream = require('node:stream');
|
|
8
8
|
var consumers = require('node:stream/consumers');
|
|
9
9
|
var getRawBody = require('raw-body');
|
|
10
|
-
var cookie = require('cookie');
|
|
11
10
|
var fmw = require('find-my-way');
|
|
12
11
|
var zod = require('zod');
|
|
12
|
+
var cookie = require('cookie');
|
|
13
13
|
var http = require('node:http');
|
|
14
14
|
|
|
15
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -103,104 +103,26 @@ function _asyncToGenerator(fn) {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
function getBody(_x) {
|
|
115
|
-
return _getBody.apply(this, arguments);
|
|
116
|
-
}
|
|
117
|
-
function _getBody() {
|
|
118
|
-
_getBody = _asyncToGenerator(function* (req) {
|
|
119
|
-
if (!req.headers['content-type']) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
var buffer = yield getRawBody__default["default"](req.raw);
|
|
123
|
-
var {
|
|
124
|
-
type
|
|
125
|
-
} = contentType.parse(req.headers['content-type']);
|
|
126
|
-
switch (type) {
|
|
127
|
-
case 'application/json':
|
|
128
|
-
{
|
|
129
|
-
return consumers.json(node_stream.Readable.from(buffer));
|
|
130
|
-
}
|
|
131
|
-
default:
|
|
132
|
-
{
|
|
133
|
-
if (process.env.NODE_ENV === 'development') {
|
|
134
|
-
console.warn('[kaito] Unsupported content type:', type);
|
|
135
|
-
console.warn('[kaito] This message is only shown in development mode.');
|
|
136
|
-
}
|
|
137
|
-
return null;
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
return _getBody.apply(this, arguments);
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
class KaitoRequest {
|
|
145
|
-
constructor(raw) {
|
|
146
|
-
_defineProperty(this, "_url", null);
|
|
147
|
-
this.raw = raw;
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
/**
|
|
151
|
-
* The full URL of the request, including the protocol, hostname, and path.
|
|
152
|
-
* Note: does not include the query string or hash
|
|
153
|
-
*/
|
|
154
|
-
get fullURL() {
|
|
155
|
-
var _this$raw$url;
|
|
156
|
-
return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* A new URL instance for the full URL of the request.
|
|
161
|
-
*/
|
|
162
|
-
get url() {
|
|
163
|
-
if (this._url) {
|
|
164
|
-
return this._url;
|
|
165
|
-
}
|
|
166
|
-
this._url = new URL(this.fullURL);
|
|
167
|
-
return this._url;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* The HTTP method of the request.
|
|
172
|
-
*/
|
|
173
|
-
get method() {
|
|
174
|
-
if (!this.raw.method) {
|
|
175
|
-
throw new Error('Request method is not defined, somehow...');
|
|
176
|
-
}
|
|
177
|
-
return this.raw.method;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/**
|
|
181
|
-
* The protocol of the request, either `http` or `https`.
|
|
182
|
-
*/
|
|
183
|
-
get protocol() {
|
|
184
|
-
if (this.raw.socket instanceof node_tls.TLSSocket) {
|
|
185
|
-
return this.raw.socket.encrypted ? 'https' : 'http';
|
|
186
|
-
}
|
|
187
|
-
return 'http';
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/**
|
|
191
|
-
* The request headers
|
|
192
|
-
*/
|
|
193
|
-
get headers() {
|
|
194
|
-
return this.raw.headers;
|
|
106
|
+
function ownKeys(object, enumerableOnly) {
|
|
107
|
+
var keys = Object.keys(object);
|
|
108
|
+
if (Object.getOwnPropertySymbols) {
|
|
109
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
110
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
111
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
112
|
+
})), keys.push.apply(keys, symbols);
|
|
195
113
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
114
|
+
return keys;
|
|
115
|
+
}
|
|
116
|
+
function _objectSpread2(target) {
|
|
117
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
118
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
119
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
120
|
+
_defineProperty(target, key, source[key]);
|
|
121
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
122
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
123
|
+
});
|
|
203
124
|
}
|
|
125
|
+
return target;
|
|
204
126
|
}
|
|
205
127
|
|
|
206
128
|
class KaitoResponse {
|
|
@@ -255,28 +177,6 @@ class KaitoResponse {
|
|
|
255
177
|
}
|
|
256
178
|
}
|
|
257
179
|
|
|
258
|
-
function ownKeys(object, enumerableOnly) {
|
|
259
|
-
var keys = Object.keys(object);
|
|
260
|
-
if (Object.getOwnPropertySymbols) {
|
|
261
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
262
|
-
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
263
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
264
|
-
})), keys.push.apply(keys, symbols);
|
|
265
|
-
}
|
|
266
|
-
return keys;
|
|
267
|
-
}
|
|
268
|
-
function _objectSpread2(target) {
|
|
269
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
270
|
-
var source = null != arguments[i] ? arguments[i] : {};
|
|
271
|
-
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
272
|
-
_defineProperty(target, key, source[key]);
|
|
273
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
274
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
return target;
|
|
278
|
-
}
|
|
279
|
-
|
|
280
180
|
var getSend = res => (status, response) => {
|
|
281
181
|
if (res.raw.headersSent) {
|
|
282
182
|
return;
|
|
@@ -353,7 +253,6 @@ class Router {
|
|
|
353
253
|
})();
|
|
354
254
|
}
|
|
355
255
|
constructor(routes) {
|
|
356
|
-
_defineProperty(this, "old_add", route => new Router([...this.routes, route]));
|
|
357
256
|
_defineProperty(this, "add", (method, path, route) => {
|
|
358
257
|
var merged = _objectSpread2(_objectSpread2({}, typeof route === 'object' ? route : {
|
|
359
258
|
run: route
|
|
@@ -369,7 +268,7 @@ class Router {
|
|
|
369
268
|
}));
|
|
370
269
|
return new Router([...this.routes, ...newRoutes]);
|
|
371
270
|
});
|
|
372
|
-
_defineProperty(this, "
|
|
271
|
+
_defineProperty(this, "freeze", server => {
|
|
373
272
|
var instance = fmw__default["default"]({
|
|
374
273
|
ignoreTrailingSlash: true,
|
|
375
274
|
defaultRoute(req, serverResponse) {
|
|
@@ -419,21 +318,158 @@ class Router {
|
|
|
419
318
|
}
|
|
420
319
|
return instance;
|
|
421
320
|
});
|
|
321
|
+
_defineProperty(this, "method", method => (path, route) => this.add(method, path, route));
|
|
322
|
+
_defineProperty(this, "get", this.method('GET'));
|
|
323
|
+
_defineProperty(this, "post", this.method('POST'));
|
|
324
|
+
_defineProperty(this, "put", this.method('PUT'));
|
|
325
|
+
_defineProperty(this, "patch", this.method('PATCH'));
|
|
326
|
+
_defineProperty(this, "delete", this.method('DELETE'));
|
|
327
|
+
_defineProperty(this, "head", this.method('HEAD'));
|
|
328
|
+
_defineProperty(this, "options", this.method('OPTIONS'));
|
|
422
329
|
this.routes = routes;
|
|
423
330
|
}
|
|
424
331
|
|
|
425
332
|
/**
|
|
426
333
|
* Adds a new route to the router
|
|
334
|
+
* @param method The HTTP method to add a route for
|
|
335
|
+
* @param path The path to add a route for
|
|
427
336
|
* @param route The route specification to add to this router
|
|
428
337
|
* @returns A new router with this route added
|
|
429
|
-
* @deprecated Use `Router#add` instead
|
|
430
338
|
*/
|
|
431
339
|
}
|
|
432
340
|
_defineProperty(Router, "create", () => new Router([]));
|
|
433
341
|
|
|
342
|
+
/**
|
|
343
|
+
* @deprecated use `createUtilities` instead
|
|
344
|
+
*/
|
|
345
|
+
function createGetContext(callback) {
|
|
346
|
+
return callback;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* A helper function to create typed necessary functions
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* const {router, getContext} = createUtilities(async (req, res) => {
|
|
355
|
+
* // Return context here
|
|
356
|
+
* })
|
|
357
|
+
*
|
|
358
|
+
* const app = router().get('/', async () => "hello");
|
|
359
|
+
*
|
|
360
|
+
* const server = createServer({
|
|
361
|
+
* router: app,
|
|
362
|
+
* getContext,
|
|
363
|
+
* // ...
|
|
364
|
+
* });
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
function createUtilities(getContext) {
|
|
368
|
+
return {
|
|
369
|
+
getContext,
|
|
370
|
+
router: () => Router.create()
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function getLastEntryInMultiHeaderValue(headerValue) {
|
|
374
|
+
var normalized = Array.isArray(headerValue) ? headerValue.join(',') : headerValue;
|
|
375
|
+
var lastIndex = normalized.lastIndexOf(',');
|
|
376
|
+
return lastIndex === -1 ? normalized.trim() : normalized.slice(lastIndex + 1).trim();
|
|
377
|
+
}
|
|
378
|
+
function getBody(_x) {
|
|
379
|
+
return _getBody.apply(this, arguments);
|
|
380
|
+
}
|
|
381
|
+
function _getBody() {
|
|
382
|
+
_getBody = _asyncToGenerator(function* (req) {
|
|
383
|
+
if (!req.headers['content-type']) {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
var buffer = yield getRawBody__default["default"](req.raw);
|
|
387
|
+
var {
|
|
388
|
+
type
|
|
389
|
+
} = contentType.parse(req.headers['content-type']);
|
|
390
|
+
switch (type) {
|
|
391
|
+
case 'application/json':
|
|
392
|
+
{
|
|
393
|
+
return consumers.json(node_stream.Readable.from(buffer));
|
|
394
|
+
}
|
|
395
|
+
default:
|
|
396
|
+
{
|
|
397
|
+
if (process.env.NODE_ENV === 'development') {
|
|
398
|
+
console.warn('[kaito] Unsupported content type:', type);
|
|
399
|
+
console.warn('[kaito] This message is only shown in development mode.');
|
|
400
|
+
}
|
|
401
|
+
return null;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
});
|
|
405
|
+
return _getBody.apply(this, arguments);
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
class KaitoRequest {
|
|
409
|
+
constructor(raw) {
|
|
410
|
+
_defineProperty(this, "_url", null);
|
|
411
|
+
this.raw = raw;
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* The full URL of the request, including the protocol, hostname, and path.
|
|
416
|
+
* Note: does not include the query string or hash
|
|
417
|
+
*/
|
|
418
|
+
get fullURL() {
|
|
419
|
+
var _this$raw$url;
|
|
420
|
+
return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* A new URL instance for the full URL of the request.
|
|
425
|
+
*/
|
|
426
|
+
get url() {
|
|
427
|
+
if (this._url) {
|
|
428
|
+
return this._url;
|
|
429
|
+
}
|
|
430
|
+
this._url = new URL(this.fullURL);
|
|
431
|
+
return this._url;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/**
|
|
435
|
+
* The HTTP method of the request.
|
|
436
|
+
*/
|
|
437
|
+
get method() {
|
|
438
|
+
if (!this.raw.method) {
|
|
439
|
+
throw new Error('Request method is not defined, somehow...');
|
|
440
|
+
}
|
|
441
|
+
return this.raw.method;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
/**
|
|
445
|
+
* The protocol of the request, either `http` or `https`.
|
|
446
|
+
*/
|
|
447
|
+
get protocol() {
|
|
448
|
+
if (this.raw.socket instanceof node_tls.TLSSocket) {
|
|
449
|
+
return this.raw.socket.encrypted ? 'https' : 'http';
|
|
450
|
+
}
|
|
451
|
+
return 'http';
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
/**
|
|
455
|
+
* The request headers
|
|
456
|
+
*/
|
|
457
|
+
get headers() {
|
|
458
|
+
return this.raw.headers;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
/**
|
|
462
|
+
* The hostname of the request.
|
|
463
|
+
*/
|
|
464
|
+
get hostname() {
|
|
465
|
+
var _this$raw$headers$hos, _this$raw$headers$Au;
|
|
466
|
+
return (_this$raw$headers$hos = this.raw.headers.host) !== null && _this$raw$headers$hos !== void 0 ? _this$raw$headers$hos : getLastEntryInMultiHeaderValue((_this$raw$headers$Au = this.raw.headers[':authority']) !== null && _this$raw$headers$Au !== void 0 ? _this$raw$headers$Au : []);
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
434
470
|
function createFMWServer(config) {
|
|
435
471
|
var _config$rawRoutes;
|
|
436
|
-
var
|
|
472
|
+
var router = config.router.freeze(config);
|
|
437
473
|
var rawRoutes = (_config$rawRoutes = config.rawRoutes) !== null && _config$rawRoutes !== void 0 ? _config$rawRoutes : {};
|
|
438
474
|
for (var method in rawRoutes) {
|
|
439
475
|
if (!Object.prototype.hasOwnProperty.call(rawRoutes, method)) {
|
|
@@ -445,10 +481,10 @@ function createFMWServer(config) {
|
|
|
445
481
|
}
|
|
446
482
|
for (var route of routes) {
|
|
447
483
|
if (method === '*') {
|
|
448
|
-
|
|
484
|
+
router.all(route.path, route.handler);
|
|
449
485
|
continue;
|
|
450
486
|
}
|
|
451
|
-
|
|
487
|
+
router[method.toLowerCase()](route.path, route.handler);
|
|
452
488
|
}
|
|
453
489
|
}
|
|
454
490
|
var server = http__namespace.createServer( /*#__PURE__*/function () {
|
|
@@ -464,7 +500,7 @@ function createFMWServer(config) {
|
|
|
464
500
|
if (res.headersSent) {
|
|
465
501
|
return;
|
|
466
502
|
}
|
|
467
|
-
var result = yield
|
|
503
|
+
var result = yield router.lookup(req, res);
|
|
468
504
|
if ('after' in config && config.after) {
|
|
469
505
|
yield config.after(before, result);
|
|
470
506
|
}
|
|
@@ -475,7 +511,7 @@ function createFMWServer(config) {
|
|
|
475
511
|
}());
|
|
476
512
|
return {
|
|
477
513
|
server,
|
|
478
|
-
fmw
|
|
514
|
+
fmw: router
|
|
479
515
|
};
|
|
480
516
|
}
|
|
481
517
|
function createServer(config) {
|
|
@@ -490,5 +526,6 @@ exports.WrappedError = WrappedError;
|
|
|
490
526
|
exports.createFMWServer = createFMWServer;
|
|
491
527
|
exports.createGetContext = createGetContext;
|
|
492
528
|
exports.createServer = createServer;
|
|
529
|
+
exports.createUtilities = createUtilities;
|
|
493
530
|
exports.getBody = getBody;
|
|
494
531
|
exports.getLastEntryInMultiHeaderValue = getLastEntryInMultiHeaderValue;
|
|
@@ -7,9 +7,9 @@ var contentType = require('content-type');
|
|
|
7
7
|
var node_stream = require('node:stream');
|
|
8
8
|
var consumers = require('node:stream/consumers');
|
|
9
9
|
var getRawBody = require('raw-body');
|
|
10
|
-
var cookie = require('cookie');
|
|
11
10
|
var fmw = require('find-my-way');
|
|
12
11
|
var zod = require('zod');
|
|
12
|
+
var cookie = require('cookie');
|
|
13
13
|
var http = require('node:http');
|
|
14
14
|
|
|
15
15
|
function _interopDefault (e) { return e && e.__esModule ? e : { 'default': e }; }
|
|
@@ -103,100 +103,26 @@ function _asyncToGenerator(fn) {
|
|
|
103
103
|
};
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
-
function
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
}
|
|
114
|
-
function getBody(_x) {
|
|
115
|
-
return _getBody.apply(this, arguments);
|
|
116
|
-
}
|
|
117
|
-
function _getBody() {
|
|
118
|
-
_getBody = _asyncToGenerator(function* (req) {
|
|
119
|
-
if (!req.headers['content-type']) {
|
|
120
|
-
return null;
|
|
121
|
-
}
|
|
122
|
-
var buffer = yield getRawBody__default["default"](req.raw);
|
|
123
|
-
var {
|
|
124
|
-
type
|
|
125
|
-
} = contentType.parse(req.headers['content-type']);
|
|
126
|
-
switch (type) {
|
|
127
|
-
case 'application/json':
|
|
128
|
-
{
|
|
129
|
-
return consumers.json(node_stream.Readable.from(buffer));
|
|
130
|
-
}
|
|
131
|
-
default:
|
|
132
|
-
{
|
|
133
|
-
return null;
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
return _getBody.apply(this, arguments);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
class KaitoRequest {
|
|
141
|
-
constructor(raw) {
|
|
142
|
-
_defineProperty(this, "_url", null);
|
|
143
|
-
this.raw = raw;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* The full URL of the request, including the protocol, hostname, and path.
|
|
148
|
-
* Note: does not include the query string or hash
|
|
149
|
-
*/
|
|
150
|
-
get fullURL() {
|
|
151
|
-
var _this$raw$url;
|
|
152
|
-
return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
/**
|
|
156
|
-
* A new URL instance for the full URL of the request.
|
|
157
|
-
*/
|
|
158
|
-
get url() {
|
|
159
|
-
if (this._url) {
|
|
160
|
-
return this._url;
|
|
161
|
-
}
|
|
162
|
-
this._url = new URL(this.fullURL);
|
|
163
|
-
return this._url;
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
/**
|
|
167
|
-
* The HTTP method of the request.
|
|
168
|
-
*/
|
|
169
|
-
get method() {
|
|
170
|
-
if (!this.raw.method) {
|
|
171
|
-
throw new Error('Request method is not defined, somehow...');
|
|
172
|
-
}
|
|
173
|
-
return this.raw.method;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* The protocol of the request, either `http` or `https`.
|
|
178
|
-
*/
|
|
179
|
-
get protocol() {
|
|
180
|
-
if (this.raw.socket instanceof node_tls.TLSSocket) {
|
|
181
|
-
return this.raw.socket.encrypted ? 'https' : 'http';
|
|
182
|
-
}
|
|
183
|
-
return 'http';
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
/**
|
|
187
|
-
* The request headers
|
|
188
|
-
*/
|
|
189
|
-
get headers() {
|
|
190
|
-
return this.raw.headers;
|
|
106
|
+
function ownKeys(object, enumerableOnly) {
|
|
107
|
+
var keys = Object.keys(object);
|
|
108
|
+
if (Object.getOwnPropertySymbols) {
|
|
109
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
110
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
111
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
112
|
+
})), keys.push.apply(keys, symbols);
|
|
191
113
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
114
|
+
return keys;
|
|
115
|
+
}
|
|
116
|
+
function _objectSpread2(target) {
|
|
117
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
118
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
119
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
120
|
+
_defineProperty(target, key, source[key]);
|
|
121
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
122
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
123
|
+
});
|
|
199
124
|
}
|
|
125
|
+
return target;
|
|
200
126
|
}
|
|
201
127
|
|
|
202
128
|
class KaitoResponse {
|
|
@@ -251,28 +177,6 @@ class KaitoResponse {
|
|
|
251
177
|
}
|
|
252
178
|
}
|
|
253
179
|
|
|
254
|
-
function ownKeys(object, enumerableOnly) {
|
|
255
|
-
var keys = Object.keys(object);
|
|
256
|
-
if (Object.getOwnPropertySymbols) {
|
|
257
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
258
|
-
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
259
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
260
|
-
})), keys.push.apply(keys, symbols);
|
|
261
|
-
}
|
|
262
|
-
return keys;
|
|
263
|
-
}
|
|
264
|
-
function _objectSpread2(target) {
|
|
265
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
266
|
-
var source = null != arguments[i] ? arguments[i] : {};
|
|
267
|
-
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
268
|
-
_defineProperty(target, key, source[key]);
|
|
269
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
270
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
|
-
return target;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
180
|
var getSend = res => (status, response) => {
|
|
277
181
|
if (res.raw.headersSent) {
|
|
278
182
|
return;
|
|
@@ -349,7 +253,6 @@ class Router {
|
|
|
349
253
|
})();
|
|
350
254
|
}
|
|
351
255
|
constructor(routes) {
|
|
352
|
-
_defineProperty(this, "old_add", route => new Router([...this.routes, route]));
|
|
353
256
|
_defineProperty(this, "add", (method, path, route) => {
|
|
354
257
|
var merged = _objectSpread2(_objectSpread2({}, typeof route === 'object' ? route : {
|
|
355
258
|
run: route
|
|
@@ -365,7 +268,7 @@ class Router {
|
|
|
365
268
|
}));
|
|
366
269
|
return new Router([...this.routes, ...newRoutes]);
|
|
367
270
|
});
|
|
368
|
-
_defineProperty(this, "
|
|
271
|
+
_defineProperty(this, "freeze", server => {
|
|
369
272
|
var instance = fmw__default["default"]({
|
|
370
273
|
ignoreTrailingSlash: true,
|
|
371
274
|
defaultRoute(req, serverResponse) {
|
|
@@ -415,21 +318,154 @@ class Router {
|
|
|
415
318
|
}
|
|
416
319
|
return instance;
|
|
417
320
|
});
|
|
321
|
+
_defineProperty(this, "method", method => (path, route) => this.add(method, path, route));
|
|
322
|
+
_defineProperty(this, "get", this.method('GET'));
|
|
323
|
+
_defineProperty(this, "post", this.method('POST'));
|
|
324
|
+
_defineProperty(this, "put", this.method('PUT'));
|
|
325
|
+
_defineProperty(this, "patch", this.method('PATCH'));
|
|
326
|
+
_defineProperty(this, "delete", this.method('DELETE'));
|
|
327
|
+
_defineProperty(this, "head", this.method('HEAD'));
|
|
328
|
+
_defineProperty(this, "options", this.method('OPTIONS'));
|
|
418
329
|
this.routes = routes;
|
|
419
330
|
}
|
|
420
331
|
|
|
421
332
|
/**
|
|
422
333
|
* Adds a new route to the router
|
|
334
|
+
* @param method The HTTP method to add a route for
|
|
335
|
+
* @param path The path to add a route for
|
|
423
336
|
* @param route The route specification to add to this router
|
|
424
337
|
* @returns A new router with this route added
|
|
425
|
-
* @deprecated Use `Router#add` instead
|
|
426
338
|
*/
|
|
427
339
|
}
|
|
428
340
|
_defineProperty(Router, "create", () => new Router([]));
|
|
429
341
|
|
|
342
|
+
/**
|
|
343
|
+
* @deprecated use `createUtilities` instead
|
|
344
|
+
*/
|
|
345
|
+
function createGetContext(callback) {
|
|
346
|
+
return callback;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* A helper function to create typed necessary functions
|
|
351
|
+
*
|
|
352
|
+
* @example
|
|
353
|
+
* ```ts
|
|
354
|
+
* const {router, getContext} = createUtilities(async (req, res) => {
|
|
355
|
+
* // Return context here
|
|
356
|
+
* })
|
|
357
|
+
*
|
|
358
|
+
* const app = router().get('/', async () => "hello");
|
|
359
|
+
*
|
|
360
|
+
* const server = createServer({
|
|
361
|
+
* router: app,
|
|
362
|
+
* getContext,
|
|
363
|
+
* // ...
|
|
364
|
+
* });
|
|
365
|
+
* ```
|
|
366
|
+
*/
|
|
367
|
+
function createUtilities(getContext) {
|
|
368
|
+
return {
|
|
369
|
+
getContext,
|
|
370
|
+
router: () => Router.create()
|
|
371
|
+
};
|
|
372
|
+
}
|
|
373
|
+
function getLastEntryInMultiHeaderValue(headerValue) {
|
|
374
|
+
var normalized = Array.isArray(headerValue) ? headerValue.join(',') : headerValue;
|
|
375
|
+
var lastIndex = normalized.lastIndexOf(',');
|
|
376
|
+
return lastIndex === -1 ? normalized.trim() : normalized.slice(lastIndex + 1).trim();
|
|
377
|
+
}
|
|
378
|
+
function getBody(_x) {
|
|
379
|
+
return _getBody.apply(this, arguments);
|
|
380
|
+
}
|
|
381
|
+
function _getBody() {
|
|
382
|
+
_getBody = _asyncToGenerator(function* (req) {
|
|
383
|
+
if (!req.headers['content-type']) {
|
|
384
|
+
return null;
|
|
385
|
+
}
|
|
386
|
+
var buffer = yield getRawBody__default["default"](req.raw);
|
|
387
|
+
var {
|
|
388
|
+
type
|
|
389
|
+
} = contentType.parse(req.headers['content-type']);
|
|
390
|
+
switch (type) {
|
|
391
|
+
case 'application/json':
|
|
392
|
+
{
|
|
393
|
+
return consumers.json(node_stream.Readable.from(buffer));
|
|
394
|
+
}
|
|
395
|
+
default:
|
|
396
|
+
{
|
|
397
|
+
return null;
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
});
|
|
401
|
+
return _getBody.apply(this, arguments);
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
class KaitoRequest {
|
|
405
|
+
constructor(raw) {
|
|
406
|
+
_defineProperty(this, "_url", null);
|
|
407
|
+
this.raw = raw;
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* The full URL of the request, including the protocol, hostname, and path.
|
|
412
|
+
* Note: does not include the query string or hash
|
|
413
|
+
*/
|
|
414
|
+
get fullURL() {
|
|
415
|
+
var _this$raw$url;
|
|
416
|
+
return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
* A new URL instance for the full URL of the request.
|
|
421
|
+
*/
|
|
422
|
+
get url() {
|
|
423
|
+
if (this._url) {
|
|
424
|
+
return this._url;
|
|
425
|
+
}
|
|
426
|
+
this._url = new URL(this.fullURL);
|
|
427
|
+
return this._url;
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* The HTTP method of the request.
|
|
432
|
+
*/
|
|
433
|
+
get method() {
|
|
434
|
+
if (!this.raw.method) {
|
|
435
|
+
throw new Error('Request method is not defined, somehow...');
|
|
436
|
+
}
|
|
437
|
+
return this.raw.method;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* The protocol of the request, either `http` or `https`.
|
|
442
|
+
*/
|
|
443
|
+
get protocol() {
|
|
444
|
+
if (this.raw.socket instanceof node_tls.TLSSocket) {
|
|
445
|
+
return this.raw.socket.encrypted ? 'https' : 'http';
|
|
446
|
+
}
|
|
447
|
+
return 'http';
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
/**
|
|
451
|
+
* The request headers
|
|
452
|
+
*/
|
|
453
|
+
get headers() {
|
|
454
|
+
return this.raw.headers;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* The hostname of the request.
|
|
459
|
+
*/
|
|
460
|
+
get hostname() {
|
|
461
|
+
var _this$raw$headers$hos, _this$raw$headers$Au;
|
|
462
|
+
return (_this$raw$headers$hos = this.raw.headers.host) !== null && _this$raw$headers$hos !== void 0 ? _this$raw$headers$hos : getLastEntryInMultiHeaderValue((_this$raw$headers$Au = this.raw.headers[':authority']) !== null && _this$raw$headers$Au !== void 0 ? _this$raw$headers$Au : []);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
|
|
430
466
|
function createFMWServer(config) {
|
|
431
467
|
var _config$rawRoutes;
|
|
432
|
-
var
|
|
468
|
+
var router = config.router.freeze(config);
|
|
433
469
|
var rawRoutes = (_config$rawRoutes = config.rawRoutes) !== null && _config$rawRoutes !== void 0 ? _config$rawRoutes : {};
|
|
434
470
|
for (var method in rawRoutes) {
|
|
435
471
|
if (!Object.prototype.hasOwnProperty.call(rawRoutes, method)) {
|
|
@@ -441,10 +477,10 @@ function createFMWServer(config) {
|
|
|
441
477
|
}
|
|
442
478
|
for (var route of routes) {
|
|
443
479
|
if (method === '*') {
|
|
444
|
-
|
|
480
|
+
router.all(route.path, route.handler);
|
|
445
481
|
continue;
|
|
446
482
|
}
|
|
447
|
-
|
|
483
|
+
router[method.toLowerCase()](route.path, route.handler);
|
|
448
484
|
}
|
|
449
485
|
}
|
|
450
486
|
var server = http__namespace.createServer( /*#__PURE__*/function () {
|
|
@@ -460,7 +496,7 @@ function createFMWServer(config) {
|
|
|
460
496
|
if (res.headersSent) {
|
|
461
497
|
return;
|
|
462
498
|
}
|
|
463
|
-
var result = yield
|
|
499
|
+
var result = yield router.lookup(req, res);
|
|
464
500
|
if ('after' in config && config.after) {
|
|
465
501
|
yield config.after(before, result);
|
|
466
502
|
}
|
|
@@ -471,7 +507,7 @@ function createFMWServer(config) {
|
|
|
471
507
|
}());
|
|
472
508
|
return {
|
|
473
509
|
server,
|
|
474
|
-
fmw
|
|
510
|
+
fmw: router
|
|
475
511
|
};
|
|
476
512
|
}
|
|
477
513
|
function createServer(config) {
|
|
@@ -486,5 +522,6 @@ exports.WrappedError = WrappedError;
|
|
|
486
522
|
exports.createFMWServer = createFMWServer;
|
|
487
523
|
exports.createGetContext = createGetContext;
|
|
488
524
|
exports.createServer = createServer;
|
|
525
|
+
exports.createUtilities = createUtilities;
|
|
489
526
|
exports.getBody = getBody;
|
|
490
527
|
exports.getLastEntryInMultiHeaderValue = getLastEntryInMultiHeaderValue;
|
|
@@ -3,9 +3,9 @@ import { parse } from 'content-type';
|
|
|
3
3
|
import { Readable } from 'node:stream';
|
|
4
4
|
import { json } from 'node:stream/consumers';
|
|
5
5
|
import getRawBody from 'raw-body';
|
|
6
|
-
import { serialize } from 'cookie';
|
|
7
6
|
import fmw from 'find-my-way';
|
|
8
7
|
import { z } from 'zod';
|
|
8
|
+
import { serialize } from 'cookie';
|
|
9
9
|
import * as http from 'node:http';
|
|
10
10
|
|
|
11
11
|
class WrappedError extends Error {
|
|
@@ -75,104 +75,26 @@ function _asyncToGenerator(fn) {
|
|
|
75
75
|
};
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
function
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
}
|
|
86
|
-
function getBody(_x) {
|
|
87
|
-
return _getBody.apply(this, arguments);
|
|
88
|
-
}
|
|
89
|
-
function _getBody() {
|
|
90
|
-
_getBody = _asyncToGenerator(function* (req) {
|
|
91
|
-
if (!req.headers['content-type']) {
|
|
92
|
-
return null;
|
|
93
|
-
}
|
|
94
|
-
var buffer = yield getRawBody(req.raw);
|
|
95
|
-
var {
|
|
96
|
-
type
|
|
97
|
-
} = parse(req.headers['content-type']);
|
|
98
|
-
switch (type) {
|
|
99
|
-
case 'application/json':
|
|
100
|
-
{
|
|
101
|
-
return json(Readable.from(buffer));
|
|
102
|
-
}
|
|
103
|
-
default:
|
|
104
|
-
{
|
|
105
|
-
if (process.env.NODE_ENV === 'development') {
|
|
106
|
-
console.warn('[kaito] Unsupported content type:', type);
|
|
107
|
-
console.warn('[kaito] This message is only shown in development mode.');
|
|
108
|
-
}
|
|
109
|
-
return null;
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
});
|
|
113
|
-
return _getBody.apply(this, arguments);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
class KaitoRequest {
|
|
117
|
-
constructor(raw) {
|
|
118
|
-
_defineProperty(this, "_url", null);
|
|
119
|
-
this.raw = raw;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* The full URL of the request, including the protocol, hostname, and path.
|
|
124
|
-
* Note: does not include the query string or hash
|
|
125
|
-
*/
|
|
126
|
-
get fullURL() {
|
|
127
|
-
var _this$raw$url;
|
|
128
|
-
return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
/**
|
|
132
|
-
* A new URL instance for the full URL of the request.
|
|
133
|
-
*/
|
|
134
|
-
get url() {
|
|
135
|
-
if (this._url) {
|
|
136
|
-
return this._url;
|
|
137
|
-
}
|
|
138
|
-
this._url = new URL(this.fullURL);
|
|
139
|
-
return this._url;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/**
|
|
143
|
-
* The HTTP method of the request.
|
|
144
|
-
*/
|
|
145
|
-
get method() {
|
|
146
|
-
if (!this.raw.method) {
|
|
147
|
-
throw new Error('Request method is not defined, somehow...');
|
|
148
|
-
}
|
|
149
|
-
return this.raw.method;
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
/**
|
|
153
|
-
* The protocol of the request, either `http` or `https`.
|
|
154
|
-
*/
|
|
155
|
-
get protocol() {
|
|
156
|
-
if (this.raw.socket instanceof TLSSocket) {
|
|
157
|
-
return this.raw.socket.encrypted ? 'https' : 'http';
|
|
158
|
-
}
|
|
159
|
-
return 'http';
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
/**
|
|
163
|
-
* The request headers
|
|
164
|
-
*/
|
|
165
|
-
get headers() {
|
|
166
|
-
return this.raw.headers;
|
|
78
|
+
function ownKeys(object, enumerableOnly) {
|
|
79
|
+
var keys = Object.keys(object);
|
|
80
|
+
if (Object.getOwnPropertySymbols) {
|
|
81
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
82
|
+
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
83
|
+
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
84
|
+
})), keys.push.apply(keys, symbols);
|
|
167
85
|
}
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
86
|
+
return keys;
|
|
87
|
+
}
|
|
88
|
+
function _objectSpread2(target) {
|
|
89
|
+
for (var i = 1; i < arguments.length; i++) {
|
|
90
|
+
var source = null != arguments[i] ? arguments[i] : {};
|
|
91
|
+
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
92
|
+
_defineProperty(target, key, source[key]);
|
|
93
|
+
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
94
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
95
|
+
});
|
|
175
96
|
}
|
|
97
|
+
return target;
|
|
176
98
|
}
|
|
177
99
|
|
|
178
100
|
class KaitoResponse {
|
|
@@ -227,28 +149,6 @@ class KaitoResponse {
|
|
|
227
149
|
}
|
|
228
150
|
}
|
|
229
151
|
|
|
230
|
-
function ownKeys(object, enumerableOnly) {
|
|
231
|
-
var keys = Object.keys(object);
|
|
232
|
-
if (Object.getOwnPropertySymbols) {
|
|
233
|
-
var symbols = Object.getOwnPropertySymbols(object);
|
|
234
|
-
enumerableOnly && (symbols = symbols.filter(function (sym) {
|
|
235
|
-
return Object.getOwnPropertyDescriptor(object, sym).enumerable;
|
|
236
|
-
})), keys.push.apply(keys, symbols);
|
|
237
|
-
}
|
|
238
|
-
return keys;
|
|
239
|
-
}
|
|
240
|
-
function _objectSpread2(target) {
|
|
241
|
-
for (var i = 1; i < arguments.length; i++) {
|
|
242
|
-
var source = null != arguments[i] ? arguments[i] : {};
|
|
243
|
-
i % 2 ? ownKeys(Object(source), !0).forEach(function (key) {
|
|
244
|
-
_defineProperty(target, key, source[key]);
|
|
245
|
-
}) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) {
|
|
246
|
-
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
return target;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
152
|
var getSend = res => (status, response) => {
|
|
253
153
|
if (res.raw.headersSent) {
|
|
254
154
|
return;
|
|
@@ -325,7 +225,6 @@ class Router {
|
|
|
325
225
|
})();
|
|
326
226
|
}
|
|
327
227
|
constructor(routes) {
|
|
328
|
-
_defineProperty(this, "old_add", route => new Router([...this.routes, route]));
|
|
329
228
|
_defineProperty(this, "add", (method, path, route) => {
|
|
330
229
|
var merged = _objectSpread2(_objectSpread2({}, typeof route === 'object' ? route : {
|
|
331
230
|
run: route
|
|
@@ -341,7 +240,7 @@ class Router {
|
|
|
341
240
|
}));
|
|
342
241
|
return new Router([...this.routes, ...newRoutes]);
|
|
343
242
|
});
|
|
344
|
-
_defineProperty(this, "
|
|
243
|
+
_defineProperty(this, "freeze", server => {
|
|
345
244
|
var instance = fmw({
|
|
346
245
|
ignoreTrailingSlash: true,
|
|
347
246
|
defaultRoute(req, serverResponse) {
|
|
@@ -391,21 +290,158 @@ class Router {
|
|
|
391
290
|
}
|
|
392
291
|
return instance;
|
|
393
292
|
});
|
|
293
|
+
_defineProperty(this, "method", method => (path, route) => this.add(method, path, route));
|
|
294
|
+
_defineProperty(this, "get", this.method('GET'));
|
|
295
|
+
_defineProperty(this, "post", this.method('POST'));
|
|
296
|
+
_defineProperty(this, "put", this.method('PUT'));
|
|
297
|
+
_defineProperty(this, "patch", this.method('PATCH'));
|
|
298
|
+
_defineProperty(this, "delete", this.method('DELETE'));
|
|
299
|
+
_defineProperty(this, "head", this.method('HEAD'));
|
|
300
|
+
_defineProperty(this, "options", this.method('OPTIONS'));
|
|
394
301
|
this.routes = routes;
|
|
395
302
|
}
|
|
396
303
|
|
|
397
304
|
/**
|
|
398
305
|
* Adds a new route to the router
|
|
306
|
+
* @param method The HTTP method to add a route for
|
|
307
|
+
* @param path The path to add a route for
|
|
399
308
|
* @param route The route specification to add to this router
|
|
400
309
|
* @returns A new router with this route added
|
|
401
|
-
* @deprecated Use `Router#add` instead
|
|
402
310
|
*/
|
|
403
311
|
}
|
|
404
312
|
_defineProperty(Router, "create", () => new Router([]));
|
|
405
313
|
|
|
314
|
+
/**
|
|
315
|
+
* @deprecated use `createUtilities` instead
|
|
316
|
+
*/
|
|
317
|
+
function createGetContext(callback) {
|
|
318
|
+
return callback;
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/**
|
|
322
|
+
* A helper function to create typed necessary functions
|
|
323
|
+
*
|
|
324
|
+
* @example
|
|
325
|
+
* ```ts
|
|
326
|
+
* const {router, getContext} = createUtilities(async (req, res) => {
|
|
327
|
+
* // Return context here
|
|
328
|
+
* })
|
|
329
|
+
*
|
|
330
|
+
* const app = router().get('/', async () => "hello");
|
|
331
|
+
*
|
|
332
|
+
* const server = createServer({
|
|
333
|
+
* router: app,
|
|
334
|
+
* getContext,
|
|
335
|
+
* // ...
|
|
336
|
+
* });
|
|
337
|
+
* ```
|
|
338
|
+
*/
|
|
339
|
+
function createUtilities(getContext) {
|
|
340
|
+
return {
|
|
341
|
+
getContext,
|
|
342
|
+
router: () => Router.create()
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function getLastEntryInMultiHeaderValue(headerValue) {
|
|
346
|
+
var normalized = Array.isArray(headerValue) ? headerValue.join(',') : headerValue;
|
|
347
|
+
var lastIndex = normalized.lastIndexOf(',');
|
|
348
|
+
return lastIndex === -1 ? normalized.trim() : normalized.slice(lastIndex + 1).trim();
|
|
349
|
+
}
|
|
350
|
+
function getBody(_x) {
|
|
351
|
+
return _getBody.apply(this, arguments);
|
|
352
|
+
}
|
|
353
|
+
function _getBody() {
|
|
354
|
+
_getBody = _asyncToGenerator(function* (req) {
|
|
355
|
+
if (!req.headers['content-type']) {
|
|
356
|
+
return null;
|
|
357
|
+
}
|
|
358
|
+
var buffer = yield getRawBody(req.raw);
|
|
359
|
+
var {
|
|
360
|
+
type
|
|
361
|
+
} = parse(req.headers['content-type']);
|
|
362
|
+
switch (type) {
|
|
363
|
+
case 'application/json':
|
|
364
|
+
{
|
|
365
|
+
return json(Readable.from(buffer));
|
|
366
|
+
}
|
|
367
|
+
default:
|
|
368
|
+
{
|
|
369
|
+
if (process.env.NODE_ENV === 'development') {
|
|
370
|
+
console.warn('[kaito] Unsupported content type:', type);
|
|
371
|
+
console.warn('[kaito] This message is only shown in development mode.');
|
|
372
|
+
}
|
|
373
|
+
return null;
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
});
|
|
377
|
+
return _getBody.apply(this, arguments);
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
class KaitoRequest {
|
|
381
|
+
constructor(raw) {
|
|
382
|
+
_defineProperty(this, "_url", null);
|
|
383
|
+
this.raw = raw;
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
* The full URL of the request, including the protocol, hostname, and path.
|
|
388
|
+
* Note: does not include the query string or hash
|
|
389
|
+
*/
|
|
390
|
+
get fullURL() {
|
|
391
|
+
var _this$raw$url;
|
|
392
|
+
return "".concat(this.protocol, "://").concat(this.hostname).concat((_this$raw$url = this.raw.url) !== null && _this$raw$url !== void 0 ? _this$raw$url : '');
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* A new URL instance for the full URL of the request.
|
|
397
|
+
*/
|
|
398
|
+
get url() {
|
|
399
|
+
if (this._url) {
|
|
400
|
+
return this._url;
|
|
401
|
+
}
|
|
402
|
+
this._url = new URL(this.fullURL);
|
|
403
|
+
return this._url;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
/**
|
|
407
|
+
* The HTTP method of the request.
|
|
408
|
+
*/
|
|
409
|
+
get method() {
|
|
410
|
+
if (!this.raw.method) {
|
|
411
|
+
throw new Error('Request method is not defined, somehow...');
|
|
412
|
+
}
|
|
413
|
+
return this.raw.method;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
/**
|
|
417
|
+
* The protocol of the request, either `http` or `https`.
|
|
418
|
+
*/
|
|
419
|
+
get protocol() {
|
|
420
|
+
if (this.raw.socket instanceof TLSSocket) {
|
|
421
|
+
return this.raw.socket.encrypted ? 'https' : 'http';
|
|
422
|
+
}
|
|
423
|
+
return 'http';
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* The request headers
|
|
428
|
+
*/
|
|
429
|
+
get headers() {
|
|
430
|
+
return this.raw.headers;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
/**
|
|
434
|
+
* The hostname of the request.
|
|
435
|
+
*/
|
|
436
|
+
get hostname() {
|
|
437
|
+
var _this$raw$headers$hos, _this$raw$headers$Au;
|
|
438
|
+
return (_this$raw$headers$hos = this.raw.headers.host) !== null && _this$raw$headers$hos !== void 0 ? _this$raw$headers$hos : getLastEntryInMultiHeaderValue((_this$raw$headers$Au = this.raw.headers[':authority']) !== null && _this$raw$headers$Au !== void 0 ? _this$raw$headers$Au : []);
|
|
439
|
+
}
|
|
440
|
+
}
|
|
441
|
+
|
|
406
442
|
function createFMWServer(config) {
|
|
407
443
|
var _config$rawRoutes;
|
|
408
|
-
var
|
|
444
|
+
var router = config.router.freeze(config);
|
|
409
445
|
var rawRoutes = (_config$rawRoutes = config.rawRoutes) !== null && _config$rawRoutes !== void 0 ? _config$rawRoutes : {};
|
|
410
446
|
for (var method in rawRoutes) {
|
|
411
447
|
if (!Object.prototype.hasOwnProperty.call(rawRoutes, method)) {
|
|
@@ -417,10 +453,10 @@ function createFMWServer(config) {
|
|
|
417
453
|
}
|
|
418
454
|
for (var route of routes) {
|
|
419
455
|
if (method === '*') {
|
|
420
|
-
|
|
456
|
+
router.all(route.path, route.handler);
|
|
421
457
|
continue;
|
|
422
458
|
}
|
|
423
|
-
|
|
459
|
+
router[method.toLowerCase()](route.path, route.handler);
|
|
424
460
|
}
|
|
425
461
|
}
|
|
426
462
|
var server = http.createServer( /*#__PURE__*/function () {
|
|
@@ -436,7 +472,7 @@ function createFMWServer(config) {
|
|
|
436
472
|
if (res.headersSent) {
|
|
437
473
|
return;
|
|
438
474
|
}
|
|
439
|
-
var result = yield
|
|
475
|
+
var result = yield router.lookup(req, res);
|
|
440
476
|
if ('after' in config && config.after) {
|
|
441
477
|
yield config.after(before, result);
|
|
442
478
|
}
|
|
@@ -447,11 +483,11 @@ function createFMWServer(config) {
|
|
|
447
483
|
}());
|
|
448
484
|
return {
|
|
449
485
|
server,
|
|
450
|
-
fmw
|
|
486
|
+
fmw: router
|
|
451
487
|
};
|
|
452
488
|
}
|
|
453
489
|
function createServer(config) {
|
|
454
490
|
return createFMWServer(config).server;
|
|
455
491
|
}
|
|
456
492
|
|
|
457
|
-
export { KaitoError, KaitoRequest, KaitoResponse, Router, WrappedError, createFMWServer, createGetContext, createServer, getBody, getLastEntryInMultiHeaderValue };
|
|
493
|
+
export { KaitoError, KaitoRequest, KaitoResponse, Router, WrappedError, createFMWServer, createGetContext, createServer, createUtilities, getBody, getLastEntryInMultiHeaderValue };
|