tezx 1.0.12 → 1.0.13
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/MiddlewareConfigure.js +2 -20
- package/dist/adapter.js +4 -20
- package/dist/common.js +0 -83
- package/dist/context.js +1 -149
- package/dist/header.js +1 -55
- package/dist/helper/common.js +3 -7
- package/dist/helper/env-parser.js +3 -97
- package/dist/index.js +0 -2
- package/dist/middleware/cors.js +0 -3
- package/dist/middleware/logger.js +6 -21
- package/dist/middleware/powered-by.js +2 -16
- package/dist/middleware/rateLimiter.js +2 -60
- package/dist/middleware/request-id.js +0 -18
- package/dist/middleware/sanitizeHeader.js +2 -46
- package/dist/middleware/secureHeaders.js +0 -28
- package/dist/middleware/xssProtection.js +0 -20
- package/dist/request.js +0 -50
- package/dist/router.js +14 -109
- package/dist/server.js +0 -3
- package/dist/utils/debugging.js +0 -7
- package/dist/utils/formData.js +0 -17
- package/dist/utils/params.js +0 -39
- package/dist/utils/state.js +0 -39
- package/dist/utils/staticFile.js +1 -18
- package/dist/utils/url.js +1 -34
- package/package.json +1 -1
|
@@ -9,10 +9,10 @@ export class TriMiddleware {
|
|
|
9
9
|
constructor(pathname = "/") {
|
|
10
10
|
this.pathname = pathname;
|
|
11
11
|
if (GlobalConfig.allowDuplicateMw) {
|
|
12
|
-
this.middlewares = [];
|
|
12
|
+
this.middlewares = [];
|
|
13
13
|
}
|
|
14
14
|
else {
|
|
15
|
-
this.middlewares = new Set();
|
|
15
|
+
this.middlewares = new Set();
|
|
16
16
|
}
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -24,20 +24,7 @@ export default class MiddlewareConfigure extends CommonHandler {
|
|
|
24
24
|
this.basePath = basePath;
|
|
25
25
|
}
|
|
26
26
|
addMiddleware(pathname, middlewares) {
|
|
27
|
-
// console.log(this.basePath)
|
|
28
|
-
// console.log(pathname);
|
|
29
27
|
const parts = sanitizePathSplit(this.basePath, pathname);
|
|
30
|
-
// console.log(parts, this.basePath)
|
|
31
|
-
// if (/(\/\*|\?)/.test(pathname)) {
|
|
32
|
-
// let path = parts.join("/");
|
|
33
|
-
// let handler = this.routeMiddlewares.get(path);
|
|
34
|
-
// if (!handler) {
|
|
35
|
-
// // handler.set(method, { callback: callback, middlewares });
|
|
36
|
-
// return this.routeMiddlewares.set(path, middlewares);
|
|
37
|
-
// }
|
|
38
|
-
// // console.log(this.routeMiddlewares, 35345)
|
|
39
|
-
// return handler.push(...middlewares);
|
|
40
|
-
// }
|
|
41
28
|
let node = this.triMiddlewares;
|
|
42
29
|
for (const part of parts) {
|
|
43
30
|
if (part.startsWith("*")) {
|
|
@@ -47,7 +34,6 @@ export default class MiddlewareConfigure extends CommonHandler {
|
|
|
47
34
|
node = node.children.get("*");
|
|
48
35
|
}
|
|
49
36
|
else if (part.startsWith(":")) {
|
|
50
|
-
// Dynamic parameter (e.g., :id)
|
|
51
37
|
const isOptional = part?.endsWith("?");
|
|
52
38
|
if (isOptional) {
|
|
53
39
|
node.isOptional = isOptional;
|
|
@@ -59,13 +45,11 @@ export default class MiddlewareConfigure extends CommonHandler {
|
|
|
59
45
|
node = node.children.get(":");
|
|
60
46
|
}
|
|
61
47
|
else {
|
|
62
|
-
// Static path segment
|
|
63
48
|
if (!node.children.has(part)) {
|
|
64
49
|
node.children.set(part, new TriMiddleware());
|
|
65
50
|
}
|
|
66
51
|
node = node.children.get(part);
|
|
67
52
|
}
|
|
68
|
-
// Optionally, you could store the parameter name in the node if needed
|
|
69
53
|
}
|
|
70
54
|
if (GlobalConfig.allowDuplicateMw) {
|
|
71
55
|
node.middlewares.push(...middlewares);
|
|
@@ -75,7 +59,5 @@ export default class MiddlewareConfigure extends CommonHandler {
|
|
|
75
59
|
node.middlewares.add(middleware);
|
|
76
60
|
}
|
|
77
61
|
}
|
|
78
|
-
// this.triMiddleware = new TriMiddleware(pathname);
|
|
79
|
-
// this.triMiddleware.middlewares = middlewares;
|
|
80
62
|
}
|
|
81
63
|
}
|
package/dist/adapter.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
//src/adapter.ts
|
|
2
1
|
import { GlobalConfig } from "./config/config";
|
|
3
2
|
export function denoAdapter(TezX) {
|
|
4
3
|
function listen(port, callback) {
|
|
@@ -38,11 +37,8 @@ export function denoAdapter(TezX) {
|
|
|
38
37
|
if (!server) {
|
|
39
38
|
throw new Error("Deno is not find");
|
|
40
39
|
}
|
|
41
|
-
// Determine protocol based on SSL configuration
|
|
42
40
|
const protocol = "\x1b[1;34mhttp\x1b[0m";
|
|
43
|
-
// Constructing the colorful message with emojis
|
|
44
41
|
const message = `\x1b[1m🚀 Deno TezX Server running at ${protocol}://localhost:${port}/\x1b[0m`;
|
|
45
|
-
// Logging the message to the console
|
|
46
42
|
if (typeof callback === "function") {
|
|
47
43
|
callback(message);
|
|
48
44
|
}
|
|
@@ -86,12 +82,8 @@ export function bunAdapter(TezX) {
|
|
|
86
82
|
},
|
|
87
83
|
});
|
|
88
84
|
GlobalConfig.serverInfo = server;
|
|
89
|
-
// Determine protocol based on SSL configuration
|
|
90
85
|
const protocol = "\x1b[1;34mhttp\x1b[0m";
|
|
91
|
-
// const protocol = "\x1b[1;35mhttps\x1b[0m" : "\x1b[1;34mhttp\x1b[0m";
|
|
92
|
-
// Constructing the colorful message with emojis
|
|
93
86
|
const message = `\x1b[1m Bun TezX Server running at ${protocol}://localhost:${port}/\x1b[0m`;
|
|
94
|
-
// Logging the message to the console
|
|
95
87
|
if (typeof callback == "function") {
|
|
96
88
|
callback(message);
|
|
97
89
|
}
|
|
@@ -118,46 +110,38 @@ export function nodeAdapter(TezX) {
|
|
|
118
110
|
address = {
|
|
119
111
|
remoteAddr: {
|
|
120
112
|
family: req.socket.remoteFamily,
|
|
121
|
-
address: req.socket.remoteAddress,
|
|
122
|
-
port: req.socket.remotePort,
|
|
113
|
+
address: req.socket.remoteAddress,
|
|
114
|
+
port: req.socket.remotePort,
|
|
123
115
|
},
|
|
124
116
|
localAddr: {
|
|
125
|
-
address: req.socket.localAddress,
|
|
126
|
-
port: req.socket.localPort,
|
|
117
|
+
address: req.socket.localAddress,
|
|
118
|
+
port: req.socket.localPort,
|
|
127
119
|
family: req.socket.localFamily,
|
|
128
120
|
},
|
|
129
121
|
};
|
|
130
122
|
}
|
|
131
123
|
const response = await TezX.serve(req, address);
|
|
132
|
-
// console.log((req as any).socket.remoteAddress)
|
|
133
124
|
const statusText = response?.statusText;
|
|
134
125
|
if (!(response instanceof Response)) {
|
|
135
126
|
throw new Error("Invalid response from TezX.serve");
|
|
136
127
|
}
|
|
137
128
|
const headers = Object.fromEntries(await response.headers.entries());
|
|
138
|
-
// const body = await response.text(); // Ensure it's a string
|
|
139
129
|
if (statusText) {
|
|
140
130
|
res.statusMessage = statusText;
|
|
141
131
|
}
|
|
142
132
|
res.writeHead(response.status, headers);
|
|
143
133
|
const { Readable } = await import("stream");
|
|
144
134
|
if (response.body instanceof Readable) {
|
|
145
|
-
// Stream the body (e.g., for large files or binary data)
|
|
146
135
|
response.body.pipe(res);
|
|
147
136
|
}
|
|
148
137
|
else {
|
|
149
|
-
// Convert body to text or buffer
|
|
150
138
|
const body = await response.arrayBuffer();
|
|
151
139
|
res.end(Buffer.from(body));
|
|
152
140
|
}
|
|
153
141
|
});
|
|
154
142
|
server.listen(port, () => {
|
|
155
|
-
// Determine protocol based on SSL configuration
|
|
156
143
|
const protocol = "\x1b[1;34mhttp\x1b[0m";
|
|
157
|
-
// const protocol = "\x1b[1;35mhttps\x1b[0m" : "\x1b[1;34mhttp\x1b[0m";
|
|
158
|
-
// Constructing the colorful message with emojis
|
|
159
144
|
const message = `\x1b[1m NodeJS TezX Server running at ${protocol}://localhost:${port}/\x1b[0m`;
|
|
160
|
-
// Logging the message to the console
|
|
161
145
|
GlobalConfig.serverInfo = server;
|
|
162
146
|
if (typeof callback == "function") {
|
|
163
147
|
callback(message);
|
package/dist/common.js
CHANGED
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
import { GlobalConfig } from "./config/config";
|
|
2
2
|
export class CommonHandler {
|
|
3
|
-
/**
|
|
4
|
-
* Register a custom 404 handler for missing routes
|
|
5
|
-
* @param {Callback} callback - Handler function to execute when no route matches
|
|
6
|
-
* @returns {this} - Returns current instance for chaining
|
|
7
|
-
*
|
|
8
|
-
* @example
|
|
9
|
-
* // Register a custom not-found handler
|
|
10
|
-
* app.notFound((ctx) => {
|
|
11
|
-
* ctx.status(404).text('Custom not found message');
|
|
12
|
-
* });
|
|
13
|
-
*/
|
|
14
3
|
notFound(callback) {
|
|
15
4
|
GlobalConfig.notFound = callback;
|
|
16
5
|
return this;
|
|
@@ -20,75 +9,3 @@ export class CommonHandler {
|
|
|
20
9
|
return this;
|
|
21
10
|
}
|
|
22
11
|
}
|
|
23
|
-
// class T<T> {
|
|
24
|
-
// private data: T;
|
|
25
|
-
// constructor() {
|
|
26
|
-
// this.data = {} as T; // Initialize with an empty object of type T
|
|
27
|
-
// }
|
|
28
|
-
// // Method to set a value
|
|
29
|
-
// set<K extends keyof T>(key: K, value: T[K]): void {
|
|
30
|
-
// this.data[key] = value;
|
|
31
|
-
// }
|
|
32
|
-
// // Method to get a value
|
|
33
|
-
// get<K extends keyof T>(key: K): T[K] | undefined {
|
|
34
|
-
// return this.data[key];
|
|
35
|
-
// }
|
|
36
|
-
// }
|
|
37
|
-
// // Create an instance of T with a specific type
|
|
38
|
-
// const x = new T<{ user: string }>();
|
|
39
|
-
// // Set the 'user' property
|
|
40
|
-
// x.set('user', 'rakib');
|
|
41
|
-
// // Get the 'user' property
|
|
42
|
-
// console.log(x.get('user')); // Output: "rakib"
|
|
43
|
-
// class T<T extends Record<string,any>> {
|
|
44
|
-
// [key: any extends keyof T]: T; // Allow dynamic properties
|
|
45
|
-
// constructor() { }
|
|
46
|
-
// }
|
|
47
|
-
// // Create an instance of T with a specific type
|
|
48
|
-
// const x = new T<{ user: string }>();
|
|
49
|
-
// // Assign the 'user' property dynamically
|
|
50
|
-
// x.user = 'rakib';
|
|
51
|
-
// // // Access the 'user' property
|
|
52
|
-
// console.log(x.user); // Output: "rakib"
|
|
53
|
-
// class T {
|
|
54
|
-
// constructor(data: T) {
|
|
55
|
-
// Object.assign(this, data);
|
|
56
|
-
// }
|
|
57
|
-
// }
|
|
58
|
-
// type x = T & {
|
|
59
|
-
// user: 5345
|
|
60
|
-
// }
|
|
61
|
-
// const xx: x = {
|
|
62
|
-
// user: 5345
|
|
63
|
-
// }
|
|
64
|
-
// class T<T> {
|
|
65
|
-
// constructor(public data: T) { }
|
|
66
|
-
// }
|
|
67
|
-
// const x = new T<{ user: string }>({ user: 'rakib' });
|
|
68
|
-
// x.data.user = 'rakib';
|
|
69
|
-
// console.log(x.data.user); // Outputs: rakib
|
|
70
|
-
// class T<T extends object> {
|
|
71
|
-
// constructor(data: T) {
|
|
72
|
-
// Object.assign(this, data);
|
|
73
|
-
// }
|
|
74
|
-
// }
|
|
75
|
-
// const x = new T({ user: 'rakib' }) as T<{ user: string }> & { user: string };
|
|
76
|
-
// x.user = 'rakib';
|
|
77
|
-
// console.log(x.user); // Outputs: rakib
|
|
78
|
-
// const x = new T({ user: 'rakib' }) as T<{ user: string }> & { user: string };
|
|
79
|
-
// x.user = 'rakib';
|
|
80
|
-
// console.log(x.user); // Outputs:
|
|
81
|
-
// class T<T extends Record<string, any>> {
|
|
82
|
-
// private data: T = {} as T;
|
|
83
|
-
// [key: string]: any; // Allows dynamic property assignment
|
|
84
|
-
// set<K extends keyof T>(key: K, value: T[K]): void {
|
|
85
|
-
// this.data[key] = value;
|
|
86
|
-
// }
|
|
87
|
-
// get<K extends keyof T>(key: K): T[K] | undefined {
|
|
88
|
-
// return this.data[key];
|
|
89
|
-
// }
|
|
90
|
-
// }
|
|
91
|
-
// // ✅ Usage
|
|
92
|
-
// const x = new T<{ user: string }>();
|
|
93
|
-
// x.user = "rakib"; // ✅ Works
|
|
94
|
-
// console.log(x.user); // Output: "rakib"
|
package/dist/context.js
CHANGED
|
@@ -68,82 +68,20 @@ export const httpStatusMap = {
|
|
|
68
68
|
510: "Not Extended",
|
|
69
69
|
511: "Network Authentication Required",
|
|
70
70
|
};
|
|
71
|
-
// export type ResponseOption = {
|
|
72
|
-
// statusText?: string; // Optional status text (e.g., "OK", "Not Found")
|
|
73
|
-
// headers?: ResponseHeaders;
|
|
74
|
-
// } | ResponseHeaders
|
|
75
|
-
// Action
|
|
76
|
-
// Simple Name
|
|
77
|
-
// Descriptive Name
|
|
78
|
-
// Set a value
|
|
79
|
-
// store()
|
|
80
|
-
// setItem(), add()
|
|
81
|
-
// Get a value
|
|
82
|
-
// fetch()
|
|
83
|
-
// retrieve(), getItem()
|
|
84
|
-
// Delete a value
|
|
85
|
-
// remove()
|
|
86
|
-
// discard(), deleteItem()
|
|
87
|
-
// Get all values
|
|
88
|
-
// list()
|
|
89
|
-
// getAll(), dump()
|
|
90
|
-
// Clear everything
|
|
91
|
-
// clear()
|
|
92
|
-
// wipe(), reset()
|
|
93
71
|
export class Context {
|
|
94
72
|
#rawRequest;
|
|
95
|
-
/**
|
|
96
|
-
* Environment variables and configuration
|
|
97
|
-
* @type {object}
|
|
98
|
-
*/
|
|
99
73
|
env = {};
|
|
100
|
-
/**
|
|
101
|
-
* Parser for handling and manipulating HTTP headers
|
|
102
|
-
* @type {HeadersParser}
|
|
103
|
-
*/
|
|
104
74
|
headers = new HeadersParser();
|
|
105
|
-
/**
|
|
106
|
-
* Parser for handling and manipulating HTTP response(Read Only)
|
|
107
|
-
* @type {Response}
|
|
108
|
-
*/
|
|
109
75
|
res;
|
|
110
|
-
/**
|
|
111
|
-
* Request path without query parameters
|
|
112
|
-
* @type {string}
|
|
113
|
-
*/
|
|
114
76
|
pathname;
|
|
115
|
-
/**
|
|
116
|
-
* Full request URL including protocol and query string
|
|
117
|
-
* @type {string}
|
|
118
|
-
*/
|
|
119
77
|
url;
|
|
120
|
-
/**
|
|
121
|
-
* HTTP request method (GET, POST, PUT, DELETE, etc.)
|
|
122
|
-
* @type {HTTPMethod}
|
|
123
|
-
*/
|
|
124
78
|
method;
|
|
125
79
|
#status = 200;
|
|
126
|
-
/**
|
|
127
|
-
* Public state container for application data
|
|
128
|
-
* state storage for middleware and plugins
|
|
129
|
-
* @type {State}
|
|
130
|
-
*/
|
|
131
80
|
state = new State();
|
|
132
|
-
/**
|
|
133
|
-
* URL parameters extracted from route
|
|
134
|
-
* @private
|
|
135
|
-
* @type {Record<string, any>}
|
|
136
|
-
*/
|
|
137
81
|
#params = {};
|
|
138
|
-
// /**
|
|
139
|
-
// * WebSocket connection instance (null until upgraded)
|
|
140
|
-
// * @type {WebSocket | null}
|
|
141
|
-
// */
|
|
142
|
-
// ws: WebSocket | null = null;
|
|
143
82
|
#localAddress = {};
|
|
144
83
|
#remoteAddress = {};
|
|
145
84
|
constructor(req, connInfo) {
|
|
146
|
-
// this.status = this.status.bind(this);
|
|
147
85
|
this.#rawRequest = req;
|
|
148
86
|
this.#remoteAddress = connInfo.remoteAddr;
|
|
149
87
|
this.#localAddress = connInfo.localAddr;
|
|
@@ -151,20 +89,6 @@ export class Context {
|
|
|
151
89
|
this.pathname = this.req.urlRef.pathname;
|
|
152
90
|
this.url = this.req.url;
|
|
153
91
|
}
|
|
154
|
-
/**
|
|
155
|
-
* Cookie handling utility with get/set/delete operations
|
|
156
|
-
* @returns {{
|
|
157
|
-
* get: (name: string) => string | undefined,
|
|
158
|
-
* all: () => Record<string, string>,
|
|
159
|
-
* delete: (name: string, options?: CookieOptions) => void,
|
|
160
|
-
* set: (name: string, value: string, options?: CookieOptions) => void
|
|
161
|
-
* }} Cookie handling interface
|
|
162
|
-
*/
|
|
163
|
-
/**
|
|
164
|
-
* Sets a header value.
|
|
165
|
-
* @param key - Header name.
|
|
166
|
-
* @param value - Header value(s).
|
|
167
|
-
*/
|
|
168
92
|
header(key, value) {
|
|
169
93
|
this.headers.set(key, value);
|
|
170
94
|
return this;
|
|
@@ -187,41 +111,21 @@ export class Context {
|
|
|
187
111
|
}
|
|
188
112
|
}
|
|
189
113
|
return {
|
|
190
|
-
/**
|
|
191
|
-
* Get a specific cookie by name.
|
|
192
|
-
* @param {string} cookie - The name of the cookie to retrieve.
|
|
193
|
-
* @returns {string | undefined} - The cookie value or undefined if not found.
|
|
194
|
-
*/
|
|
195
114
|
get: (cookie) => {
|
|
196
115
|
return cookies?.[cookie];
|
|
197
116
|
},
|
|
198
|
-
/**
|
|
199
|
-
* Get all cookies as an object.
|
|
200
|
-
* @returns {Record<string, string>} - An object containing all cookies.
|
|
201
|
-
*/
|
|
202
117
|
all: () => {
|
|
203
118
|
return cookies;
|
|
204
119
|
},
|
|
205
|
-
/**
|
|
206
|
-
* Delete a cookie by setting its expiration to the past.
|
|
207
|
-
* @param {string} name - The name of the cookie to delete.
|
|
208
|
-
* @param {CookieOptions} [options] - Additional cookie options.
|
|
209
|
-
*/
|
|
210
120
|
delete: (name, options) => {
|
|
211
121
|
const value = "";
|
|
212
122
|
const cookieOptions = {
|
|
213
123
|
...options,
|
|
214
|
-
expires: new Date(0),
|
|
124
|
+
expires: new Date(0),
|
|
215
125
|
};
|
|
216
126
|
const cookieHeader = `${name}=${value};${serializeOptions(cookieOptions)}`;
|
|
217
127
|
this.headers.set("Set-Cookie", cookieHeader);
|
|
218
128
|
},
|
|
219
|
-
/**
|
|
220
|
-
* Set a new cookie with the given name, value, and options.
|
|
221
|
-
* @param {string} name - The name of the cookie.
|
|
222
|
-
* @param {string} value - The value of the cookie.
|
|
223
|
-
* @param {CookieOptions} [options] - Additional options like expiration.
|
|
224
|
-
*/
|
|
225
129
|
set: (name, value, options) => {
|
|
226
130
|
const cookieHeader = `${name}=${value};${serializeOptions(options || {})}`;
|
|
227
131
|
this.headers.set("Set-Cookie", cookieHeader);
|
|
@@ -333,11 +237,6 @@ export class Context {
|
|
|
333
237
|
headers: headers,
|
|
334
238
|
});
|
|
335
239
|
}
|
|
336
|
-
/**
|
|
337
|
-
* HTTP status code..
|
|
338
|
-
* @param status - number.
|
|
339
|
-
* @returns Response object with context all method.
|
|
340
|
-
*/
|
|
341
240
|
status = (status) => {
|
|
342
241
|
this.#status = status;
|
|
343
242
|
return this;
|
|
@@ -348,27 +247,14 @@ export class Context {
|
|
|
348
247
|
get getStatus() {
|
|
349
248
|
return this.#status;
|
|
350
249
|
}
|
|
351
|
-
/**
|
|
352
|
-
* Redirects to a given URL.
|
|
353
|
-
* @param url - The target URL.
|
|
354
|
-
* @param status - (Optional) HTTP status code (default: 302).
|
|
355
|
-
* @returns Response object with redirect.
|
|
356
|
-
*/
|
|
357
250
|
redirect(url, status = 302) {
|
|
358
251
|
return new Response(null, {
|
|
359
252
|
status: status,
|
|
360
253
|
headers: { Location: url },
|
|
361
254
|
});
|
|
362
255
|
}
|
|
363
|
-
/**
|
|
364
|
-
* Handles file downloads.
|
|
365
|
-
* @param filePath - The path to the file.
|
|
366
|
-
* @param fileName - The name of the downloaded file.
|
|
367
|
-
* @returns Response object for file download.
|
|
368
|
-
*/
|
|
369
256
|
async download(filePath, fileName) {
|
|
370
257
|
try {
|
|
371
|
-
// Ensure the file exists
|
|
372
258
|
let fileExists = false;
|
|
373
259
|
const runtime = EnvironmentDetector.getEnvironment;
|
|
374
260
|
if (runtime === "node") {
|
|
@@ -390,7 +276,6 @@ export class Context {
|
|
|
390
276
|
if (!fileExists) {
|
|
391
277
|
throw Error("File not found");
|
|
392
278
|
}
|
|
393
|
-
// Read the file content based on the runtime
|
|
394
279
|
let fileBuffer;
|
|
395
280
|
if (runtime === "node") {
|
|
396
281
|
const { readFileSync } = await import("fs");
|
|
@@ -404,7 +289,6 @@ export class Context {
|
|
|
404
289
|
else if (runtime === "deno") {
|
|
405
290
|
fileBuffer = await Deno.readFile(filePath);
|
|
406
291
|
}
|
|
407
|
-
// Return the file as a downloadable response
|
|
408
292
|
return this.#handleResponse(fileBuffer, {
|
|
409
293
|
status: 200,
|
|
410
294
|
headers: {
|
|
@@ -421,11 +305,7 @@ export class Context {
|
|
|
421
305
|
async sendFile(filePath, ...args) {
|
|
422
306
|
try {
|
|
423
307
|
const runtime = EnvironmentDetector.getEnvironment;
|
|
424
|
-
// Resolve the absolute path to the file
|
|
425
308
|
const resolvedPath = filePath;
|
|
426
|
-
// const resolvedPath =
|
|
427
|
-
// runtime === "node" ? join(process.cwd(), filePath) : filePath;
|
|
428
|
-
// Check if the file exists
|
|
429
309
|
let fileExists = false;
|
|
430
310
|
if (runtime === "node") {
|
|
431
311
|
const { existsSync } = await import("fs");
|
|
@@ -446,7 +326,6 @@ export class Context {
|
|
|
446
326
|
if (!fileExists) {
|
|
447
327
|
throw Error("File not found");
|
|
448
328
|
}
|
|
449
|
-
// Read file stats (size)
|
|
450
329
|
let fileSize = 0;
|
|
451
330
|
if (runtime === "node") {
|
|
452
331
|
const { statSync } = await import("fs");
|
|
@@ -461,7 +340,6 @@ export class Context {
|
|
|
461
340
|
}
|
|
462
341
|
const ext = filePath.split(".").pop()?.toLowerCase() || "";
|
|
463
342
|
const mimeType = mimeTypes[ext] || defaultMimeType;
|
|
464
|
-
// Create a readable stream for the file
|
|
465
343
|
let fileStream;
|
|
466
344
|
if (runtime === "node") {
|
|
467
345
|
const { createReadStream } = await import("fs");
|
|
@@ -474,7 +352,6 @@ export class Context {
|
|
|
474
352
|
const file = await Deno.open(resolvedPath, { read: true });
|
|
475
353
|
fileStream = file.readable;
|
|
476
354
|
}
|
|
477
|
-
// Build headers
|
|
478
355
|
let headers = {
|
|
479
356
|
"Content-Type": mimeType,
|
|
480
357
|
"Content-Length": fileSize.toString(),
|
|
@@ -489,11 +366,9 @@ export class Context {
|
|
|
489
366
|
else if (typeof args[0] === "object") {
|
|
490
367
|
headers = { ...headers, ...args[0] };
|
|
491
368
|
}
|
|
492
|
-
// Add Content-Disposition header if fileName is provided
|
|
493
369
|
if (fileName) {
|
|
494
370
|
headers["Content-Disposition"] = `attachment; filename="${fileName}"`;
|
|
495
371
|
}
|
|
496
|
-
// Return the file as a Response object
|
|
497
372
|
return this.#handleResponse(fileStream, {
|
|
498
373
|
status: 200,
|
|
499
374
|
headers,
|
|
@@ -510,34 +385,11 @@ export class Context {
|
|
|
510
385
|
});
|
|
511
386
|
let clone = response.clone();
|
|
512
387
|
this.res = response;
|
|
513
|
-
// console.log(this.res)
|
|
514
388
|
return clone;
|
|
515
389
|
}
|
|
516
|
-
// get res() {
|
|
517
|
-
// return this.res;
|
|
518
|
-
// }
|
|
519
|
-
// set res(res: Response) {
|
|
520
|
-
// this.res = res;
|
|
521
|
-
// }
|
|
522
|
-
/**
|
|
523
|
-
* Getter that creates a standardized Request object from internal state
|
|
524
|
-
* @returns {Request} - Normalized request object combining:
|
|
525
|
-
* - Raw platform-specific request
|
|
526
|
-
* - Parsed headers
|
|
527
|
-
* - Route parameters
|
|
528
|
-
*
|
|
529
|
-
* @example
|
|
530
|
-
* // Get standardized request
|
|
531
|
-
* const request = ctx.req;
|
|
532
|
-
* // Access route params
|
|
533
|
-
* const id = request.params.get('id');
|
|
534
|
-
*/
|
|
535
390
|
get req() {
|
|
536
391
|
return new Request(this.#rawRequest, this.params, this.#remoteAddress);
|
|
537
392
|
}
|
|
538
|
-
// attachWebSocket(ws) {
|
|
539
|
-
// this.ws = ws;
|
|
540
|
-
// }
|
|
541
393
|
set params(params) {
|
|
542
394
|
this.#params = params;
|
|
543
395
|
}
|
package/dist/header.js
CHANGED
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
export class HeadersParser {
|
|
2
|
-
headers = new Map();
|
|
2
|
+
headers = new Map();
|
|
3
3
|
constructor(init) {
|
|
4
4
|
if (init) {
|
|
5
5
|
this.add(init);
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Adds multiple headers to the parser.
|
|
10
|
-
* @param headers - Headers as an array of tuples or a record object.
|
|
11
|
-
*/
|
|
12
8
|
add(headers) {
|
|
13
9
|
if (Array.isArray(headers)) {
|
|
14
10
|
for (const [key, value] of headers) {
|
|
@@ -29,11 +25,6 @@ export class HeadersParser {
|
|
|
29
25
|
}
|
|
30
26
|
return this;
|
|
31
27
|
}
|
|
32
|
-
/**
|
|
33
|
-
* Sets a header value.
|
|
34
|
-
* @param key - Header name.
|
|
35
|
-
* @param value - Header value(s).
|
|
36
|
-
*/
|
|
37
28
|
set(key, value) {
|
|
38
29
|
this.headers.set(key.toLowerCase(), Array.isArray(value) ? value : [value]);
|
|
39
30
|
return this;
|
|
@@ -42,44 +33,19 @@ export class HeadersParser {
|
|
|
42
33
|
this.headers.clear();
|
|
43
34
|
return this;
|
|
44
35
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Retrieves the first value of a header.
|
|
47
|
-
* @param key - Header name.
|
|
48
|
-
* @returns The first header value or undefined if not found.
|
|
49
|
-
*/
|
|
50
36
|
get(key) {
|
|
51
37
|
const values = this.headers.get(key.toLowerCase());
|
|
52
38
|
return values ? values[0] : undefined;
|
|
53
39
|
}
|
|
54
|
-
/**
|
|
55
|
-
* Retrieves all values of a header.
|
|
56
|
-
* @param key - Header name.
|
|
57
|
-
* @returns An array of header values.
|
|
58
|
-
*/
|
|
59
40
|
getAll(key) {
|
|
60
41
|
return this.headers.get(key.toLowerCase()) || [];
|
|
61
42
|
}
|
|
62
|
-
/**
|
|
63
|
-
* Checks if a header exists.
|
|
64
|
-
* @param key - Header name.
|
|
65
|
-
* @returns True if the header exists, false otherwise.
|
|
66
|
-
*/
|
|
67
43
|
has(key) {
|
|
68
44
|
return this.headers.has(key.toLowerCase());
|
|
69
45
|
}
|
|
70
|
-
/**
|
|
71
|
-
* Deletes a header.
|
|
72
|
-
* @param key - Header name.
|
|
73
|
-
* @returns True if deleted successfully, false otherwise.
|
|
74
|
-
*/
|
|
75
46
|
delete(key) {
|
|
76
47
|
return this.headers.delete(key.toLowerCase());
|
|
77
48
|
}
|
|
78
|
-
/**
|
|
79
|
-
* Appends a value to an existing header or creates a new one.
|
|
80
|
-
* @param key - Header name.
|
|
81
|
-
* @param value - Value to append.
|
|
82
|
-
*/
|
|
83
49
|
append(key, value) {
|
|
84
50
|
const lowerKey = key.toLowerCase();
|
|
85
51
|
if (this.headers.has(lowerKey)) {
|
|
@@ -90,40 +56,20 @@ export class HeadersParser {
|
|
|
90
56
|
}
|
|
91
57
|
return this;
|
|
92
58
|
}
|
|
93
|
-
/**
|
|
94
|
-
* Returns an iterator over header entries.
|
|
95
|
-
* @returns IterableIterator of header key-value pairs.
|
|
96
|
-
*/
|
|
97
59
|
entries() {
|
|
98
60
|
return this.headers.entries();
|
|
99
61
|
}
|
|
100
|
-
/**
|
|
101
|
-
* Returns an iterator over header keys.
|
|
102
|
-
* @returns IterableIterator of header names.
|
|
103
|
-
*/
|
|
104
62
|
keys() {
|
|
105
63
|
return this.headers.keys();
|
|
106
64
|
}
|
|
107
|
-
/**
|
|
108
|
-
* Returns an iterator over header values.
|
|
109
|
-
* @returns IterableIterator of header values arrays.
|
|
110
|
-
*/
|
|
111
65
|
values() {
|
|
112
66
|
return this.headers.values();
|
|
113
67
|
}
|
|
114
|
-
/**
|
|
115
|
-
* Iterates over headers and executes a callback function.
|
|
116
|
-
* @param callback - Function to execute for each header.
|
|
117
|
-
*/
|
|
118
68
|
forEach(callback) {
|
|
119
69
|
for (const [key, value] of this.headers) {
|
|
120
70
|
callback(value, key);
|
|
121
71
|
}
|
|
122
72
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Converts headers into a plain object.
|
|
125
|
-
* @returns A record of headers where single-value headers are returned as a string.
|
|
126
|
-
*/
|
|
127
73
|
toObject() {
|
|
128
74
|
const obj = {};
|
|
129
75
|
for (const [key, value] of this.headers.entries()) {
|
package/dist/helper/common.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a unique request ID
|
|
3
|
-
* @returns {string} - A unique request identifier
|
|
4
|
-
*/
|
|
5
1
|
export function generateID() {
|
|
6
|
-
const timestamp = Date.now().toString(16);
|
|
2
|
+
const timestamp = Date.now().toString(16);
|
|
7
3
|
const random = Math.floor(Math.random() * 0xffffffffffff)
|
|
8
4
|
.toString(16)
|
|
9
|
-
.padStart(12, "0");
|
|
10
|
-
const pid = (process.pid % 0x10000).toString(16).padStart(4, "0");
|
|
5
|
+
.padStart(12, "0");
|
|
6
|
+
const pid = (process.pid % 0x10000).toString(16).padStart(4, "0");
|
|
11
7
|
return `${timestamp}-${random}-${pid}`;
|
|
12
8
|
}
|