diesel-core 1.6.8 → 1.7.0
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/constant.js +11 -0
- package/dist/ctx.d.ts +6 -6
- package/dist/ctx.js +326 -0
- package/dist/handleRequest.d.ts +2 -2
- package/dist/handleRequest.js +83 -0
- package/dist/http-exception.js +20 -0
- package/dist/http-exception.test.js +50 -0
- package/dist/main.d.ts +1 -1
- package/dist/main.js +686 -0
- package/dist/middlewares/cors/index.test.js +94 -0
- package/dist/middlewares/file-route/index.js +69 -0
- package/dist/middlewares/filesave/index.test.js +73 -0
- package/dist/middlewares/filesave/savefile.js +1 -1
- package/dist/middlewares/jwt/index.js +1 -1
- package/dist/middlewares/jwt/index.test.js +74 -0
- package/dist/middlewares/powered-by/index.js +1 -1
- package/dist/middlewares/powered-by/index.test.js +46 -0
- package/dist/middlewares/ratelimit/index.test.js +104 -0
- package/dist/middlewares/request-id/index.js +50 -0
- package/dist/middlewares/request-id/index.test.js +1 -0
- package/dist/middlewares/security/index.test.js +50 -0
- package/dist/request_pipeline.js +353 -0
- package/dist/router/find-my-way.js +18 -0
- package/dist/router/interface.js +22 -0
- package/dist/router/regex.js +3 -0
- package/dist/router/trie.js +148 -0
- package/dist/router/trie2.js +151 -0
- package/dist/router/trie2.test.js +162 -0
- package/dist/src/constant.js +1 -1
- package/dist/src/ctx.js +22 -22
- package/dist/src/handleRequest.js +21 -21
- package/dist/src/http-exception.js +1 -1
- package/dist/src/main.js +98 -98
- package/dist/src/request_pipeline.js +65 -65
- package/dist/src/router/find-my-way.js +63 -63
- package/dist/src/router/interface.js +63 -63
- package/dist/src/router/trie.js +1 -1
- package/dist/types.d.ts +6 -6
- package/dist/types.js +1 -0
- package/dist/utils/jwt.js +1 -1
- package/dist/utils/request.util.d.ts +5 -4
- package/dist/utils/request.util.js +1 -1
- package/index.d.ts +1 -0
- package/package.json +1 -1
package/dist/constant.js
ADDED
package/dist/ctx.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Server } from "bun";
|
|
2
|
-
import type {
|
|
3
|
-
export declare class Context
|
|
2
|
+
import type { CookieOptions } from "./types";
|
|
3
|
+
export declare class Context {
|
|
4
4
|
req: Request;
|
|
5
5
|
server?: Server | undefined;
|
|
6
6
|
path?: string | undefined;
|
|
@@ -25,10 +25,10 @@ export declare class Context implements ContextType {
|
|
|
25
25
|
get query(): Record<string, string>;
|
|
26
26
|
get params(): Record<string, string>;
|
|
27
27
|
get body(): Promise<any>;
|
|
28
|
-
text(data: string, status?: number): Response;
|
|
29
|
-
send<T>(data: T, status?: number): Response;
|
|
30
|
-
json<T>(object: T, status?: number): Response;
|
|
31
|
-
file(filePath: string,
|
|
28
|
+
text(data: string, status?: number, customHeaders?: HeadersInit): Response;
|
|
29
|
+
send<T>(data: T, status?: number, customHeaders?: HeadersInit): Response;
|
|
30
|
+
json<T>(object: T, status?: number, customHeaders?: HeadersInit): Response;
|
|
31
|
+
file(filePath: string, mimeType?: string, status?: number, customHeaders?: HeadersInit): Response;
|
|
32
32
|
ejs(viewPath: string, data?: {}, status?: number): Promise<Response>;
|
|
33
33
|
redirect(path: string, status?: number): Response;
|
|
34
34
|
setCookie(name: string, value: string, options?: CookieOptions): this;
|
package/dist/ctx.js
ADDED
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { getMimeType } from "./utils/mimeType";
|
|
11
|
+
let ejsInstance = null;
|
|
12
|
+
function getEjs() {
|
|
13
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
14
|
+
if (!ejsInstance) {
|
|
15
|
+
const mod = yield import("ejs");
|
|
16
|
+
ejsInstance = mod.default || mod;
|
|
17
|
+
}
|
|
18
|
+
return ejsInstance;
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
const typeMap = {
|
|
22
|
+
string: "text/plain; charset=utf-8",
|
|
23
|
+
object: "application/json; charset=utf-8",
|
|
24
|
+
Uint8Array: "application/octet-stream",
|
|
25
|
+
ArrayBuffer: "application/octet-stream",
|
|
26
|
+
};
|
|
27
|
+
export class Context {
|
|
28
|
+
constructor(req, server, path, routePattern, paramNames, env, executionContext) {
|
|
29
|
+
this.headers = new Headers();
|
|
30
|
+
// Lazily initialized
|
|
31
|
+
this.parsedQuery = null;
|
|
32
|
+
this.parsedParams = null;
|
|
33
|
+
this.parsedCookies = null;
|
|
34
|
+
this.parsedBody = null;
|
|
35
|
+
this.contextData = {};
|
|
36
|
+
this.urlObject = null;
|
|
37
|
+
this.req = req;
|
|
38
|
+
this.server = server;
|
|
39
|
+
this.path = path;
|
|
40
|
+
this.routePattern = routePattern;
|
|
41
|
+
this.executionContext = executionContext;
|
|
42
|
+
this.env = env;
|
|
43
|
+
this.paramNames = paramNames;
|
|
44
|
+
}
|
|
45
|
+
// Methods
|
|
46
|
+
setHeader(key, value) {
|
|
47
|
+
this.headers.set(key, value);
|
|
48
|
+
return this;
|
|
49
|
+
}
|
|
50
|
+
removeHeader(key) {
|
|
51
|
+
this.headers.delete(key);
|
|
52
|
+
return this;
|
|
53
|
+
}
|
|
54
|
+
set(key, value) {
|
|
55
|
+
this.contextData[key] = value;
|
|
56
|
+
return this;
|
|
57
|
+
}
|
|
58
|
+
get(key) {
|
|
59
|
+
return this.contextData[key];
|
|
60
|
+
}
|
|
61
|
+
get ip() {
|
|
62
|
+
var _a, _b;
|
|
63
|
+
if (this.server)
|
|
64
|
+
return (_b = (_a = this.server.requestIP(this.req)) === null || _a === void 0 ? void 0 : _a.address) !== null && _b !== void 0 ? _b : null;
|
|
65
|
+
return this.req.headers.get("CF-Connecting-IP") || null;
|
|
66
|
+
}
|
|
67
|
+
get url() {
|
|
68
|
+
if (!this.urlObject) {
|
|
69
|
+
this.urlObject = new URL(this.req.url);
|
|
70
|
+
}
|
|
71
|
+
return this.urlObject;
|
|
72
|
+
}
|
|
73
|
+
get query() {
|
|
74
|
+
if (!this.parsedQuery) {
|
|
75
|
+
this.parsedQuery = this.url.search ? Object.fromEntries(this.url.searchParams) : {};
|
|
76
|
+
}
|
|
77
|
+
return this.parsedQuery;
|
|
78
|
+
}
|
|
79
|
+
get params() {
|
|
80
|
+
var _a;
|
|
81
|
+
if (!Array.isArray(this.paramNames)) {
|
|
82
|
+
return this.paramNames;
|
|
83
|
+
}
|
|
84
|
+
if (!this.parsedParams) {
|
|
85
|
+
try {
|
|
86
|
+
this.parsedParams = extractParam(this.paramNames, this.path);
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
90
|
+
throw new Error(`Failed to extract route parameters: ${message}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return (_a = this.parsedParams) !== null && _a !== void 0 ? _a : {};
|
|
94
|
+
}
|
|
95
|
+
get body() {
|
|
96
|
+
if (this.req.method === "GET") {
|
|
97
|
+
console.error(`you are trying to access body in GET method ${this.path}`);
|
|
98
|
+
return Promise.resolve({});
|
|
99
|
+
}
|
|
100
|
+
if (!this.parsedBody) {
|
|
101
|
+
this.parsedBody = (() => __awaiter(this, void 0, void 0, function* () {
|
|
102
|
+
try {
|
|
103
|
+
const result = yield parseBody(this.req);
|
|
104
|
+
if (result.error) {
|
|
105
|
+
throw new Error(result.error);
|
|
106
|
+
}
|
|
107
|
+
return Object.keys(result).length === 0 ? null : result;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw new Error("Invalid request body format");
|
|
111
|
+
// const message = error instanceof Error ? error.message : String(error);
|
|
112
|
+
// throw new Error(`Failed to parse request body: ${message}`);
|
|
113
|
+
}
|
|
114
|
+
}))();
|
|
115
|
+
}
|
|
116
|
+
return this.parsedBody;
|
|
117
|
+
}
|
|
118
|
+
text(data, status = 200, customHeaders) {
|
|
119
|
+
if (customHeaders) {
|
|
120
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
121
|
+
this.headers.set(key, value);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
if (!this.headers.has("Content-Type")) {
|
|
125
|
+
this.headers.set("Content-Type", "text/plain; charset=utf-8");
|
|
126
|
+
}
|
|
127
|
+
return new Response(data, { status, headers: this.headers });
|
|
128
|
+
}
|
|
129
|
+
send(data, status = 200, customHeaders) {
|
|
130
|
+
var _a;
|
|
131
|
+
if (customHeaders) {
|
|
132
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
133
|
+
this.headers.set(key, value);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
let dataType;
|
|
137
|
+
if (data instanceof Uint8Array)
|
|
138
|
+
dataType = "Uint8Array";
|
|
139
|
+
else if (data instanceof ArrayBuffer)
|
|
140
|
+
dataType = "ArrayBuffer";
|
|
141
|
+
else
|
|
142
|
+
dataType = typeof data;
|
|
143
|
+
if (!this.headers.has("Content-Type")) {
|
|
144
|
+
this.headers.set("Content-Type", (_a = typeMap[dataType]) !== null && _a !== void 0 ? _a : "text/plain; charset=utf-8");
|
|
145
|
+
}
|
|
146
|
+
const responseData = dataType === "object" && data !== null
|
|
147
|
+
? JSON.stringify(data)
|
|
148
|
+
: data;
|
|
149
|
+
return new Response(responseData, { status, headers: this.headers });
|
|
150
|
+
}
|
|
151
|
+
json(object, status = 200, customHeaders) {
|
|
152
|
+
if (customHeaders) {
|
|
153
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
154
|
+
this.headers.set(key, value);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!this.headers.has("Content-Type")) {
|
|
158
|
+
this.headers.set("Content-Type", "application/json; charset=utf-8");
|
|
159
|
+
}
|
|
160
|
+
return new Response(JSON.stringify(object), { status, headers: this.headers });
|
|
161
|
+
}
|
|
162
|
+
file(filePath, mimeType, status = 200, customHeaders) {
|
|
163
|
+
if (customHeaders) {
|
|
164
|
+
for (const [key, value] of Object.entries(customHeaders)) {
|
|
165
|
+
this.headers.set(key, value);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
if (!this.headers.has("Content-Type")) {
|
|
169
|
+
this.headers.set("Content-Type", mimeType !== null && mimeType !== void 0 ? mimeType : getMimeType(filePath));
|
|
170
|
+
}
|
|
171
|
+
const file = Bun.file(filePath);
|
|
172
|
+
return new Response(file, { status, headers: this.headers });
|
|
173
|
+
}
|
|
174
|
+
ejs(viewPath_1) {
|
|
175
|
+
return __awaiter(this, arguments, void 0, function* (viewPath, data = {}, status = 200) {
|
|
176
|
+
// this.status = status;
|
|
177
|
+
const ejs = yield getEjs();
|
|
178
|
+
try {
|
|
179
|
+
const template = yield Bun.file(viewPath).text();
|
|
180
|
+
const rendered = ejs.render(template, data);
|
|
181
|
+
const headers = new Headers({ "Content-Type": "text/html; charset=utf-8" });
|
|
182
|
+
return new Response(rendered, { status, headers });
|
|
183
|
+
}
|
|
184
|
+
catch (error) {
|
|
185
|
+
console.error("EJS Rendering Error:", error);
|
|
186
|
+
return new Response("Error rendering template", { status: 500 });
|
|
187
|
+
}
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
redirect(path, status = 302) {
|
|
191
|
+
this.headers.set("Location", path);
|
|
192
|
+
return new Response(null, { status, headers: this.headers });
|
|
193
|
+
}
|
|
194
|
+
setCookie(name, value, options = {}) {
|
|
195
|
+
let cookieString = `${encodeURIComponent(name)}=${encodeURIComponent(value)}`;
|
|
196
|
+
if (options.maxAge)
|
|
197
|
+
cookieString += `; Max-Age=${options.maxAge}`;
|
|
198
|
+
if (options.expires)
|
|
199
|
+
cookieString += `; Expires=${options.expires.toUTCString()}`;
|
|
200
|
+
if (options.path)
|
|
201
|
+
cookieString += `; Path=${options.path}`;
|
|
202
|
+
if (options.domain)
|
|
203
|
+
cookieString += `; Domain=${options.domain}`;
|
|
204
|
+
if (options.secure)
|
|
205
|
+
cookieString += `; Secure`;
|
|
206
|
+
if (options.httpOnly)
|
|
207
|
+
cookieString += `; HttpOnly`;
|
|
208
|
+
if (options.sameSite)
|
|
209
|
+
cookieString += `; SameSite=${options.sameSite}`;
|
|
210
|
+
this.headers.append("Set-Cookie", cookieString);
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
get cookies() {
|
|
214
|
+
if (!this.parsedCookies) {
|
|
215
|
+
const cookieHeader = this.req.headers.get("cookie");
|
|
216
|
+
this.parsedCookies = cookieHeader ? parseCookie(cookieHeader) : {};
|
|
217
|
+
}
|
|
218
|
+
return this.parsedCookies;
|
|
219
|
+
}
|
|
220
|
+
// Streams
|
|
221
|
+
stream(callback) {
|
|
222
|
+
const headers = new Headers(this.headers);
|
|
223
|
+
const stream = new ReadableStream({
|
|
224
|
+
start(controller) {
|
|
225
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
226
|
+
yield callback(controller);
|
|
227
|
+
controller.close();
|
|
228
|
+
});
|
|
229
|
+
},
|
|
230
|
+
});
|
|
231
|
+
return new Response(stream, { headers });
|
|
232
|
+
}
|
|
233
|
+
yieldStream(callback) {
|
|
234
|
+
return new Response(
|
|
235
|
+
// {
|
|
236
|
+
// async *[Symbol.asyncIterator]() {
|
|
237
|
+
// yield* callback();
|
|
238
|
+
// },
|
|
239
|
+
// },
|
|
240
|
+
// { headers: this.headers }
|
|
241
|
+
);
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
// function parseCookie(cookieHeader: string | undefined): Record<string, string> {
|
|
245
|
+
// const cookies: Record<string, string> = {};
|
|
246
|
+
// const cookiesArray = cookieHeader?.split(";")!;
|
|
247
|
+
// for (let i = 0; i < cookiesArray?.length!; i++) {
|
|
248
|
+
// const [cookieName, ...cookieValeParts] = cookiesArray[i].trim().split("=");
|
|
249
|
+
// const cookieVale = cookieValeParts?.join("=").trim();
|
|
250
|
+
// if (cookieName) {
|
|
251
|
+
// cookies[cookieName.trim()] = decodeURIComponent(cookieVale);
|
|
252
|
+
// }
|
|
253
|
+
// }
|
|
254
|
+
// return cookies;
|
|
255
|
+
// }
|
|
256
|
+
function parseCookie(cookieHeader) {
|
|
257
|
+
return Object.fromEntries(cookieHeader.split(";").map((cookie) => {
|
|
258
|
+
const [name, ...valueParts] = cookie.trim().split("=");
|
|
259
|
+
return [name, decodeURIComponent(valueParts.join("="))];
|
|
260
|
+
}));
|
|
261
|
+
}
|
|
262
|
+
export function extractParam(paramNames, incomingPath) {
|
|
263
|
+
// ["id","name"]
|
|
264
|
+
const param = {};
|
|
265
|
+
// inComingpath = /user/2/pradeep
|
|
266
|
+
const [pathWithoutQuery] = incomingPath.split("?");
|
|
267
|
+
const pathSegments = pathWithoutQuery.split("/").filter(s => s !== '');
|
|
268
|
+
// let segmentStart = 0
|
|
269
|
+
// let segmentIndex = 0
|
|
270
|
+
// const segments: string[] = []
|
|
271
|
+
// for (let i = 0; i <= pathWithoutQuery.length; i++) {
|
|
272
|
+
// if (i === pathWithoutQuery.length || pathWithoutQuery.charCodeAt(i) === 47) { // '/'
|
|
273
|
+
// if (i > segmentStart) {
|
|
274
|
+
// segments[segmentIndex++] = pathWithoutQuery.slice(segmentStart, i)
|
|
275
|
+
// }
|
|
276
|
+
// segmentStart = i + 1
|
|
277
|
+
// }
|
|
278
|
+
// }
|
|
279
|
+
const start = pathSegments.length - paramNames.length;
|
|
280
|
+
for (let i = 0; i < paramNames.length; i++) {
|
|
281
|
+
param[paramNames[i]] = pathSegments[start + i];
|
|
282
|
+
}
|
|
283
|
+
return param;
|
|
284
|
+
}
|
|
285
|
+
export function extractDynamicParams(originalPath, incomingPath) {
|
|
286
|
+
const params = {};
|
|
287
|
+
const routeSegments = originalPath.split("/");
|
|
288
|
+
const [pathWithoutQuery] = incomingPath.split("?");
|
|
289
|
+
const pathSegments = pathWithoutQuery.split("/");
|
|
290
|
+
if (routeSegments.length !== pathSegments.length)
|
|
291
|
+
return null;
|
|
292
|
+
for (let i = 0; i < routeSegments.length; i++) {
|
|
293
|
+
const segment = routeSegments[i];
|
|
294
|
+
if (segment.charCodeAt(0) === 58) {
|
|
295
|
+
params[segment.slice(1)] = pathSegments[i];
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
return params;
|
|
299
|
+
}
|
|
300
|
+
function parseBody(req) {
|
|
301
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
302
|
+
const contentType = req.headers.get("Content-Type") || '';
|
|
303
|
+
if (!contentType)
|
|
304
|
+
return {};
|
|
305
|
+
const contentLength = req.headers.get("Content-Length");
|
|
306
|
+
if (contentLength === "0" || !req.body) {
|
|
307
|
+
return {};
|
|
308
|
+
}
|
|
309
|
+
if (contentType.startsWith("application/json")) {
|
|
310
|
+
return yield req.json();
|
|
311
|
+
}
|
|
312
|
+
if (contentType.startsWith("application/x-www-form-urlencoded")) {
|
|
313
|
+
const body = yield req.text();
|
|
314
|
+
return Object.fromEntries(new URLSearchParams(body));
|
|
315
|
+
}
|
|
316
|
+
if (contentType.startsWith("multipart/form-data")) {
|
|
317
|
+
const formData = yield req.formData();
|
|
318
|
+
const obj = {};
|
|
319
|
+
for (const [key, value] of formData.entries()) {
|
|
320
|
+
obj[key] = value;
|
|
321
|
+
}
|
|
322
|
+
return obj;
|
|
323
|
+
}
|
|
324
|
+
return { error: "Unknown request body type" };
|
|
325
|
+
});
|
|
326
|
+
}
|
package/dist/handleRequest.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import { Server } from "bun";
|
|
2
|
-
import
|
|
3
|
-
export default function handleRequest(req: Request, server: Server, diesel:
|
|
2
|
+
import Diesel from "./main";
|
|
3
|
+
export default function handleRequest(req: Request, server: Server, diesel: Diesel, env?: Record<string, any>, executionContext?: any): Promise<Response | undefined>;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { Context } from "./ctx";
|
|
11
|
+
import { tryDecodeURI } from "./utils/urls";
|
|
12
|
+
import { generateErrorResponse, handleRouteNotFound, runFilter, runHooks } from "./utils/request.util";
|
|
13
|
+
import { isPromise } from "./utils/promise";
|
|
14
|
+
export default function handleRequest(req, server, diesel, env, executionContext) {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
let pathname;
|
|
17
|
+
const start = req.url.indexOf('/', req.url.indexOf(':') + 4);
|
|
18
|
+
let i = start;
|
|
19
|
+
for (; i < req.url.length; i++) {
|
|
20
|
+
const charCode = req.url.charCodeAt(i);
|
|
21
|
+
if (charCode === 37) { // percent-encoded
|
|
22
|
+
const queryIndex = req.url.indexOf('?', i);
|
|
23
|
+
const path = req.url.slice(start, queryIndex === -1 ? undefined : queryIndex);
|
|
24
|
+
pathname = tryDecodeURI(path.includes('%25') ? path.replace(/%25/g, '%2525') : path);
|
|
25
|
+
break;
|
|
26
|
+
}
|
|
27
|
+
else if (charCode === 63) {
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
if (!pathname) {
|
|
32
|
+
pathname = req.url.slice(start, i);
|
|
33
|
+
}
|
|
34
|
+
const matchedRouteHandler = diesel.router.find(req.method, pathname);
|
|
35
|
+
const ctx = new Context(req, server, pathname, matchedRouteHandler === null || matchedRouteHandler === void 0 ? void 0 : matchedRouteHandler.path, env, executionContext);
|
|
36
|
+
// const ctx = createCtx(req,server,pathname,routeHandler?.path)
|
|
37
|
+
// PipeLines such as filters , middlewares, hooks
|
|
38
|
+
// if (diesel.hasOnReqHook)
|
|
39
|
+
// await runHooks('onRequest', diesel.hooks.onRequest, [req, pathname, server])
|
|
40
|
+
// middleware execution
|
|
41
|
+
// if (diesel.hasMiddleware) {
|
|
42
|
+
// const mwResult = await runMiddlewares(diesel, pathname, ctx);
|
|
43
|
+
// if (mwResult) return mwResult;
|
|
44
|
+
// }
|
|
45
|
+
// filter execution
|
|
46
|
+
if (diesel.hasFilterEnabled) {
|
|
47
|
+
const filterResponse = yield runFilter(diesel, pathname, ctx);
|
|
48
|
+
if (filterResponse)
|
|
49
|
+
return filterResponse;
|
|
50
|
+
}
|
|
51
|
+
// if route not found
|
|
52
|
+
// if (!routeHandler) return await handleRouteNotFound(diesel, ctx, pathname)
|
|
53
|
+
// pre-handler
|
|
54
|
+
if (diesel.hasPreHandlerHook) {
|
|
55
|
+
const result = yield runHooks('preHandler', diesel.hooks.preHandler, [ctx]);
|
|
56
|
+
if (result)
|
|
57
|
+
return result;
|
|
58
|
+
}
|
|
59
|
+
let finalResult;
|
|
60
|
+
const handlers = matchedRouteHandler === null || matchedRouteHandler === void 0 ? void 0 : matchedRouteHandler.handler;
|
|
61
|
+
if (handlers.length === 1) {
|
|
62
|
+
const result = handlers[0](ctx);
|
|
63
|
+
finalResult = isPromise(result) ? yield result : result;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
for (let i = 0; i < handlers.length; i++) {
|
|
67
|
+
const result = handlers[i](ctx);
|
|
68
|
+
finalResult = isPromise(result) ? yield result : result;
|
|
69
|
+
if (finalResult)
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// onSend
|
|
74
|
+
if (diesel.hasOnSendHook) {
|
|
75
|
+
const response = yield runHooks('onSend', diesel.hooks.onSend, [ctx, finalResult]);
|
|
76
|
+
if (response)
|
|
77
|
+
return response;
|
|
78
|
+
}
|
|
79
|
+
return finalResult !== null && finalResult !== void 0 ? finalResult : yield handleRouteNotFound(diesel, ctx, pathname);
|
|
80
|
+
// if we dont return a response then by default Bun shows a err
|
|
81
|
+
return generateErrorResponse(500, "No response returned from handler.");
|
|
82
|
+
});
|
|
83
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export class HTTPException extends Error {
|
|
2
|
+
constructor(status = 500, options) {
|
|
3
|
+
super(options === null || options === void 0 ? void 0 : options.message, { cause: options === null || options === void 0 ? void 0 : options.cause });
|
|
4
|
+
this.name = 'HTTPException';
|
|
5
|
+
this.res = options === null || options === void 0 ? void 0 : options.res;
|
|
6
|
+
this.status = status;
|
|
7
|
+
}
|
|
8
|
+
getResponse() {
|
|
9
|
+
if (this.res) {
|
|
10
|
+
const newResponse = new Response(this.res.body, {
|
|
11
|
+
status: this.status,
|
|
12
|
+
headers: this.res.headers,
|
|
13
|
+
});
|
|
14
|
+
return newResponse;
|
|
15
|
+
}
|
|
16
|
+
return new Response(this.message, {
|
|
17
|
+
status: this.status,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { describe, expect, it } from 'bun:test';
|
|
11
|
+
import { HTTPException } from './http-exception';
|
|
12
|
+
describe('HTTPException', () => {
|
|
13
|
+
it('Should be 401 HTTP exception object', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
14
|
+
// We should throw an exception if is not authorized
|
|
15
|
+
// because next handlers should not be fired.
|
|
16
|
+
const exception = new HTTPException(401, {
|
|
17
|
+
message: 'Unauthorized',
|
|
18
|
+
});
|
|
19
|
+
const res = exception.getResponse();
|
|
20
|
+
expect(res.status).toBe(401);
|
|
21
|
+
expect(yield res.text()).toBe('Unauthorized');
|
|
22
|
+
expect(exception.status).toBe(401);
|
|
23
|
+
expect(exception.message).toBe('Unauthorized');
|
|
24
|
+
}));
|
|
25
|
+
it('Should be accessible to the object causing the exception', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
26
|
+
// We should pass the cause of the error to the cause option
|
|
27
|
+
// because it makes debugging easier.
|
|
28
|
+
const error = new Error('Server Error');
|
|
29
|
+
const exception = new HTTPException(500, {
|
|
30
|
+
message: 'Internal Server Error',
|
|
31
|
+
cause: error,
|
|
32
|
+
});
|
|
33
|
+
const res = exception.getResponse();
|
|
34
|
+
expect(res.status).toBe(500);
|
|
35
|
+
expect(yield res.text()).toBe('Internal Server Error');
|
|
36
|
+
expect(exception.status).toBe(500);
|
|
37
|
+
expect(exception.message).toBe('Internal Server Error');
|
|
38
|
+
expect(exception.cause).toBe(error);
|
|
39
|
+
}));
|
|
40
|
+
it('Should prioritize the status code over the code in the response', () => __awaiter(void 0, void 0, void 0, function* () {
|
|
41
|
+
const exception = new HTTPException(400, {
|
|
42
|
+
res: new Response('An exception', {
|
|
43
|
+
status: 200,
|
|
44
|
+
}),
|
|
45
|
+
});
|
|
46
|
+
const res = exception.getResponse();
|
|
47
|
+
expect(res.status).toBe(400);
|
|
48
|
+
expect(yield res.text()).toBe('An exception');
|
|
49
|
+
}));
|
|
50
|
+
});
|
package/dist/main.d.ts
CHANGED
|
@@ -20,7 +20,7 @@ export default class Diesel {
|
|
|
20
20
|
FilterRoutes: string[] | null | undefined;
|
|
21
21
|
filters: Set<string>;
|
|
22
22
|
filterFunction: Function[];
|
|
23
|
-
|
|
23
|
+
hasFilterEnabled: boolean;
|
|
24
24
|
private serverInstance;
|
|
25
25
|
staticFiles: any;
|
|
26
26
|
user_jwt_secret: string;
|