@kaito-http/core 3.0.0-beta.8 → 3.0.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/index.cjs +225 -320
- package/dist/index.d.cts +166 -148
- package/dist/index.d.ts +166 -148
- package/dist/index.js +220 -301
- package/dist/stream/stream.cjs +134 -0
- package/dist/stream/stream.d.cts +36 -0
- package/dist/stream/stream.d.ts +36 -0
- package/dist/stream/stream.js +105 -0
- package/package.json +21 -15
- package/src/error.ts +26 -0
- package/src/handler.ts +96 -0
- package/src/head.ts +83 -0
- package/src/index.ts +7 -0
- package/src/request.ts +47 -0
- package/src/route.ts +52 -0
- package/src/router/router.test.ts +269 -0
- package/src/router/router.ts +264 -0
- package/src/router/types.ts +1 -0
- package/src/stream/stream.ts +156 -0
- package/src/util.ts +83 -0
package/dist/index.cjs
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __create = Object.create;
|
|
3
2
|
var __defProp = Object.defineProperty;
|
|
4
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
6
|
var __export = (target, all) => {
|
|
9
7
|
for (var name in all)
|
|
@@ -17,33 +15,21 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
15
|
}
|
|
18
16
|
return to;
|
|
19
17
|
};
|
|
20
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
-
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
-
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
-
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
-
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
-
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
-
mod
|
|
27
|
-
));
|
|
28
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
19
|
|
|
30
20
|
// src/index.ts
|
|
31
|
-
var
|
|
32
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
33
23
|
KaitoError: () => KaitoError,
|
|
34
24
|
KaitoRequest: () => KaitoRequest,
|
|
35
|
-
KaitoResponse: () => KaitoResponse,
|
|
36
25
|
Router: () => Router,
|
|
37
26
|
WrappedError: () => WrappedError,
|
|
38
|
-
|
|
39
|
-
createGetContext: () => createGetContext,
|
|
40
|
-
createServer: () => createServer2,
|
|
27
|
+
createKaitoHandler: () => createKaitoHandler,
|
|
41
28
|
createUtilities: () => createUtilities,
|
|
42
|
-
|
|
43
|
-
getLastEntryInMultiHeaderValue: () => getLastEntryInMultiHeaderValue,
|
|
29
|
+
isNodeLikeDev: () => isNodeLikeDev,
|
|
44
30
|
parsable: () => parsable
|
|
45
31
|
});
|
|
46
|
-
module.exports = __toCommonJS(
|
|
32
|
+
module.exports = __toCommonJS(index_exports);
|
|
47
33
|
|
|
48
34
|
// src/error.ts
|
|
49
35
|
var WrappedError = class _WrappedError extends Error {
|
|
@@ -68,205 +54,265 @@ var KaitoError = class extends Error {
|
|
|
68
54
|
}
|
|
69
55
|
};
|
|
70
56
|
|
|
71
|
-
// src/
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
57
|
+
// src/handler.ts
|
|
58
|
+
function createKaitoHandler(config) {
|
|
59
|
+
const handle = config.router.freeze(config);
|
|
60
|
+
return async (request) => {
|
|
61
|
+
if (config.before) {
|
|
62
|
+
const result = await config.before(request);
|
|
63
|
+
if (result instanceof Response) {
|
|
64
|
+
if (config.transform) {
|
|
65
|
+
const result2 = await config.transform(request, result);
|
|
66
|
+
if (result2 instanceof Response) return result;
|
|
67
|
+
}
|
|
68
|
+
return result;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const response = await handle(request);
|
|
72
|
+
if (config.transform) {
|
|
73
|
+
const result = await config.transform(request, response);
|
|
74
|
+
if (result instanceof Response) return result;
|
|
75
|
+
}
|
|
76
|
+
return response;
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
79
|
|
|
80
|
-
// src/
|
|
81
|
-
var
|
|
80
|
+
// src/request.ts
|
|
81
|
+
var KaitoRequest = class {
|
|
82
|
+
url;
|
|
83
|
+
_request;
|
|
84
|
+
constructor(url, request) {
|
|
85
|
+
this._request = request;
|
|
86
|
+
this.url = url;
|
|
87
|
+
}
|
|
88
|
+
get headers() {
|
|
89
|
+
return this._request.headers;
|
|
90
|
+
}
|
|
91
|
+
get method() {
|
|
92
|
+
return this._request.method;
|
|
93
|
+
}
|
|
94
|
+
async arrayBuffer() {
|
|
95
|
+
return this._request.arrayBuffer();
|
|
96
|
+
}
|
|
97
|
+
async blob() {
|
|
98
|
+
return this._request.blob();
|
|
99
|
+
}
|
|
100
|
+
async formData() {
|
|
101
|
+
return this._request.formData();
|
|
102
|
+
}
|
|
103
|
+
async bytes() {
|
|
104
|
+
const buffer = await this.arrayBuffer();
|
|
105
|
+
return new Uint8Array(buffer);
|
|
106
|
+
}
|
|
107
|
+
async json() {
|
|
108
|
+
return this._request.json();
|
|
109
|
+
}
|
|
110
|
+
async text() {
|
|
111
|
+
return this._request.text();
|
|
112
|
+
}
|
|
113
|
+
get request() {
|
|
114
|
+
return this._request;
|
|
115
|
+
}
|
|
116
|
+
};
|
|
82
117
|
|
|
83
|
-
// src/
|
|
84
|
-
var
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
118
|
+
// src/head.ts
|
|
119
|
+
var KaitoHead = class {
|
|
120
|
+
_headers;
|
|
121
|
+
_status;
|
|
122
|
+
constructor() {
|
|
123
|
+
this._headers = null;
|
|
124
|
+
this._status = 200;
|
|
88
125
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
*/
|
|
95
|
-
header(key, value) {
|
|
96
|
-
this.raw.setHeader(key, value);
|
|
97
|
-
return this;
|
|
126
|
+
get headers() {
|
|
127
|
+
if (this._headers === null) {
|
|
128
|
+
this._headers = new Headers();
|
|
129
|
+
}
|
|
130
|
+
return this._headers;
|
|
98
131
|
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
status(code) {
|
|
105
|
-
this.raw.statusCode = code;
|
|
132
|
+
status(status) {
|
|
133
|
+
if (status === void 0) {
|
|
134
|
+
return this._status;
|
|
135
|
+
}
|
|
136
|
+
this._status = status;
|
|
106
137
|
return this;
|
|
107
138
|
}
|
|
108
139
|
/**
|
|
109
|
-
*
|
|
110
|
-
* @param
|
|
111
|
-
* @
|
|
112
|
-
* @param options The options for the cookie
|
|
113
|
-
* @returns The response object
|
|
140
|
+
* Turn this KaitoHead instance into a Response instance
|
|
141
|
+
* @param body The Kaito JSON format to be sent as the response body
|
|
142
|
+
* @returns A Response instance, ready to be sent
|
|
114
143
|
*/
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
144
|
+
toResponse(body) {
|
|
145
|
+
const init = {
|
|
146
|
+
status: this._status
|
|
147
|
+
};
|
|
148
|
+
if (this._headers) {
|
|
149
|
+
init.headers = this._headers;
|
|
150
|
+
}
|
|
151
|
+
return Response.json(body, init);
|
|
118
152
|
}
|
|
119
153
|
/**
|
|
120
|
-
*
|
|
121
|
-
* @param data The data to send
|
|
122
|
-
* @returns The response object
|
|
154
|
+
* Whether this KaitoHead instance has been touched/modified
|
|
123
155
|
*/
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
this.raw.setHeader("Content-Type", "application/json");
|
|
127
|
-
this.raw.setHeader("Content-Length", Buffer.byteLength(json2));
|
|
128
|
-
this.raw.end(json2);
|
|
129
|
-
return this;
|
|
156
|
+
get touched() {
|
|
157
|
+
return this._status !== 200 || this._headers !== null;
|
|
130
158
|
}
|
|
131
159
|
};
|
|
132
160
|
|
|
133
|
-
// src/
|
|
134
|
-
var
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
};
|
|
161
|
+
// src/util.ts
|
|
162
|
+
var isNodeLikeDev = typeof process !== "undefined" && typeof process.env !== "undefined" && process.env.NODE_ENV === "development";
|
|
163
|
+
function createUtilities(getContext) {
|
|
164
|
+
return {
|
|
165
|
+
getContext,
|
|
166
|
+
router: () => Router.create()
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
function parsable(parse) {
|
|
170
|
+
return {
|
|
171
|
+
parse
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// src/router/router.ts
|
|
140
176
|
var Router = class _Router {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
177
|
+
state;
|
|
178
|
+
static create = () => new _Router({
|
|
179
|
+
through: async (context) => context,
|
|
180
|
+
routes: /* @__PURE__ */ new Set()
|
|
145
181
|
});
|
|
146
182
|
static parseQuery(schema, url) {
|
|
147
183
|
if (!schema) {
|
|
148
184
|
return {};
|
|
149
185
|
}
|
|
150
186
|
const result = {};
|
|
151
|
-
for (const
|
|
187
|
+
for (const key in schema) {
|
|
188
|
+
if (!schema.hasOwnProperty(key)) continue;
|
|
152
189
|
const value = url.searchParams.get(key);
|
|
153
|
-
result[key] =
|
|
190
|
+
result[key] = schema[key].parse(value);
|
|
154
191
|
}
|
|
155
192
|
return result;
|
|
156
193
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
try {
|
|
160
|
-
const rootCtx = await server.getContext(options.req, options.res);
|
|
161
|
-
const ctx = await route.through(rootCtx);
|
|
162
|
-
const body = await route.body?.parse(await getBody(options.req)) ?? void 0;
|
|
163
|
-
const query = _Router.parseQuery(route.query, options.req.url);
|
|
164
|
-
const result = await route.run({
|
|
165
|
-
ctx,
|
|
166
|
-
body,
|
|
167
|
-
query,
|
|
168
|
-
params: options.params
|
|
169
|
-
});
|
|
170
|
-
if (options.res.raw.headersSent) {
|
|
171
|
-
return {
|
|
172
|
-
success: true,
|
|
173
|
-
data: result
|
|
174
|
-
};
|
|
175
|
-
}
|
|
176
|
-
send(200, {
|
|
177
|
-
success: true,
|
|
178
|
-
data: result,
|
|
179
|
-
message: "OK"
|
|
180
|
-
});
|
|
181
|
-
return {
|
|
182
|
-
success: true,
|
|
183
|
-
data: result
|
|
184
|
-
};
|
|
185
|
-
} catch (e) {
|
|
186
|
-
const error = WrappedError.maybe(e);
|
|
187
|
-
if (error instanceof KaitoError) {
|
|
188
|
-
send(error.status, {
|
|
189
|
-
success: false,
|
|
190
|
-
data: null,
|
|
191
|
-
message: error.message
|
|
192
|
-
});
|
|
193
|
-
return;
|
|
194
|
-
}
|
|
195
|
-
const { status, message } = await server.onError({ error, req: options.req, res: options.res }).catch(() => ({ status: 500, message: "Internal Server Error" }));
|
|
196
|
-
send(status, {
|
|
197
|
-
success: false,
|
|
198
|
-
data: null,
|
|
199
|
-
message
|
|
200
|
-
});
|
|
201
|
-
return {
|
|
202
|
-
success: false,
|
|
203
|
-
data: { status, message }
|
|
204
|
-
};
|
|
205
|
-
}
|
|
194
|
+
constructor(options) {
|
|
195
|
+
this.state = options;
|
|
206
196
|
}
|
|
207
|
-
|
|
208
|
-
this.
|
|
209
|
-
this.routes = new Set(routes);
|
|
197
|
+
get routes() {
|
|
198
|
+
return this.state.routes;
|
|
210
199
|
}
|
|
211
|
-
/**
|
|
212
|
-
* Adds a new route to the router
|
|
213
|
-
* @deprecated Use the method-specific methods instead
|
|
214
|
-
*/
|
|
215
200
|
add = (method, path, route) => {
|
|
216
201
|
const merged = {
|
|
202
|
+
// TODO: Ideally fix the typing here, but this will be replaced in Kaito v4 where all routes must return a Response (which we can type)
|
|
217
203
|
...typeof route === "object" ? route : { run: route },
|
|
218
204
|
method,
|
|
219
205
|
path,
|
|
220
|
-
through: this.
|
|
206
|
+
through: this.state.through
|
|
221
207
|
};
|
|
222
|
-
return new _Router(
|
|
208
|
+
return new _Router({
|
|
209
|
+
...this.state,
|
|
210
|
+
routes: /* @__PURE__ */ new Set([...this.state.routes, merged])
|
|
211
|
+
});
|
|
223
212
|
};
|
|
224
213
|
merge = (pathPrefix, other) => {
|
|
225
|
-
const newRoutes = [...other.routes].map((route) => ({
|
|
214
|
+
const newRoutes = [...other.state.routes].map((route) => ({
|
|
226
215
|
...route,
|
|
227
216
|
path: `${pathPrefix}${route.path}`
|
|
228
217
|
}));
|
|
229
|
-
return new _Router(
|
|
230
|
-
|
|
231
|
-
this.
|
|
232
|
-
);
|
|
218
|
+
return new _Router({
|
|
219
|
+
...this.state,
|
|
220
|
+
routes: /* @__PURE__ */ new Set([...this.state.routes, ...newRoutes])
|
|
221
|
+
});
|
|
233
222
|
};
|
|
234
|
-
// Allow for any server context to be passed
|
|
235
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
236
223
|
freeze = (server) => {
|
|
237
|
-
const
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
224
|
+
const routes = /* @__PURE__ */ new Map();
|
|
225
|
+
for (const route of this.state.routes) {
|
|
226
|
+
if (!routes.has(route.path)) {
|
|
227
|
+
routes.set(route.path, /* @__PURE__ */ new Map());
|
|
228
|
+
}
|
|
229
|
+
routes.get(route.path).set(route.method, route);
|
|
230
|
+
}
|
|
231
|
+
const findRoute = (method, path) => {
|
|
232
|
+
const params = {};
|
|
233
|
+
const pathParts = path.split("/").filter(Boolean);
|
|
234
|
+
for (const [routePath, methodHandlers] of routes) {
|
|
235
|
+
const routeParts = routePath.split("/").filter(Boolean);
|
|
236
|
+
if (routeParts.length !== pathParts.length) continue;
|
|
237
|
+
let matches = true;
|
|
238
|
+
for (let i = 0; i < routeParts.length; i++) {
|
|
239
|
+
const routePart = routeParts[i];
|
|
240
|
+
const pathPart = pathParts[i];
|
|
241
|
+
if (routePart && pathPart && routePart.startsWith(":")) {
|
|
242
|
+
params[routePart.slice(1)] = pathPart;
|
|
243
|
+
} else if (routePart !== pathPart) {
|
|
244
|
+
matches = false;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
if (matches) {
|
|
249
|
+
const route = methodHandlers.get(method);
|
|
250
|
+
if (route) return { route, params };
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
return { params };
|
|
254
|
+
};
|
|
255
|
+
return async (req) => {
|
|
256
|
+
const url = new URL(req.url);
|
|
257
|
+
const method = req.method;
|
|
258
|
+
const { route, params } = findRoute(method, url.pathname);
|
|
259
|
+
if (!route) {
|
|
260
|
+
const body = {
|
|
243
261
|
success: false,
|
|
244
262
|
data: null,
|
|
245
|
-
message
|
|
246
|
-
});
|
|
247
|
-
return {
|
|
248
|
-
success: false,
|
|
249
|
-
data: { status: 404, message }
|
|
263
|
+
message: `Cannot ${method} ${url.pathname}`
|
|
250
264
|
};
|
|
265
|
+
return Response.json(body, { status: 404 });
|
|
251
266
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
267
|
+
const request = new KaitoRequest(url, req);
|
|
268
|
+
const head = new KaitoHead();
|
|
269
|
+
try {
|
|
270
|
+
const body = route.body ? await route.body.parse(await req.json()) : void 0;
|
|
271
|
+
const query = _Router.parseQuery(route.query, url);
|
|
272
|
+
const rootCtx = await server.getContext(request, head);
|
|
273
|
+
const ctx = await route.through(rootCtx);
|
|
274
|
+
const result = await route.run({
|
|
275
|
+
ctx,
|
|
276
|
+
body,
|
|
277
|
+
query,
|
|
278
|
+
params
|
|
279
|
+
});
|
|
280
|
+
if (result instanceof Response) {
|
|
281
|
+
if (isNodeLikeDev) {
|
|
282
|
+
if (head.touched) {
|
|
283
|
+
const msg = [
|
|
284
|
+
"Kaito detected that you used the KaitoHead object to modify the headers or status, but then returned a Response in the route",
|
|
285
|
+
"This is usually a mistake, as your Response object will override any changes you made to the headers or status code.",
|
|
286
|
+
"",
|
|
287
|
+
"This warning was shown because `process.env.NODE_ENV=development`"
|
|
288
|
+
].join("\n");
|
|
289
|
+
console.warn(msg);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
return head.toResponse({
|
|
295
|
+
success: true,
|
|
296
|
+
data: result,
|
|
297
|
+
message: "OK"
|
|
298
|
+
});
|
|
299
|
+
} catch (e) {
|
|
300
|
+
const error = WrappedError.maybe(e);
|
|
301
|
+
if (error instanceof KaitoError) {
|
|
302
|
+
return head.status(error.status).toResponse({
|
|
303
|
+
success: false,
|
|
304
|
+
data: null,
|
|
305
|
+
message: error.message
|
|
306
|
+
});
|
|
307
|
+
}
|
|
308
|
+
const { status, message } = await server.onError({ error, req: request }).catch(() => ({ status: 500, message: "Internal Server Error" }));
|
|
309
|
+
return head.status(status).toResponse({
|
|
310
|
+
success: false,
|
|
311
|
+
data: null,
|
|
312
|
+
message
|
|
261
313
|
});
|
|
262
|
-
};
|
|
263
|
-
if (route.method === "*") {
|
|
264
|
-
instance.all(route.path, handler);
|
|
265
|
-
continue;
|
|
266
314
|
}
|
|
267
|
-
|
|
268
|
-
}
|
|
269
|
-
return instance;
|
|
315
|
+
};
|
|
270
316
|
};
|
|
271
317
|
method = (method) => (path, route) => {
|
|
272
318
|
return this.add(method, path, route);
|
|
@@ -278,162 +324,21 @@ var Router = class _Router {
|
|
|
278
324
|
delete = this.method("DELETE");
|
|
279
325
|
head = this.method("HEAD");
|
|
280
326
|
options = this.method("OPTIONS");
|
|
281
|
-
through = (
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
}
|
|
286
|
-
});
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
// src/util.ts
|
|
290
|
-
function createGetContext(callback) {
|
|
291
|
-
return callback;
|
|
292
|
-
}
|
|
293
|
-
function createUtilities(getContext) {
|
|
294
|
-
return {
|
|
295
|
-
getContext,
|
|
296
|
-
router: () => Router.create()
|
|
297
|
-
};
|
|
298
|
-
}
|
|
299
|
-
function getLastEntryInMultiHeaderValue(headerValue) {
|
|
300
|
-
const normalized = Array.isArray(headerValue) ? headerValue.join(",") : headerValue;
|
|
301
|
-
const lastIndex = normalized.lastIndexOf(",");
|
|
302
|
-
return lastIndex === -1 ? normalized.trim() : normalized.slice(lastIndex + 1).trim();
|
|
303
|
-
}
|
|
304
|
-
function parsable(parse) {
|
|
305
|
-
return {
|
|
306
|
-
parse
|
|
327
|
+
through = (through) => {
|
|
328
|
+
return new _Router({
|
|
329
|
+
...this.state,
|
|
330
|
+
through: async (context) => through(await this.state.through(context))
|
|
331
|
+
});
|
|
307
332
|
};
|
|
308
|
-
}
|
|
309
|
-
async function getBody(req) {
|
|
310
|
-
if (!req.headers["content-type"]) {
|
|
311
|
-
return null;
|
|
312
|
-
}
|
|
313
|
-
const buffer = await (0, import_raw_body.default)(req.raw);
|
|
314
|
-
const { type } = (0, import_content_type.parse)(req.headers["content-type"]);
|
|
315
|
-
switch (type) {
|
|
316
|
-
case "application/json": {
|
|
317
|
-
return (0, import_consumers.json)(import_node_stream.Readable.from(buffer));
|
|
318
|
-
}
|
|
319
|
-
default: {
|
|
320
|
-
if (process.env.NODE_ENV === "development") {
|
|
321
|
-
console.warn("[kaito] Unsupported content type:", type);
|
|
322
|
-
console.warn("[kaito] This message is only shown in development mode.");
|
|
323
|
-
}
|
|
324
|
-
return null;
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// src/req.ts
|
|
330
|
-
var KaitoRequest = class {
|
|
331
|
-
constructor(raw) {
|
|
332
|
-
this.raw = raw;
|
|
333
|
-
}
|
|
334
|
-
_url = null;
|
|
335
|
-
/**
|
|
336
|
-
* The full URL of the request, including the protocol, hostname, and path.
|
|
337
|
-
* Note: does not include the query string or hash
|
|
338
|
-
*/
|
|
339
|
-
get fullURL() {
|
|
340
|
-
return `${this.protocol}://${this.hostname}${this.raw.url ?? ""}`;
|
|
341
|
-
}
|
|
342
|
-
/**
|
|
343
|
-
* A new URL instance for the full URL of the request.
|
|
344
|
-
*/
|
|
345
|
-
get url() {
|
|
346
|
-
if (this._url) {
|
|
347
|
-
return this._url;
|
|
348
|
-
}
|
|
349
|
-
this._url = new URL(this.fullURL);
|
|
350
|
-
return this._url;
|
|
351
|
-
}
|
|
352
|
-
/**
|
|
353
|
-
* The HTTP method of the request.
|
|
354
|
-
*/
|
|
355
|
-
get method() {
|
|
356
|
-
if (!this.raw.method) {
|
|
357
|
-
throw new Error("Request method is not defined, somehow...");
|
|
358
|
-
}
|
|
359
|
-
return this.raw.method;
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* The protocol of the request, either `http` or `https`.
|
|
363
|
-
*/
|
|
364
|
-
get protocol() {
|
|
365
|
-
if (this.raw.socket instanceof import_node_tls.TLSSocket) {
|
|
366
|
-
return this.raw.socket.encrypted ? "https" : "http";
|
|
367
|
-
}
|
|
368
|
-
return "http";
|
|
369
|
-
}
|
|
370
|
-
/**
|
|
371
|
-
* The request headers
|
|
372
|
-
*/
|
|
373
|
-
get headers() {
|
|
374
|
-
return this.raw.headers;
|
|
375
|
-
}
|
|
376
|
-
/**
|
|
377
|
-
* The hostname of the request.
|
|
378
|
-
*/
|
|
379
|
-
get hostname() {
|
|
380
|
-
return this.raw.headers.host ?? getLastEntryInMultiHeaderValue(this.raw.headers[":authority"] ?? []);
|
|
381
|
-
}
|
|
382
333
|
};
|
|
383
|
-
|
|
384
|
-
// src/server.ts
|
|
385
|
-
var http = __toESM(require("http"), 1);
|
|
386
|
-
function createFMWServer(config) {
|
|
387
|
-
const router = config.router.freeze(config);
|
|
388
|
-
const rawRoutes = config.rawRoutes ?? {};
|
|
389
|
-
for (const method in rawRoutes) {
|
|
390
|
-
if (!Object.prototype.hasOwnProperty.call(rawRoutes, method)) {
|
|
391
|
-
continue;
|
|
392
|
-
}
|
|
393
|
-
const routes = rawRoutes[method];
|
|
394
|
-
if (!routes || routes.length === 0) {
|
|
395
|
-
continue;
|
|
396
|
-
}
|
|
397
|
-
for (const route of routes) {
|
|
398
|
-
if (method === "*") {
|
|
399
|
-
router.all(route.path, route.handler);
|
|
400
|
-
continue;
|
|
401
|
-
}
|
|
402
|
-
router[method.toLowerCase()](route.path, route.handler);
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
const server = http.createServer(async (req, res) => {
|
|
406
|
-
let before;
|
|
407
|
-
if (config.before) {
|
|
408
|
-
before = await config.before(req, res);
|
|
409
|
-
} else {
|
|
410
|
-
before = void 0;
|
|
411
|
-
}
|
|
412
|
-
if (res.headersSent) {
|
|
413
|
-
return;
|
|
414
|
-
}
|
|
415
|
-
const result = await router.lookup(req, res);
|
|
416
|
-
if ("after" in config && config.after) {
|
|
417
|
-
await config.after(before, result);
|
|
418
|
-
}
|
|
419
|
-
});
|
|
420
|
-
return { server, fmw: router };
|
|
421
|
-
}
|
|
422
|
-
function createServer2(config) {
|
|
423
|
-
return createFMWServer(config).server;
|
|
424
|
-
}
|
|
425
334
|
// Annotate the CommonJS export names for ESM import in node:
|
|
426
335
|
0 && (module.exports = {
|
|
427
336
|
KaitoError,
|
|
428
337
|
KaitoRequest,
|
|
429
|
-
KaitoResponse,
|
|
430
338
|
Router,
|
|
431
339
|
WrappedError,
|
|
432
|
-
|
|
433
|
-
createGetContext,
|
|
434
|
-
createServer,
|
|
340
|
+
createKaitoHandler,
|
|
435
341
|
createUtilities,
|
|
436
|
-
|
|
437
|
-
getLastEntryInMultiHeaderValue,
|
|
342
|
+
isNodeLikeDev,
|
|
438
343
|
parsable
|
|
439
344
|
});
|