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