tezx 2.0.11 → 3.0.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/README.md +122 -89
- package/bun/getConnInfo.d.ts +21 -0
- package/bun/getConnInfo.js +9 -0
- package/bun/index.d.ts +10 -4
- package/bun/index.js +8 -4
- package/bun/ws.d.ts +48 -0
- package/bun/ws.js +58 -0
- package/cjs/bun/getConnInfo.js +12 -0
- package/cjs/bun/index.js +35 -7
- package/cjs/bun/ws.js +63 -0
- package/cjs/core/config.js +2 -12
- package/cjs/core/context.js +131 -379
- package/cjs/core/error.js +49 -0
- package/cjs/core/request.js +79 -131
- package/cjs/core/router.js +54 -387
- package/cjs/core/server.js +83 -202
- package/cjs/deno/env.js +4 -4
- package/cjs/deno/getConnInfo.js +18 -0
- package/cjs/deno/index.js +11 -18
- package/cjs/deno/serveStatic.js +53 -0
- package/cjs/deno/ws.js +39 -0
- package/cjs/helper/index.js +46 -10
- package/cjs/index.js +5 -7
- package/cjs/jwt/node.js +94 -0
- package/cjs/jwt/web.js +178 -0
- package/cjs/middleware/basic-auth.js +42 -0
- package/cjs/middleware/bearer-auth.js +34 -0
- package/cjs/middleware/cache-control.js +44 -0
- package/cjs/middleware/cors.js +11 -21
- package/cjs/middleware/detect-bot.js +57 -0
- package/cjs/middleware/i18n.js +73 -60
- package/cjs/middleware/index.js +8 -46
- package/cjs/middleware/logger.js +9 -4
- package/cjs/middleware/pagination.js +3 -2
- package/cjs/middleware/powered-by.js +3 -2
- package/cjs/middleware/rate-limiter.js +38 -0
- package/cjs/middleware/request-id.js +4 -5
- package/cjs/middleware/sanitize-headers.js +22 -0
- package/cjs/middleware/secure-headers copy.js +143 -0
- package/cjs/middleware/secure-headers.js +157 -0
- package/cjs/middleware/{xssProtection.js → xss-protection.js} +5 -8
- package/cjs/node/env.js +7 -7
- package/cjs/node/getConnInfo.js +16 -0
- package/cjs/node/index.js +17 -18
- package/cjs/node/mount-node.js +59 -0
- package/cjs/node/serveStatic.js +56 -0
- package/cjs/node/toWebRequest.js +25 -0
- package/cjs/node/ws.js +82 -0
- package/cjs/registry/RadixRouter.js +148 -0
- package/cjs/registry/index.js +17 -0
- package/cjs/types/headers.js +2 -0
- package/cjs/types/index.js +13 -0
- package/cjs/utils/buffer.js +17 -0
- package/cjs/utils/colors.js +2 -0
- package/cjs/utils/cookie.js +59 -0
- package/cjs/utils/file.js +136 -0
- package/cjs/utils/formData.js +60 -10
- package/cjs/utils/generateID.js +37 -0
- package/cjs/utils/low-level.js +115 -0
- package/cjs/utils/{staticFile.js → mimeTypes.js} +0 -87
- package/cjs/utils/rateLimit.js +41 -0
- package/cjs/utils/response.js +65 -0
- package/cjs/{core/environment.js → utils/runtime.js} +2 -1
- package/cjs/utils/url.js +65 -30
- package/core/config.d.ts +2 -7
- package/core/config.js +2 -12
- package/core/context.d.ts +209 -164
- package/core/context.js +131 -346
- package/core/error.d.ts +96 -0
- package/core/error.js +44 -0
- package/core/request.d.ts +67 -107
- package/core/request.js +78 -130
- package/core/router.d.ts +138 -133
- package/core/router.js +53 -352
- package/core/server.d.ts +99 -38
- package/core/server.js +83 -202
- package/deno/env.js +3 -3
- package/deno/getConnInfo.d.ts +21 -0
- package/deno/getConnInfo.js +15 -0
- package/deno/index.d.ts +9 -4
- package/deno/index.js +7 -4
- package/deno/serveStatic.d.ts +28 -0
- package/deno/serveStatic.js +49 -0
- package/deno/ws.d.ts +42 -0
- package/deno/ws.js +36 -0
- package/helper/index.d.ts +29 -15
- package/helper/index.js +27 -7
- package/index.d.ts +10 -8
- package/index.js +4 -5
- package/jwt/node.d.ts +39 -0
- package/jwt/node.js +87 -0
- package/jwt/web.d.ts +14 -0
- package/jwt/web.js +174 -0
- package/middleware/basic-auth.d.ts +56 -0
- package/middleware/basic-auth.js +38 -0
- package/middleware/bearer-auth.d.ts +53 -0
- package/middleware/bearer-auth.js +30 -0
- package/middleware/cache-control.d.ts +30 -0
- package/middleware/cache-control.js +40 -0
- package/middleware/cors.d.ts +30 -3
- package/middleware/cors.js +12 -22
- package/middleware/detect-bot.d.ts +113 -0
- package/middleware/detect-bot.js +53 -0
- package/middleware/i18n.d.ts +166 -73
- package/middleware/i18n.js +73 -60
- package/middleware/index.d.ts +8 -32
- package/middleware/index.js +8 -44
- package/middleware/logger.d.ts +5 -2
- package/middleware/logger.js +9 -4
- package/middleware/pagination.d.ts +9 -6
- package/middleware/pagination.js +3 -2
- package/middleware/powered-by.d.ts +2 -1
- package/middleware/powered-by.js +3 -2
- package/middleware/{rateLimiter.d.ts → rate-limiter.d.ts} +15 -9
- package/middleware/rate-limiter.js +34 -0
- package/middleware/request-id.d.ts +2 -1
- package/middleware/request-id.js +5 -6
- package/middleware/{sanitizeHeader.d.ts → sanitize-headers.d.ts} +5 -19
- package/middleware/sanitize-headers.js +18 -0
- package/middleware/secure-headers copy.d.ts +15 -0
- package/middleware/secure-headers copy.js +136 -0
- package/middleware/secure-headers.d.ts +132 -0
- package/middleware/secure-headers.js +153 -0
- package/middleware/{xssProtection.d.ts → xss-protection.d.ts} +2 -1
- package/middleware/xss-protection.js +19 -0
- package/node/env.js +4 -4
- package/node/getConnInfo.d.ts +21 -0
- package/node/getConnInfo.js +13 -0
- package/node/index.d.ts +13 -4
- package/node/index.js +11 -4
- package/node/mount-node.d.ts +11 -0
- package/node/mount-node.js +56 -0
- package/node/serveStatic.d.ts +36 -0
- package/node/serveStatic.js +52 -0
- package/node/toWebRequest.js +22 -0
- package/node/ws.d.ts +56 -0
- package/node/ws.js +46 -0
- package/package.json +39 -30
- package/registry/RadixRouter.d.ts +40 -0
- package/registry/RadixRouter.js +144 -0
- package/registry/index.d.ts +2 -0
- package/registry/index.js +1 -0
- package/types/headers.d.ts +2 -0
- package/types/headers.js +1 -0
- package/types/index.d.ts +318 -18
- package/types/index.js +12 -1
- package/utils/buffer.d.ts +1 -0
- package/utils/buffer.js +14 -0
- package/utils/colors.d.ts +24 -0
- package/utils/colors.js +2 -0
- package/utils/cookie.d.ts +55 -0
- package/utils/cookie.js +53 -0
- package/utils/file.d.ts +38 -0
- package/utils/file.js +96 -0
- package/utils/formData.d.ts +41 -1
- package/utils/formData.js +58 -9
- package/utils/generateID.d.ts +42 -0
- package/utils/generateID.js +32 -0
- package/utils/httpStatusMap.d.ts +14 -0
- package/utils/low-level.d.ts +58 -0
- package/utils/low-level.js +108 -0
- package/utils/mimeTypes.d.ts +4 -0
- package/utils/{staticFile.js → mimeTypes.js} +0 -53
- package/utils/rateLimit.d.ts +18 -0
- package/utils/rateLimit.js +37 -0
- package/utils/response.d.ts +18 -0
- package/utils/response.js +58 -0
- package/{core/environment.d.ts → utils/runtime.d.ts} +1 -0
- package/{core/environment.js → utils/runtime.js} +1 -0
- package/utils/url.d.ts +42 -14
- package/utils/url.js +61 -27
- package/bun/adapter.d.ts +0 -127
- package/bun/adapter.js +0 -97
- package/cjs/bun/adapter.js +0 -100
- package/cjs/core/MiddlewareConfigure.js +0 -68
- package/cjs/core/common.js +0 -15
- package/cjs/deno/adpater.js +0 -67
- package/cjs/helper/common.js +0 -17
- package/cjs/middleware/basicAuth.js +0 -71
- package/cjs/middleware/cacheControl.js +0 -90
- package/cjs/middleware/detectBot.js +0 -104
- package/cjs/middleware/detectLocale.js +0 -43
- package/cjs/middleware/lazyLoadModules.js +0 -73
- package/cjs/middleware/rateLimiter.js +0 -24
- package/cjs/middleware/requestTimeout.js +0 -42
- package/cjs/middleware/sanitizeHeader.js +0 -51
- package/cjs/middleware/secureHeaders.js +0 -42
- package/cjs/node/adapter.js +0 -138
- package/cjs/utils/regexRouter.js +0 -58
- package/cjs/utils/state.js +0 -34
- package/cjs/utils/toWebRequest.js +0 -35
- package/cjs/ws/deno.js +0 -20
- package/cjs/ws/index.js +0 -53
- package/cjs/ws/node.js +0 -65
- package/core/MiddlewareConfigure.d.ts +0 -15
- package/core/MiddlewareConfigure.js +0 -63
- package/core/common.d.ts +0 -21
- package/core/common.js +0 -11
- package/deno/adpater.d.ts +0 -38
- package/deno/adpater.js +0 -64
- package/helper/common.d.ts +0 -5
- package/helper/common.js +0 -14
- package/middleware/basicAuth.d.ts +0 -81
- package/middleware/basicAuth.js +0 -67
- package/middleware/cacheControl.d.ts +0 -48
- package/middleware/cacheControl.js +0 -53
- package/middleware/detectBot.d.ts +0 -121
- package/middleware/detectBot.js +0 -98
- package/middleware/detectLocale.d.ts +0 -55
- package/middleware/detectLocale.js +0 -39
- package/middleware/lazyLoadModules.d.ts +0 -72
- package/middleware/lazyLoadModules.js +0 -69
- package/middleware/rateLimiter.js +0 -20
- package/middleware/requestTimeout.d.ts +0 -25
- package/middleware/requestTimeout.js +0 -38
- package/middleware/sanitizeHeader.js +0 -47
- package/middleware/secureHeaders.d.ts +0 -78
- package/middleware/secureHeaders.js +0 -38
- package/middleware/xssProtection.js +0 -22
- package/node/adapter.d.ts +0 -46
- package/node/adapter.js +0 -102
- package/utils/regexRouter.d.ts +0 -66
- package/utils/regexRouter.js +0 -53
- package/utils/state.d.ts +0 -50
- package/utils/state.js +0 -30
- package/utils/staticFile.d.ts +0 -10
- package/utils/toWebRequest.js +0 -32
- package/ws/deno.d.ts +0 -6
- package/ws/deno.js +0 -16
- package/ws/index.d.ts +0 -180
- package/ws/index.js +0 -50
- package/ws/node.d.ts +0 -7
- package/ws/node.js +0 -28
- /package/{utils → node}/toWebRequest.d.ts +0 -0
package/core/request.d.ts
CHANGED
|
@@ -1,136 +1,96 @@
|
|
|
1
|
-
import { ExtractParamsFromPath,
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { ExtractParamsFromPath, HTTPMethod, NetAddr, ReqHeaderKey, RequestHeaders } from "../types/index.js";
|
|
2
|
+
/**
|
|
3
|
+
* A wrapper around the raw HTTP request that provides convenient access to URL, headers, body parsing, and route parameters.
|
|
4
|
+
*
|
|
5
|
+
* @template Path - The route path string used to extract dynamic route parameters.
|
|
6
|
+
*/
|
|
7
|
+
export declare class TezXRequest<Path extends string = any> {
|
|
8
|
+
#private;
|
|
5
9
|
/**
|
|
6
|
-
* Full request URL including protocol and query string
|
|
10
|
+
* Full request URL including protocol and query string.
|
|
7
11
|
* @type {string}
|
|
8
12
|
*/
|
|
9
13
|
readonly url: string;
|
|
10
14
|
/**
|
|
11
|
-
* HTTP request method (GET, POST, PUT, DELETE
|
|
15
|
+
* HTTP request method (e.g., GET, POST, PUT, DELETE).
|
|
12
16
|
* @type {HTTPMethod}
|
|
13
17
|
*/
|
|
14
18
|
readonly method: HTTPMethod;
|
|
15
19
|
/**
|
|
16
|
-
* Request path without query parameters
|
|
20
|
+
* Request path without query parameters.
|
|
17
21
|
* @type {string}
|
|
18
22
|
*/
|
|
19
23
|
readonly pathname: string;
|
|
20
|
-
/** Parsed URL reference containing components like query parameters, pathname, etc. */
|
|
21
|
-
readonly urlRef: UrlRef;
|
|
22
|
-
/** Query parameters extracted from the URL */
|
|
23
|
-
readonly query: Record<string, any>;
|
|
24
|
-
protected rawRequest: any;
|
|
25
24
|
/**
|
|
26
|
-
*
|
|
27
|
-
* @
|
|
28
|
-
* @returns The parameter value if found, or undefined.
|
|
25
|
+
* Route parameters extracted from the path.
|
|
26
|
+
* @type {ExtractParamsFromPath<Path>}
|
|
29
27
|
*/
|
|
30
28
|
readonly params: ExtractParamsFromPath<Path>;
|
|
31
29
|
/**
|
|
32
|
-
*
|
|
30
|
+
* Remote address details of the connected client.
|
|
31
|
+
* @requires injectRemoteAddress middleware.
|
|
32
|
+
* @typedef {Object} NetAddr
|
|
33
|
+
* @property {string} [transport] - Transport protocol (e.g., "tcp", "udp").
|
|
34
|
+
* @property {"IPv4" | "IPv6" | "Unix"} [family] - Address family.
|
|
35
|
+
* @property {string} [hostname] - Hostname or IP address.
|
|
36
|
+
* @property {number} [port] - Port number.
|
|
37
|
+
* @type {NetAddr}
|
|
38
|
+
* @default {}
|
|
39
|
+
*/
|
|
40
|
+
remoteAddress: NetAddr;
|
|
41
|
+
/**
|
|
42
|
+
* Creates an instance of TezXRequest.
|
|
33
43
|
*
|
|
34
|
-
* @
|
|
35
|
-
* @
|
|
36
|
-
* @
|
|
37
|
-
* @
|
|
38
|
-
|
|
44
|
+
* @param {Request} req - The raw Request object.
|
|
45
|
+
* @param {string} method - The HTTP method.
|
|
46
|
+
* @param {string} pathname - The request path without query parameters.
|
|
47
|
+
* @param {ExtractParamsFromPath<Path>} params - Route parameters extracted from the path.
|
|
48
|
+
*/
|
|
49
|
+
constructor(req: Request, method: string, pathname: string, params: ExtractParamsFromPath<Path>);
|
|
50
|
+
/**
|
|
51
|
+
* Gets a single header value by name, or all headers as an object if no name is provided.
|
|
39
52
|
*
|
|
40
|
-
* @
|
|
41
|
-
*
|
|
42
|
-
* ctx.req.remoteAddress
|
|
43
|
-
* ```
|
|
53
|
+
* @param {ReqHeaderKey} [header] - The header name.
|
|
54
|
+
* @returns {string | undefined | RequestHeaders} The header value or map of all headers.
|
|
44
55
|
*/
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
get
|
|
53
|
-
/**
|
|
54
|
-
* Retrieves the first value of a specific header.
|
|
55
|
-
* @param key - Header name to search for.
|
|
56
|
-
* @returns The first header value or null if not found.
|
|
57
|
-
* @example
|
|
58
|
-
* get('content-type') // returns 'application/json'
|
|
59
|
-
*/
|
|
60
|
-
get: (key: string) => string | null;
|
|
61
|
-
/**
|
|
62
|
-
* Checks if a header exists in the request.
|
|
63
|
-
* @param key - Header name to check for existence.
|
|
64
|
-
* @returns True if the header exists, false otherwise.
|
|
65
|
-
* @example
|
|
66
|
-
* has('Authorization') // returns true if 'Authorization' header exists
|
|
67
|
-
*/
|
|
68
|
-
has: (key: string) => boolean;
|
|
69
|
-
/**
|
|
70
|
-
* Returns an iterator over all header entries.
|
|
71
|
-
* Each entry is a [key, value] pair where the value can be an array of strings.
|
|
72
|
-
* @returns HeadersIterator for iterating over header key-value pairs.
|
|
73
|
-
* @example
|
|
74
|
-
* for (let [key, value] of headers.entries()) {
|
|
75
|
-
* console.log(key, value);
|
|
76
|
-
* }
|
|
77
|
-
*/
|
|
78
|
-
entries: () => HeadersIterator<[string, string]>;
|
|
79
|
-
/**
|
|
80
|
-
* Returns an iterator over all header keys.
|
|
81
|
-
* This allows iteration over the names of all headers in the request.
|
|
82
|
-
* @returns HeadersIterator of header names.
|
|
83
|
-
* @example
|
|
84
|
-
* for (let key of headers.keys()) {
|
|
85
|
-
* console.log(key);
|
|
86
|
-
* }
|
|
87
|
-
*/
|
|
88
|
-
keys: () => HeadersIterator<string>;
|
|
89
|
-
/**
|
|
90
|
-
* Returns an iterator over all header values.
|
|
91
|
-
* This allows iteration over the values of all headers, with each value being an array of strings.
|
|
92
|
-
* @returns HeadersIterator<string> of header values.
|
|
93
|
-
* @example
|
|
94
|
-
* for (let value of headers.values()) {
|
|
95
|
-
* console.log(value);
|
|
96
|
-
* }
|
|
97
|
-
*/
|
|
98
|
-
values: () => HeadersIterator<string>;
|
|
99
|
-
/**
|
|
100
|
-
* Iterates over each header and executes a callback for every header found.
|
|
101
|
-
* @param callback - Function to execute for each header. Receives the value array and key.
|
|
102
|
-
* @example
|
|
103
|
-
* headers.forEach((key, value) => {
|
|
104
|
-
* console.log(key, value);
|
|
105
|
-
* });
|
|
106
|
-
*/
|
|
107
|
-
forEach: (callbackfn: (value: string, key: string, parent: Headers) => void) => void;
|
|
108
|
-
/**
|
|
109
|
-
* Converts headers to a JSON-safe plain object (only single string values).
|
|
110
|
-
* Multi-value headers are joined by commas.
|
|
111
|
-
* @returns A record of headers with string values.
|
|
112
|
-
*/
|
|
113
|
-
toJSON(): Record<string, string>;
|
|
114
|
-
};
|
|
56
|
+
header(): RequestHeaders;
|
|
57
|
+
header(header: ReqHeaderKey): string | undefined;
|
|
58
|
+
/**
|
|
59
|
+
* Parses the query string from the URL into a key-value object.
|
|
60
|
+
*
|
|
61
|
+
* @returns {Record<string, any>} Query parameters.
|
|
62
|
+
*/
|
|
63
|
+
get query(): Record<string, string | string[]>;
|
|
115
64
|
/**
|
|
116
65
|
* Parses the request body as plain text.
|
|
66
|
+
*
|
|
117
67
|
* @returns {Promise<string>} The text content of the request body.
|
|
118
68
|
*/
|
|
119
|
-
text(): Promise<
|
|
69
|
+
text(): Promise<string>;
|
|
120
70
|
/**
|
|
121
71
|
* Parses the request body as JSON.
|
|
122
|
-
*
|
|
123
|
-
*
|
|
72
|
+
*
|
|
73
|
+
* @template T - Expected type of parsed JSON object.
|
|
74
|
+
* @returns {Promise<T>} Parsed JSON or empty object if not application/json.
|
|
124
75
|
*/
|
|
125
|
-
json(): Promise<
|
|
76
|
+
json<T extends Record<string, any>>(): Promise<T>;
|
|
126
77
|
/**
|
|
127
|
-
* Parses the
|
|
128
|
-
*
|
|
129
|
-
*
|
|
130
|
-
* - application/x-www-form-urlencoded
|
|
131
|
-
* - multipart/form-data
|
|
132
|
-
*
|
|
133
|
-
*
|
|
78
|
+
* Parses and returns the form data from the incoming HTTP request.
|
|
79
|
+
*
|
|
80
|
+
* ✅ Supports:
|
|
81
|
+
* - `application/x-www-form-urlencoded`
|
|
82
|
+
* - `multipart/form-data`
|
|
83
|
+
*
|
|
84
|
+
* ⚠️ Throws:
|
|
85
|
+
* - If the `Content-Type` header is missing.
|
|
86
|
+
* - If the body has already been read/consumed elsewhere.
|
|
87
|
+
*
|
|
88
|
+
* 🧠 Internally caches the parsed `FormData` to prevent multiple reads.
|
|
89
|
+
*
|
|
90
|
+
* @returns {Promise<FormData>}
|
|
91
|
+
* A promise that resolves to a native `FormData` object.
|
|
92
|
+
*
|
|
93
|
+
* @throws {Error} If the content type is missing or the request body has already been consumed.
|
|
134
94
|
*/
|
|
135
|
-
formData(
|
|
95
|
+
formData(): Promise<FormData>;
|
|
136
96
|
}
|
package/core/request.js
CHANGED
|
@@ -1,148 +1,96 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
export class
|
|
1
|
+
import { url2query } from "../utils/url.js";
|
|
2
|
+
import { TezXError } from "./error.js";
|
|
3
|
+
export class TezXRequest {
|
|
4
4
|
url;
|
|
5
5
|
method;
|
|
6
6
|
pathname;
|
|
7
|
-
|
|
8
|
-
protocol: undefined,
|
|
9
|
-
origin: undefined,
|
|
10
|
-
hostname: undefined,
|
|
11
|
-
port: undefined,
|
|
12
|
-
href: undefined,
|
|
13
|
-
query: {},
|
|
14
|
-
pathname: "/",
|
|
15
|
-
};
|
|
16
|
-
query;
|
|
17
|
-
rawRequest;
|
|
7
|
+
#rawRequest;
|
|
18
8
|
params = {};
|
|
19
9
|
remoteAddress = {};
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
10
|
+
#bodyConsumed = false;
|
|
11
|
+
#rawBodyArrayBuffer;
|
|
12
|
+
#cachedText;
|
|
13
|
+
#cachedJSON;
|
|
14
|
+
#cachedFormObject;
|
|
15
|
+
#headersCache;
|
|
16
|
+
#queryCache;
|
|
17
|
+
constructor(req, method, pathname, params) {
|
|
18
|
+
this.url = req.url;
|
|
19
|
+
this.params = params ?? {};
|
|
26
20
|
this.method = method;
|
|
27
|
-
this
|
|
28
|
-
this.
|
|
29
|
-
this.pathname = parse.pathname;
|
|
30
|
-
this.query = parse.query;
|
|
21
|
+
this.#rawRequest = req;
|
|
22
|
+
this.pathname = pathname ?? "/";
|
|
31
23
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
toJSON() {
|
|
54
|
-
const obj = {};
|
|
55
|
-
for (const [key, value] of requestHeaders.entries()) {
|
|
56
|
-
obj[key] = value;
|
|
57
|
-
}
|
|
58
|
-
return obj;
|
|
59
|
-
},
|
|
60
|
-
};
|
|
24
|
+
header(header) {
|
|
25
|
+
if (header) {
|
|
26
|
+
return this.#rawRequest.headers.get(header.toLowerCase());
|
|
27
|
+
}
|
|
28
|
+
if (this.#headersCache)
|
|
29
|
+
return this.#headersCache;
|
|
30
|
+
const obj = {};
|
|
31
|
+
this.#rawRequest.headers.forEach((value, key) => {
|
|
32
|
+
obj[key.toLowerCase()] = value;
|
|
33
|
+
});
|
|
34
|
+
this.#headersCache = obj;
|
|
35
|
+
return this.#headersCache;
|
|
36
|
+
}
|
|
37
|
+
get query() {
|
|
38
|
+
return (this.#queryCache ??= url2query(this.url));
|
|
39
|
+
}
|
|
40
|
+
async #ensureRawBuffer() {
|
|
41
|
+
if (this.#bodyConsumed)
|
|
42
|
+
return;
|
|
43
|
+
this.#rawBodyArrayBuffer = await this.#rawRequest.arrayBuffer();
|
|
44
|
+
this.#bodyConsumed = true;
|
|
61
45
|
}
|
|
62
46
|
async text() {
|
|
63
|
-
|
|
47
|
+
if (this.#cachedText !== undefined)
|
|
48
|
+
return this.#cachedText;
|
|
49
|
+
await this.#ensureRawBuffer();
|
|
50
|
+
this.#cachedText = new TextDecoder().decode(this.#rawBodyArrayBuffer);
|
|
51
|
+
return this.#cachedText;
|
|
52
|
+
}
|
|
53
|
+
get #contentType() {
|
|
54
|
+
const ct = this.#rawRequest.headers.get("content-type");
|
|
55
|
+
if (!ct)
|
|
56
|
+
return "";
|
|
57
|
+
return ct.split(";")[0].trim().toLowerCase();
|
|
64
58
|
}
|
|
65
59
|
async json() {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
else {
|
|
60
|
+
if (this.#cachedJSON !== undefined)
|
|
61
|
+
return this.#cachedJSON;
|
|
62
|
+
if (this.#contentType !== "application/json")
|
|
71
63
|
return {};
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
if (!contentType) {
|
|
77
|
-
throw Error("Invalid Content-Type");
|
|
78
|
-
}
|
|
79
|
-
if (contentType.includes("application/json")) {
|
|
80
|
-
return await this.rawRequest.json();
|
|
81
|
-
}
|
|
82
|
-
else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
83
|
-
const formData = await this.rawRequest.formData();
|
|
84
|
-
const result = {};
|
|
85
|
-
for (const [key, value] of formData.entries()) {
|
|
86
|
-
result[key] = value;
|
|
87
|
-
}
|
|
88
|
-
return result;
|
|
89
|
-
}
|
|
90
|
-
else if (contentType.includes("multipart/form-data")) {
|
|
91
|
-
const boundaryMatch = contentType.match(/boundary=([^;]+)/);
|
|
92
|
-
if (!boundaryMatch) {
|
|
93
|
-
throw new Error("Boundary not found in multipart/form-data");
|
|
64
|
+
try {
|
|
65
|
+
if (!this.#bodyConsumed) {
|
|
66
|
+
this.#cachedJSON = await this.#rawRequest.json();
|
|
67
|
+
this.#bodyConsumed = true;
|
|
94
68
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
let val = value;
|
|
99
|
-
if (val instanceof File && typeof options == "object") {
|
|
100
|
-
let filename = val.name;
|
|
101
|
-
if (options?.sanitized) {
|
|
102
|
-
filename = `${Date.now()}-${sanitized(filename)}`;
|
|
103
|
-
}
|
|
104
|
-
if (Array.isArray(options?.allowedTypes) &&
|
|
105
|
-
!options.allowedTypes?.includes(val.type)) {
|
|
106
|
-
throw new Error(`Invalid file type: "${val.type}". Allowed types: ${options.allowedTypes.join(", ")}`);
|
|
107
|
-
}
|
|
108
|
-
if (typeof options?.maxSize !== "undefined" &&
|
|
109
|
-
val.size > options.maxSize) {
|
|
110
|
-
throw new Error(`File size exceeds the limit: ${val.size} bytes (Max: ${options.maxSize} bytes)`);
|
|
111
|
-
}
|
|
112
|
-
if (typeof options?.maxFiles != "undefined" &&
|
|
113
|
-
options.maxFiles == 0) {
|
|
114
|
-
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
115
|
-
}
|
|
116
|
-
val = new File([await val.arrayBuffer()], filename, {
|
|
117
|
-
type: val.type,
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
if (result[key]) {
|
|
121
|
-
if (Array.isArray(result[key])) {
|
|
122
|
-
if (val instanceof File &&
|
|
123
|
-
typeof options?.maxFiles != "undefined" &&
|
|
124
|
-
result[key]?.length >= options.maxFiles) {
|
|
125
|
-
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
126
|
-
}
|
|
127
|
-
result[key].push(val);
|
|
128
|
-
}
|
|
129
|
-
else {
|
|
130
|
-
if (val instanceof File &&
|
|
131
|
-
typeof options?.maxFiles != "undefined" &&
|
|
132
|
-
options.maxFiles == 1) {
|
|
133
|
-
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
134
|
-
}
|
|
135
|
-
result[key] = [result[key], val];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
else {
|
|
139
|
-
result[key] = val;
|
|
140
|
-
}
|
|
69
|
+
else {
|
|
70
|
+
const txt = await this.text();
|
|
71
|
+
this.#cachedJSON = txt ? JSON.parse(txt) : {};
|
|
141
72
|
}
|
|
142
|
-
return result;
|
|
143
73
|
}
|
|
144
|
-
|
|
145
|
-
|
|
74
|
+
catch {
|
|
75
|
+
this.#cachedJSON = {};
|
|
76
|
+
}
|
|
77
|
+
return this.#cachedJSON;
|
|
78
|
+
}
|
|
79
|
+
async formData() {
|
|
80
|
+
if (this.#cachedFormObject)
|
|
81
|
+
return this.#cachedFormObject;
|
|
82
|
+
const ct = this.#contentType;
|
|
83
|
+
if (!ct)
|
|
84
|
+
throw new TezXError("Missing Content-Type");
|
|
85
|
+
if (ct === "application/x-www-form-urlencoded" ||
|
|
86
|
+
ct === "multipart/form-data") {
|
|
87
|
+
if (this.#bodyConsumed) {
|
|
88
|
+
throw new TezXError("Multipart body already consumed elsewhere");
|
|
89
|
+
}
|
|
90
|
+
this.#cachedFormObject = (await this.#rawRequest.formData());
|
|
91
|
+
this.#bodyConsumed = true;
|
|
92
|
+
return this.#cachedFormObject;
|
|
146
93
|
}
|
|
94
|
+
return this.#cachedFormObject;
|
|
147
95
|
}
|
|
148
96
|
}
|