tezx 1.0.74 → 1.0.76-beta
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/adapter/bun.d.ts +29 -0
- package/adapter/deno.d.ts +30 -0
- package/adapter/index.d.ts +1 -1
- package/adapter/index.js +1 -1
- package/adapter/node/index.d.ts +47 -0
- package/adapter/{node.js → node/index.js} +2 -2
- package/cjs/adapter/index.js +1 -1
- package/cjs/adapter/{node.js → node/index.js} +2 -2
- package/cjs/core/context.js +13 -97
- package/cjs/core/environment.js +0 -8
- package/cjs/core/request.js +69 -25
- package/cjs/core/router.js +5 -0
- package/cjs/core/server.js +6 -5
- package/cjs/index.js +1 -1
- package/cjs/middleware/cors.js +1 -1
- package/cjs/middleware/sanitizeHeader.js +2 -2
- package/cjs/utils/formData.js +0 -235
- package/cjs/utils/httpStatusMap.js +68 -0
- package/cjs/utils/staticFile.js +4 -1
- package/cjs/utils/toWebRequest.js +35 -0
- package/core/context.d.ts +5 -6
- package/core/context.js +14 -98
- package/core/environment.d.ts +0 -2
- package/core/environment.js +0 -8
- package/core/request.d.ts +11 -32
- package/core/request.js +70 -26
- package/core/router.d.ts +29 -0
- package/core/router.js +5 -0
- package/core/server.js +5 -4
- package/index.js +1 -1
- package/middleware/cors.js +1 -1
- package/middleware/sanitizeHeader.js +2 -2
- package/package.json +1 -1
- package/utils/formData.d.ts +0 -5
- package/utils/formData.js +0 -231
- package/utils/httpStatusMap.d.ts +1 -0
- package/utils/httpStatusMap.js +65 -0
- package/utils/staticFile.js +4 -1
- package/utils/toWebRequest.d.ts +11 -0
- package/utils/toWebRequest.js +32 -0
- package/adapter/node.d.ts +0 -19
- package/cjs/core/header.js +0 -92
- package/core/header.d.ts +0 -77
- package/core/header.js +0 -88
package/adapter/bun.d.ts
CHANGED
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
import { TezX } from "../core/server.js";
|
|
2
|
+
/**
|
|
3
|
+
* Starts the TezX server using Bun's built-in HTTP server.
|
|
4
|
+
*
|
|
5
|
+
* Supports Unix socket or TCP port, TLS options, hot reloading, error handling,
|
|
6
|
+
* WebSocket upgrade, and other Bun-specific server features.
|
|
7
|
+
*
|
|
8
|
+
* ### Usage examples:
|
|
9
|
+
* ```ts
|
|
10
|
+
* // Start server on port 3000
|
|
11
|
+
* bunAdapter(app).listen(3000, () => {
|
|
12
|
+
* console.log("Bun server running on port 3000");
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Start Unix socket server
|
|
16
|
+
* bunAdapter(app, { unix: "/tmp/tezx.sock" }).listen();
|
|
17
|
+
*
|
|
18
|
+
* // Start server with TLS and custom error handler
|
|
19
|
+
* bunAdapter(app, {
|
|
20
|
+
* port: 443,
|
|
21
|
+
* tls: { certFile: "./cert.pem", keyFile: "./key.pem" },
|
|
22
|
+
* error: (server, err) => new Response("Custom error", { status: 500 }),
|
|
23
|
+
* }).listen();
|
|
24
|
+
* ```
|
|
25
|
+
*
|
|
26
|
+
* @param {number} [port] - The TCP port number to listen on (ignored if unix socket is used).
|
|
27
|
+
* @param {(message: string) => void} [callback] - Optional callback invoked once the server starts.
|
|
28
|
+
* @returns {ReturnType<typeof Bun.serve>} Bun server instance.
|
|
29
|
+
* @throws {Error} Throws if Bun runtime is not detected.
|
|
30
|
+
*/
|
|
2
31
|
export declare function bunAdapter<T extends Record<string, any> = {}>(TezX: TezX<T>, options?: {
|
|
3
32
|
/**
|
|
4
33
|
* If set, the HTTP server will listen on a unix socket instead of a port.
|
package/adapter/deno.d.ts
CHANGED
|
@@ -1,4 +1,34 @@
|
|
|
1
1
|
import { TezX } from "../core/server.js";
|
|
2
|
+
/**
|
|
3
|
+
* Starts the TezX server using Deno's built-in serve APIs.
|
|
4
|
+
*
|
|
5
|
+
* Automatically selects between Unix socket and TCP server based on options.
|
|
6
|
+
* Supports TLS if TLS options are provided.
|
|
7
|
+
*
|
|
8
|
+
* ### Usage examples:
|
|
9
|
+
* ```ts
|
|
10
|
+
* // Start TCP server on port 3000
|
|
11
|
+
* denoAdapter(app).listen(3000, () => {
|
|
12
|
+
* console.log("Server running on port 3000");
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* // Start Unix socket server
|
|
16
|
+
* denoAdapter(app, { transport: "unix", path: "/tmp/tezx.sock" }).listen(() => {
|
|
17
|
+
* console.log("Server running on unix socket");
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // With TLS
|
|
21
|
+
* denoAdapter(app, {
|
|
22
|
+
* port: 443,
|
|
23
|
+
* cert: Deno.readTextFileSync("./cert.pem"),
|
|
24
|
+
* key: Deno.readTextFileSync("./key.pem"),
|
|
25
|
+
* }).listen();
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @param {number} [port] - TCP port number to listen on (ignored if using Unix socket).
|
|
29
|
+
* @param {(message: string) => void} [callback] - Optional callback invoked after server starts.
|
|
30
|
+
* @returns {Deno.Listener | Deno.Server | null} Returns the server instance or null if Deno runtime is not detected.
|
|
31
|
+
*/
|
|
2
32
|
export declare function denoAdapter<T extends Record<string, any> = {}>(TezX: TezX<T>, options?: Deno.ServeUnixOptions | Deno.ServeTcpOptions | (Deno.ServeTcpOptions & Deno.TlsCertifiedKeyPem)): {
|
|
3
33
|
listen: {
|
|
4
34
|
(callback?: (message: string) => void): any;
|
package/adapter/index.d.ts
CHANGED
package/adapter/index.js
CHANGED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type { ServerOptions } from "node:http";
|
|
2
|
+
import type { TlsOptions } from "node:tls";
|
|
3
|
+
import { TezX } from "../../core/server.js";
|
|
4
|
+
type UnixSocketOptions = ServerOptions & {
|
|
5
|
+
unix?: string;
|
|
6
|
+
enableSSL?: false;
|
|
7
|
+
};
|
|
8
|
+
type SSLOptions = ServerOptions & TlsOptions & {
|
|
9
|
+
enableSSL: true;
|
|
10
|
+
};
|
|
11
|
+
type TezXServerOptions = UnixSocketOptions | SSLOptions;
|
|
12
|
+
/**
|
|
13
|
+
* Starts the TezX server using Node.js native `http` or `https` module based on the `enableSSL` flag.
|
|
14
|
+
* - If `enableSSL` is true and valid TLS options are provided, it uses `https.createServer`.
|
|
15
|
+
* - Otherwise, falls back to `http.createServer`.
|
|
16
|
+
* - Optionally supports binding to a Unix domain socket via `options.unix`.
|
|
17
|
+
*
|
|
18
|
+
* ### Usage:
|
|
19
|
+
*
|
|
20
|
+
* ```ts
|
|
21
|
+
* // Start with default HTTP
|
|
22
|
+
* nodeAdapter(app).listen(3000, () => {
|
|
23
|
+
* console.log("Server is running");
|
|
24
|
+
* });
|
|
25
|
+
*
|
|
26
|
+
* // Start with HTTPS
|
|
27
|
+
* nodeAdapter(app, {
|
|
28
|
+
* enableSSL: true,
|
|
29
|
+
* key: fs.readFileSync("key.pem"),
|
|
30
|
+
* cert: fs.readFileSync("cert.pem")
|
|
31
|
+
* }).listen(443);
|
|
32
|
+
*
|
|
33
|
+
* // Start with Unix socket
|
|
34
|
+
* nodeAdapter(app, { unix: "/tmp/tezx.sock" }).listen();
|
|
35
|
+
* ```
|
|
36
|
+
* @param {number} [port] - The port number to listen on (ignored if `unix` is provided).
|
|
37
|
+
* @param {() => void} [callback] - Callback invoked after the server starts listening.
|
|
38
|
+
* @returns {void} Nothing is returned directly; server instance is stored in GlobalConfig.
|
|
39
|
+
*/
|
|
40
|
+
export declare function nodeAdapter<T extends Record<string, any> = {}>(TezX: TezX<T>, options?: TezXServerOptions): {
|
|
41
|
+
listen: {
|
|
42
|
+
(callback?: () => void): any;
|
|
43
|
+
(port?: number): any;
|
|
44
|
+
(port?: number, callback?: () => void): any;
|
|
45
|
+
};
|
|
46
|
+
};
|
|
47
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Buffer } from "node:buffer";
|
|
2
|
-
import { GlobalConfig } from "
|
|
3
|
-
import { Context } from "
|
|
2
|
+
import { GlobalConfig } from "../../core/config.js";
|
|
3
|
+
import { Context } from "../../core/context.js";
|
|
4
4
|
export function nodeAdapter(TezX, options = {}) {
|
|
5
5
|
function listen(...arg) {
|
|
6
6
|
let ssl = options?.enableSSL;
|
package/cjs/adapter/index.js
CHANGED
|
@@ -16,4 +16,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./bun.js"), exports);
|
|
18
18
|
__exportStar(require("./deno.js"), exports);
|
|
19
|
-
__exportStar(require("./node.js"), exports);
|
|
19
|
+
__exportStar(require("./node/index.js"), exports);
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.nodeAdapter = nodeAdapter;
|
|
4
4
|
const node_buffer_1 = require("node:buffer");
|
|
5
|
-
const config_js_1 = require("
|
|
6
|
-
const context_js_1 = require("
|
|
5
|
+
const config_js_1 = require("../../core/config.js");
|
|
6
|
+
const context_js_1 = require("../../core/context.js");
|
|
7
7
|
function nodeAdapter(TezX, options = {}) {
|
|
8
8
|
function listen(...arg) {
|
|
9
9
|
let ssl = options?.enableSSL;
|
package/cjs/core/context.js
CHANGED
|
@@ -1,82 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Context =
|
|
3
|
+
exports.Context = void 0;
|
|
4
4
|
const state_js_1 = require("../utils/state.js");
|
|
5
5
|
const staticFile_js_1 = require("../utils/staticFile.js");
|
|
6
|
-
const
|
|
6
|
+
const toWebRequest_js_1 = require("../utils/toWebRequest.js");
|
|
7
7
|
const config_js_1 = require("./config.js");
|
|
8
8
|
const environment_js_1 = require("./environment.js");
|
|
9
|
-
const header_js_1 = require("./header.js");
|
|
10
9
|
const request_js_1 = require("./request.js");
|
|
11
|
-
exports.httpStatusMap = {
|
|
12
|
-
100: "Continue",
|
|
13
|
-
101: "Switching Protocols",
|
|
14
|
-
102: "Processing",
|
|
15
|
-
103: "Early Hints",
|
|
16
|
-
200: "OK",
|
|
17
|
-
201: "Created",
|
|
18
|
-
202: "Accepted",
|
|
19
|
-
203: "Non-Authoritative Information",
|
|
20
|
-
204: "No Content",
|
|
21
|
-
205: "Reset Content",
|
|
22
|
-
206: "Partial Content",
|
|
23
|
-
207: "Multi-Status",
|
|
24
|
-
208: "Already Reported",
|
|
25
|
-
226: "IM Used",
|
|
26
|
-
300: "Multiple Choices",
|
|
27
|
-
301: "Moved Permanently",
|
|
28
|
-
302: "Found",
|
|
29
|
-
303: "See Other",
|
|
30
|
-
304: "Not Modified",
|
|
31
|
-
305: "Use Proxy",
|
|
32
|
-
306: "Switch Proxy",
|
|
33
|
-
307: "Temporary Redirect",
|
|
34
|
-
308: "Permanent Redirect",
|
|
35
|
-
400: "Bad Request",
|
|
36
|
-
401: "Unauthorized",
|
|
37
|
-
402: "Payment Required",
|
|
38
|
-
403: "Forbidden",
|
|
39
|
-
404: "Not Found",
|
|
40
|
-
405: "Method Not Allowed",
|
|
41
|
-
406: "Not Acceptable",
|
|
42
|
-
407: "Proxy Authentication Required",
|
|
43
|
-
408: "Request Timeout",
|
|
44
|
-
409: "Conflict",
|
|
45
|
-
410: "Gone",
|
|
46
|
-
411: "Length Required",
|
|
47
|
-
412: "Precondition Failed",
|
|
48
|
-
413: "Payload Too Large",
|
|
49
|
-
414: "URI Too Long",
|
|
50
|
-
415: "Unsupported Media Type",
|
|
51
|
-
416: "Range Not Satisfiable",
|
|
52
|
-
417: "Expectation Failed",
|
|
53
|
-
418: "I'm a Teapot",
|
|
54
|
-
421: "Misdirected Request",
|
|
55
|
-
422: "Unprocessable Entity",
|
|
56
|
-
423: "Locked",
|
|
57
|
-
424: "Failed Dependency",
|
|
58
|
-
425: "Too Early",
|
|
59
|
-
426: "Upgrade Required",
|
|
60
|
-
428: "Precondition Required",
|
|
61
|
-
429: "Too Many Requests",
|
|
62
|
-
431: "Request Header Fields Too Large",
|
|
63
|
-
451: "Unavailable For Legal Reasons",
|
|
64
|
-
500: "Internal Server Error",
|
|
65
|
-
501: "Not Implemented",
|
|
66
|
-
502: "Bad Gateway",
|
|
67
|
-
503: "Service Unavailable",
|
|
68
|
-
504: "Gateway Timeout",
|
|
69
|
-
505: "HTTP Version Not Supported",
|
|
70
|
-
506: "Variant Also Negotiates",
|
|
71
|
-
507: "Insufficient Storage",
|
|
72
|
-
508: "Loop Detected",
|
|
73
|
-
510: "Not Extended",
|
|
74
|
-
511: "Network Authentication Required",
|
|
75
|
-
};
|
|
76
10
|
class Context {
|
|
77
|
-
|
|
11
|
+
rawRequest;
|
|
78
12
|
env = {};
|
|
79
|
-
headers = new
|
|
13
|
+
headers = new Headers();
|
|
80
14
|
pathname;
|
|
81
15
|
url;
|
|
82
16
|
method;
|
|
@@ -85,30 +19,20 @@ class Context {
|
|
|
85
19
|
#params = {};
|
|
86
20
|
resBody;
|
|
87
21
|
#body;
|
|
88
|
-
#urlRef;
|
|
89
|
-
#requestHeaders;
|
|
90
22
|
#options;
|
|
91
23
|
constructor(req, options) {
|
|
92
24
|
this.#options = options;
|
|
93
|
-
this.#rawRequest = req;
|
|
94
25
|
this.method = req?.method?.toUpperCase();
|
|
95
|
-
this.#requestHeaders = new header_js_1.HeadersParser(req?.headers);
|
|
96
26
|
if (config_js_1.GlobalConfig.adapter == "node") {
|
|
97
|
-
let
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
? "https"
|
|
101
|
-
: "http"
|
|
102
|
-
: "http";
|
|
103
|
-
const host = environment_js_1.EnvironmentDetector.getHost(this.#requestHeaders);
|
|
104
|
-
const path = req.url || "/";
|
|
105
|
-
this.url = `${protocol}://${host}${path}`;
|
|
27
|
+
let request = (0, toWebRequest_js_1.toWebRequest)(req, this.method);
|
|
28
|
+
this.url = request.url;
|
|
29
|
+
this.rawRequest = request;
|
|
106
30
|
}
|
|
107
31
|
else {
|
|
108
32
|
this.url = req.url;
|
|
33
|
+
this.rawRequest = req;
|
|
109
34
|
}
|
|
110
|
-
this
|
|
111
|
-
this.pathname = this.#urlRef.pathname;
|
|
35
|
+
this.pathname = this.req.urlRef.pathname;
|
|
112
36
|
}
|
|
113
37
|
header(key, value, options) {
|
|
114
38
|
let append = options?.append;
|
|
@@ -121,16 +45,9 @@ class Context {
|
|
|
121
45
|
return this;
|
|
122
46
|
}
|
|
123
47
|
get cookies() {
|
|
124
|
-
const c = this
|
|
48
|
+
const c = this.req.headers.get("cookie");
|
|
125
49
|
let cookies = {};
|
|
126
|
-
if (
|
|
127
|
-
const cookieHeader = c.join("; ").split(";");
|
|
128
|
-
for (const pair of cookieHeader) {
|
|
129
|
-
const [key, value] = pair?.trim()?.split("=");
|
|
130
|
-
cookies[key] = decodeURIComponent(value);
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
else if (typeof c == "string") {
|
|
50
|
+
if (typeof c == "string") {
|
|
134
51
|
const cookieHeader = c.split(";");
|
|
135
52
|
for (const pair of cookieHeader) {
|
|
136
53
|
const [key, value] = pair?.trim()?.split("=");
|
|
@@ -422,9 +339,8 @@ class Context {
|
|
|
422
339
|
}
|
|
423
340
|
get req() {
|
|
424
341
|
return new request_js_1.Request({
|
|
425
|
-
|
|
426
|
-
req: this
|
|
427
|
-
urlRef: this.#urlRef,
|
|
342
|
+
method: this.method,
|
|
343
|
+
req: this.rawRequest,
|
|
428
344
|
options: this.#options,
|
|
429
345
|
params: this.#params,
|
|
430
346
|
});
|
package/cjs/core/environment.js
CHANGED
|
@@ -11,13 +11,5 @@ class EnvironmentDetector {
|
|
|
11
11
|
return "node";
|
|
12
12
|
return "unknown";
|
|
13
13
|
}
|
|
14
|
-
static getHost(headers) {
|
|
15
|
-
try {
|
|
16
|
-
return headers?.get("host") || "unknown";
|
|
17
|
-
}
|
|
18
|
-
catch (error) {
|
|
19
|
-
throw new Error("Failed to get host.");
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
14
|
}
|
|
23
15
|
exports.EnvironmentDetector = EnvironmentDetector;
|
package/cjs/core/request.js
CHANGED
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.Request = void 0;
|
|
4
4
|
const formData_js_1 = require("../utils/formData.js");
|
|
5
|
-
const
|
|
5
|
+
const url_js_1 = require("../utils/url.js");
|
|
6
6
|
class Request {
|
|
7
|
-
#headers = new header_js_1.HeadersParser();
|
|
8
7
|
url;
|
|
9
8
|
method;
|
|
10
9
|
urlRef = {
|
|
@@ -20,25 +19,23 @@ class Request {
|
|
|
20
19
|
rawRequest;
|
|
21
20
|
params = {};
|
|
22
21
|
remoteAddress = {};
|
|
23
|
-
constructor({
|
|
22
|
+
constructor({ params, method, req, options, }) {
|
|
23
|
+
let parse = (0, url_js_1.urlParse)(req.url);
|
|
24
|
+
let url = parse?.href;
|
|
24
25
|
this.remoteAddress = options?.connInfo?.remoteAddr;
|
|
25
|
-
this
|
|
26
|
-
this.
|
|
27
|
-
this.
|
|
28
|
-
this.method = req?.method?.toUpperCase();
|
|
26
|
+
this.url = url || "";
|
|
27
|
+
this.urlRef = parse;
|
|
28
|
+
this.method = method;
|
|
29
29
|
this.params = params;
|
|
30
30
|
this.rawRequest = req;
|
|
31
|
-
this.query =
|
|
31
|
+
this.query = parse.query;
|
|
32
32
|
}
|
|
33
33
|
get headers() {
|
|
34
|
-
let requestHeaders = this
|
|
34
|
+
let requestHeaders = this.rawRequest.headers;
|
|
35
35
|
return {
|
|
36
36
|
get: function get(key) {
|
|
37
37
|
return requestHeaders.get(key.toLowerCase());
|
|
38
38
|
},
|
|
39
|
-
getAll: function getAll(key) {
|
|
40
|
-
return requestHeaders.get(key.toLowerCase()) || [];
|
|
41
|
-
},
|
|
42
39
|
has: function has(key) {
|
|
43
40
|
return requestHeaders.has(key.toLowerCase());
|
|
44
41
|
},
|
|
@@ -51,47 +48,94 @@ class Request {
|
|
|
51
48
|
values: function values() {
|
|
52
49
|
return requestHeaders.values();
|
|
53
50
|
},
|
|
54
|
-
forEach: function forEach(
|
|
55
|
-
return requestHeaders.forEach(
|
|
51
|
+
forEach: function forEach(callbackfn) {
|
|
52
|
+
return requestHeaders.forEach(callbackfn);
|
|
56
53
|
},
|
|
57
54
|
toJSON() {
|
|
58
55
|
return requestHeaders.toJSON();
|
|
59
56
|
},
|
|
60
|
-
toObject: function toObject() {
|
|
61
|
-
return requestHeaders.toObject();
|
|
62
|
-
},
|
|
63
57
|
};
|
|
64
58
|
}
|
|
65
59
|
async text() {
|
|
66
|
-
return await
|
|
60
|
+
return await this.rawRequest.text();
|
|
67
61
|
}
|
|
68
62
|
async json() {
|
|
69
|
-
const contentType = this
|
|
63
|
+
const contentType = this.rawRequest.headers.get("content-type") || "";
|
|
70
64
|
if (contentType.includes("application/json")) {
|
|
71
|
-
return await
|
|
65
|
+
return await this.rawRequest.json();
|
|
72
66
|
}
|
|
73
67
|
else {
|
|
74
68
|
return {};
|
|
75
69
|
}
|
|
76
70
|
}
|
|
77
71
|
async formData(options) {
|
|
78
|
-
const contentType = this
|
|
72
|
+
const contentType = this.rawRequest.headers.get("content-type") || "";
|
|
79
73
|
if (!contentType) {
|
|
80
74
|
throw Error("Invalid Content-Type");
|
|
81
75
|
}
|
|
82
76
|
if (contentType.includes("application/json")) {
|
|
83
|
-
return await
|
|
77
|
+
return await this.rawRequest.json();
|
|
84
78
|
}
|
|
85
79
|
else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
86
|
-
|
|
80
|
+
const formData = await this.rawRequest.formData();
|
|
81
|
+
const result = {};
|
|
82
|
+
for (const [key, value] of formData.entries()) {
|
|
83
|
+
result[key] = value;
|
|
84
|
+
}
|
|
85
|
+
return result;
|
|
87
86
|
}
|
|
88
87
|
else if (contentType.includes("multipart/form-data")) {
|
|
89
88
|
const boundaryMatch = contentType.match(/boundary=([^;]+)/);
|
|
90
89
|
if (!boundaryMatch) {
|
|
91
90
|
throw new Error("Boundary not found in multipart/form-data");
|
|
92
91
|
}
|
|
93
|
-
const
|
|
94
|
-
|
|
92
|
+
const formData = await this.rawRequest.formData();
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const [key, value] of formData.entries()) {
|
|
95
|
+
let val = value;
|
|
96
|
+
if (val instanceof File && typeof options == "object") {
|
|
97
|
+
let filename = val.name;
|
|
98
|
+
if (options?.sanitized) {
|
|
99
|
+
filename = `${Date.now()}-${(0, formData_js_1.sanitized)(filename)}`;
|
|
100
|
+
}
|
|
101
|
+
if (Array.isArray(options?.allowedTypes) &&
|
|
102
|
+
!options.allowedTypes?.includes(val.type)) {
|
|
103
|
+
throw new Error(`Invalid file type: "${val.type}". Allowed types: ${options.allowedTypes.join(", ")}`);
|
|
104
|
+
}
|
|
105
|
+
if (typeof options?.maxSize !== "undefined" &&
|
|
106
|
+
val.size > options.maxSize) {
|
|
107
|
+
throw new Error(`File size exceeds the limit: ${val.size} bytes (Max: ${options.maxSize} bytes)`);
|
|
108
|
+
}
|
|
109
|
+
if (typeof options?.maxFiles != "undefined" && options.maxFiles == 0) {
|
|
110
|
+
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
111
|
+
}
|
|
112
|
+
val = new File([await val.arrayBuffer()], filename, {
|
|
113
|
+
type: val.type,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (result[key]) {
|
|
117
|
+
if (Array.isArray(result[key])) {
|
|
118
|
+
if (val instanceof File &&
|
|
119
|
+
typeof options?.maxFiles != "undefined" &&
|
|
120
|
+
result[key]?.length >= options.maxFiles) {
|
|
121
|
+
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
122
|
+
}
|
|
123
|
+
result[key].push(val);
|
|
124
|
+
}
|
|
125
|
+
else {
|
|
126
|
+
if (val instanceof File &&
|
|
127
|
+
typeof options?.maxFiles != "undefined" &&
|
|
128
|
+
options.maxFiles == 1) {
|
|
129
|
+
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
130
|
+
}
|
|
131
|
+
result[key] = [result[key], val];
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
result[key] = val;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return result;
|
|
95
139
|
}
|
|
96
140
|
else {
|
|
97
141
|
return {};
|
package/cjs/core/router.js
CHANGED
|
@@ -63,6 +63,11 @@ class Router extends MiddlewareConfigure_js_1.default {
|
|
|
63
63
|
this.#registerRoute("GET", path, ...args);
|
|
64
64
|
return this;
|
|
65
65
|
}
|
|
66
|
+
sse(path, handler) {
|
|
67
|
+
this.get(path, async (ctx) => {
|
|
68
|
+
return handler(ctx);
|
|
69
|
+
});
|
|
70
|
+
}
|
|
66
71
|
post(path, ...args) {
|
|
67
72
|
this.#registerRoute("POST", path, ...args);
|
|
68
73
|
return this;
|
package/cjs/core/server.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.TezX = void 0;
|
|
4
4
|
const colors_js_1 = require("../utils/colors.js");
|
|
5
|
+
const httpStatusMap_js_1 = require("../utils/httpStatusMap.js");
|
|
5
6
|
const params_js_1 = require("../utils/params.js");
|
|
6
7
|
const config_js_1 = require("./config.js");
|
|
7
8
|
const context_js_1 = require("./context.js");
|
|
@@ -197,12 +198,12 @@ class TezX extends router_js_1.Router {
|
|
|
197
198
|
}
|
|
198
199
|
let finalResponse = () => {
|
|
199
200
|
return (ctx) => {
|
|
200
|
-
|
|
201
|
-
ctx.headers.
|
|
201
|
+
for (const [key, value] of response?.headers.entries()) {
|
|
202
|
+
ctx.headers.set(key, value);
|
|
202
203
|
}
|
|
203
|
-
const statusText = response?.statusText ||
|
|
204
|
+
const statusText = response?.statusText || httpStatusMap_js_1.httpStatusMap[response?.status] || "";
|
|
204
205
|
const status = response.status || ctx.getStatus;
|
|
205
|
-
let headers = ctx.headers.
|
|
206
|
+
let headers = ctx.headers.toJSON();
|
|
206
207
|
return new Response(response.body, {
|
|
207
208
|
status,
|
|
208
209
|
statusText,
|
|
@@ -221,7 +222,7 @@ class TezX extends router_js_1.Router {
|
|
|
221
222
|
if (err instanceof Error) {
|
|
222
223
|
error = err.stack;
|
|
223
224
|
}
|
|
224
|
-
config_js_1.GlobalConfig.debugging.error(`${colors_js_1.COLORS.bgRed} ${ctx.pathname}, Method: ${ctx.method} ${colors_js_1.COLORS.reset}`, `${
|
|
225
|
+
config_js_1.GlobalConfig.debugging.error(`${colors_js_1.COLORS.bgRed} ${ctx.pathname}, Method: ${ctx.method} ${colors_js_1.COLORS.reset}`, `${httpStatusMap_js_1.httpStatusMap[500]}: ${error} `);
|
|
225
226
|
let res = await config_js_1.GlobalConfig.onError(error, ctx);
|
|
226
227
|
ctx.setStatus = res.status;
|
|
227
228
|
return res;
|
package/cjs/index.js
CHANGED
|
@@ -7,4 +7,4 @@ var server_js_1 = require("./core/server.js");
|
|
|
7
7
|
Object.defineProperty(exports, "TezX", { enumerable: true, get: function () { return server_js_1.TezX; } });
|
|
8
8
|
var params_js_1 = require("./utils/params.js");
|
|
9
9
|
Object.defineProperty(exports, "useParams", { enumerable: true, get: function () { return params_js_1.useParams; } });
|
|
10
|
-
exports.version = "1.0.
|
|
10
|
+
exports.version = "1.0.76-beta";
|
package/cjs/middleware/cors.js
CHANGED
|
@@ -31,9 +31,9 @@ const sanitizeHeaders = (options = {}) => {
|
|
|
31
31
|
config_js_1.GlobalConfig.debugging.warn(`⚠️ All values for "${normalizedKey}" invalid - removed`);
|
|
32
32
|
continue;
|
|
33
33
|
}
|
|
34
|
-
sanitizedHeaders.set(normalizedKey, sanitizedValues);
|
|
34
|
+
sanitizedHeaders.set(normalizedKey, sanitizedValues?.join(", "));
|
|
35
35
|
}
|
|
36
|
-
ctx.headers
|
|
36
|
+
ctx.headers = new Headers(sanitizedHeaders);
|
|
37
37
|
return await next();
|
|
38
38
|
};
|
|
39
39
|
};
|