tezx 1.0.73 → 1.0.75-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/basicAuth.js +1 -1
- package/cjs/middleware/cacheControl.js +1 -1
- package/cjs/middleware/cors.js +2 -2
- package/cjs/middleware/detectBot.js +1 -1
- package/cjs/middleware/detectLocale.js +1 -1
- package/cjs/middleware/{i18nMiddleware.js → i18n.js} +4 -4
- package/cjs/middleware/index.js +1 -1
- package/cjs/middleware/lazyLoadModules.js +1 -1
- package/cjs/middleware/logger.js +1 -1
- package/cjs/middleware/pagination.js +1 -1
- package/cjs/middleware/powered-by.js +1 -1
- package/cjs/middleware/rateLimiter.js +1 -1
- package/cjs/middleware/request-id.js +1 -1
- package/cjs/middleware/requestTimeout.js +1 -1
- package/cjs/middleware/sanitizeHeader.js +3 -3
- package/cjs/middleware/secureHeaders.js +1 -1
- package/cjs/middleware/xssProtection.js +1 -1
- 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 +30 -0
- package/core/router.js +5 -0
- package/core/server.js +5 -4
- package/index.js +1 -1
- package/middleware/basicAuth.js +1 -1
- package/middleware/cacheControl.js +1 -1
- package/middleware/cors.js +2 -2
- package/middleware/detectBot.js +1 -1
- package/middleware/detectLocale.js +1 -1
- package/middleware/{i18nMiddleware.d.ts → i18n.d.ts} +3 -3
- package/middleware/{i18nMiddleware.js → i18n.js} +2 -2
- package/middleware/index.d.ts +1 -1
- package/middleware/index.js +1 -1
- package/middleware/lazyLoadModules.js +1 -1
- package/middleware/logger.js +1 -1
- package/middleware/pagination.js +1 -1
- package/middleware/powered-by.js +1 -1
- package/middleware/rateLimiter.js +1 -1
- package/middleware/request-id.js +1 -1
- package/middleware/requestTimeout.js +1 -1
- package/middleware/sanitizeHeader.js +3 -3
- package/middleware/secureHeaders.js +1 -1
- package/middleware/xssProtection.js +1 -1
- 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/utils/formData.js
CHANGED
|
@@ -1,90 +1,3 @@
|
|
|
1
|
-
import { GlobalConfig } from "../core/config.js";
|
|
2
|
-
export async function parseJsonBody(req) {
|
|
3
|
-
const runtime = GlobalConfig.adapter;
|
|
4
|
-
if (runtime === "node") {
|
|
5
|
-
return new Promise((resolve, reject) => {
|
|
6
|
-
let body = "";
|
|
7
|
-
req.on("data", (chunk) => {
|
|
8
|
-
body += chunk.toString();
|
|
9
|
-
});
|
|
10
|
-
req.on("end", () => {
|
|
11
|
-
try {
|
|
12
|
-
resolve(JSON.parse(body));
|
|
13
|
-
}
|
|
14
|
-
catch (error) {
|
|
15
|
-
reject(new Error("Invalid JSON format"));
|
|
16
|
-
}
|
|
17
|
-
});
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
else if (runtime === "deno" || runtime === "bun") {
|
|
21
|
-
return await req.json();
|
|
22
|
-
}
|
|
23
|
-
else {
|
|
24
|
-
throw new Error("Unsupported environment for multipart parsing");
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export async function parseTextBody(req) {
|
|
28
|
-
const runtime = GlobalConfig.adapter;
|
|
29
|
-
if (runtime === "node") {
|
|
30
|
-
return new Promise((resolve, reject) => {
|
|
31
|
-
let body = "";
|
|
32
|
-
req.on("data", (chunk) => {
|
|
33
|
-
body += chunk.toString();
|
|
34
|
-
});
|
|
35
|
-
req.on("end", () => {
|
|
36
|
-
try {
|
|
37
|
-
resolve(body);
|
|
38
|
-
}
|
|
39
|
-
catch (error) {
|
|
40
|
-
reject(new Error("Invalid JSON format"));
|
|
41
|
-
}
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
}
|
|
45
|
-
else if (runtime === "deno" || runtime === "bun") {
|
|
46
|
-
return await req.text();
|
|
47
|
-
}
|
|
48
|
-
else {
|
|
49
|
-
throw new Error("Unsupported environment for multipart parsing");
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
export async function parseUrlEncodedBody(req) {
|
|
53
|
-
const runtime = GlobalConfig.adapter;
|
|
54
|
-
if (runtime === "node") {
|
|
55
|
-
return new Promise((resolve, reject) => {
|
|
56
|
-
let body = "";
|
|
57
|
-
req.on("data", (chunk) => {
|
|
58
|
-
body += chunk.toString("binary");
|
|
59
|
-
});
|
|
60
|
-
req.on("end", () => {
|
|
61
|
-
try {
|
|
62
|
-
const pairs = body.split("&");
|
|
63
|
-
const formData = {};
|
|
64
|
-
pairs.forEach((pair) => {
|
|
65
|
-
const [key, value] = pair.split("=");
|
|
66
|
-
formData[decodeURIComponent(key)] = decodeURIComponent(value || "");
|
|
67
|
-
});
|
|
68
|
-
resolve(formData);
|
|
69
|
-
}
|
|
70
|
-
catch {
|
|
71
|
-
reject(new Error("Invalid x-www-form-urlencoded format"));
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
else if (runtime === "deno" || runtime === "bun") {
|
|
77
|
-
const formData = await req.formData();
|
|
78
|
-
const result = {};
|
|
79
|
-
for (const [key, value] of formData.entries()) {
|
|
80
|
-
result[key] = value;
|
|
81
|
-
}
|
|
82
|
-
return result;
|
|
83
|
-
}
|
|
84
|
-
else {
|
|
85
|
-
throw new Error("Unsupported environment for multipart parsing");
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
1
|
export function sanitized(title) {
|
|
89
2
|
const base = title
|
|
90
3
|
.toLowerCase()
|
|
@@ -95,147 +8,3 @@ export function sanitized(title) {
|
|
|
95
8
|
.replace(/^-+|-+$/g, "");
|
|
96
9
|
return base;
|
|
97
10
|
}
|
|
98
|
-
export async function parseMultipartBody(req, boundary, options) {
|
|
99
|
-
const runtime = GlobalConfig.adapter;
|
|
100
|
-
if (runtime === "node") {
|
|
101
|
-
return new Promise((resolve, reject) => {
|
|
102
|
-
let body = "";
|
|
103
|
-
req.on("data", (chunk) => {
|
|
104
|
-
body += chunk.toString("binary");
|
|
105
|
-
});
|
|
106
|
-
req.on("end", () => {
|
|
107
|
-
try {
|
|
108
|
-
const formDataField = {};
|
|
109
|
-
const formDataFieldParts = body.split("----------------------------");
|
|
110
|
-
formDataFieldParts.forEach((part) => {
|
|
111
|
-
const match = part.match(/name="(.*)"\r\n\r\n(.*)\r\n/);
|
|
112
|
-
if (match && match.length === 3) {
|
|
113
|
-
const name = match[1];
|
|
114
|
-
const value = match[2];
|
|
115
|
-
if (formDataField[name]) {
|
|
116
|
-
if (Array.isArray(formDataField[name])) {
|
|
117
|
-
formDataField[name].push(value);
|
|
118
|
-
}
|
|
119
|
-
else {
|
|
120
|
-
formDataField[name] = [formDataField[name], value];
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
else {
|
|
124
|
-
formDataField[name] = value;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
});
|
|
128
|
-
const parts = body.split(`--${boundary}`);
|
|
129
|
-
for (const part of parts) {
|
|
130
|
-
if (part.includes("filename")) {
|
|
131
|
-
const filenameMatch = part.match(/filename="([^"]+)"/);
|
|
132
|
-
const fieldNameMatch = part.match(/name="([^"]+)"/);
|
|
133
|
-
const contentTypeMatch = part.match(/Content-Type: ([^\r\n]+)/);
|
|
134
|
-
if (filenameMatch && fieldNameMatch && contentTypeMatch) {
|
|
135
|
-
let filename = filenameMatch[1];
|
|
136
|
-
const fieldName = fieldNameMatch[1];
|
|
137
|
-
const contentType = contentTypeMatch[1];
|
|
138
|
-
if (options?.sanitized) {
|
|
139
|
-
filename = `${Date.now()}-${sanitized(filename)}`;
|
|
140
|
-
}
|
|
141
|
-
if (Array.isArray(options?.allowedTypes) &&
|
|
142
|
-
!options.allowedTypes?.includes(contentType)) {
|
|
143
|
-
reject(new Error(`Invalid file type: "${contentType}". Allowed types: ${options.allowedTypes.join(", ")}`));
|
|
144
|
-
}
|
|
145
|
-
const fileContentStartIndex = part.indexOf("\r\n\r\n") + 4;
|
|
146
|
-
const fileContent = Buffer.from(part.substring(fileContentStartIndex), "binary");
|
|
147
|
-
const arrayBuffer = fileContent.buffer.slice(fileContent.byteOffset, fileContent.byteOffset + fileContent.byteLength);
|
|
148
|
-
if (typeof options?.maxSize !== "undefined" &&
|
|
149
|
-
fileContent.byteLength > options.maxSize) {
|
|
150
|
-
reject(new Error(`File size exceeds the limit: ${fileContent.byteLength} bytes (Max: ${options.maxSize} bytes)`));
|
|
151
|
-
}
|
|
152
|
-
const file = new File([arrayBuffer], filename, {
|
|
153
|
-
type: contentType,
|
|
154
|
-
});
|
|
155
|
-
if (typeof options?.maxFiles != "undefined" &&
|
|
156
|
-
options.maxFiles == 0) {
|
|
157
|
-
reject(new Error(`Field "${fieldName}" exceeds the maximum allowed file count of ${options.maxFiles}.`));
|
|
158
|
-
}
|
|
159
|
-
if (formDataField[fieldName]) {
|
|
160
|
-
if (Array.isArray(formDataField[fieldName])) {
|
|
161
|
-
const existingFiles = formDataField[fieldName].filter((f) => f instanceof File);
|
|
162
|
-
if (typeof options?.maxFiles != "undefined" &&
|
|
163
|
-
existingFiles.length >= options.maxFiles) {
|
|
164
|
-
reject(new Error(`Field "${fieldName}" exceeds the maximum allowed file count of ${options.maxFiles}.`));
|
|
165
|
-
}
|
|
166
|
-
formDataField[fieldName].push(file);
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
if (formDataField[fieldName] instanceof File &&
|
|
170
|
-
typeof options?.maxFiles != "undefined" &&
|
|
171
|
-
options.maxFiles == 1) {
|
|
172
|
-
reject(new Error(`Field "${fieldName}" exceeds the maximum allowed file count of ${options.maxFiles}.`));
|
|
173
|
-
}
|
|
174
|
-
formDataField[fieldName] = [formDataField[fieldName], file];
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
else {
|
|
178
|
-
formDataField[fieldName] = file;
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
resolve(formDataField);
|
|
184
|
-
}
|
|
185
|
-
catch { }
|
|
186
|
-
});
|
|
187
|
-
});
|
|
188
|
-
}
|
|
189
|
-
else if (runtime === "deno" || runtime === "bun") {
|
|
190
|
-
const formData = await req.formData();
|
|
191
|
-
const result = {};
|
|
192
|
-
for (const [key, value] of formData.entries()) {
|
|
193
|
-
let val = value;
|
|
194
|
-
if (val instanceof File && typeof options == "object") {
|
|
195
|
-
let filename = val.name;
|
|
196
|
-
if (options?.sanitized) {
|
|
197
|
-
filename = `${Date.now()}-${sanitized(filename)}`;
|
|
198
|
-
}
|
|
199
|
-
if (Array.isArray(options?.allowedTypes) &&
|
|
200
|
-
!options.allowedTypes?.includes(val.type)) {
|
|
201
|
-
throw new Error(`Invalid file type: "${val.type}". Allowed types: ${options.allowedTypes.join(", ")}`);
|
|
202
|
-
}
|
|
203
|
-
if (typeof options?.maxSize !== "undefined" &&
|
|
204
|
-
val.size > options.maxSize) {
|
|
205
|
-
throw new Error(`File size exceeds the limit: ${val.size} bytes (Max: ${options.maxSize} bytes)`);
|
|
206
|
-
}
|
|
207
|
-
if (typeof options?.maxFiles != "undefined" && options.maxFiles == 0) {
|
|
208
|
-
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
209
|
-
}
|
|
210
|
-
val = new File([await val.arrayBuffer()], filename, {
|
|
211
|
-
type: val.type,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
if (result[key]) {
|
|
215
|
-
if (Array.isArray(result[key])) {
|
|
216
|
-
if (val instanceof File &&
|
|
217
|
-
typeof options?.maxFiles != "undefined" &&
|
|
218
|
-
result[key]?.length >= options.maxFiles) {
|
|
219
|
-
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
220
|
-
}
|
|
221
|
-
result[key].push(val);
|
|
222
|
-
}
|
|
223
|
-
else {
|
|
224
|
-
if (val instanceof File &&
|
|
225
|
-
typeof options?.maxFiles != "undefined" &&
|
|
226
|
-
options.maxFiles == 1) {
|
|
227
|
-
throw new Error(`Field "${key}" exceeds the maximum allowed file count of ${options.maxFiles}.`);
|
|
228
|
-
}
|
|
229
|
-
result[key] = [result[key], val];
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
result[key] = val;
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
return result;
|
|
237
|
-
}
|
|
238
|
-
else {
|
|
239
|
-
throw new Error("Unsupported environment for multipart parsing");
|
|
240
|
-
}
|
|
241
|
-
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const httpStatusMap: Record<number, string>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const httpStatusMap = {
|
|
2
|
+
100: "Continue",
|
|
3
|
+
101: "Switching Protocols",
|
|
4
|
+
102: "Processing",
|
|
5
|
+
103: "Early Hints",
|
|
6
|
+
200: "OK",
|
|
7
|
+
201: "Created",
|
|
8
|
+
202: "Accepted",
|
|
9
|
+
203: "Non-Authoritative Information",
|
|
10
|
+
204: "No Content",
|
|
11
|
+
205: "Reset Content",
|
|
12
|
+
206: "Partial Content",
|
|
13
|
+
207: "Multi-Status",
|
|
14
|
+
208: "Already Reported",
|
|
15
|
+
226: "IM Used",
|
|
16
|
+
300: "Multiple Choices",
|
|
17
|
+
301: "Moved Permanently",
|
|
18
|
+
302: "Found",
|
|
19
|
+
303: "See Other",
|
|
20
|
+
304: "Not Modified",
|
|
21
|
+
305: "Use Proxy",
|
|
22
|
+
306: "Switch Proxy",
|
|
23
|
+
307: "Temporary Redirect",
|
|
24
|
+
308: "Permanent Redirect",
|
|
25
|
+
400: "Bad Request",
|
|
26
|
+
401: "Unauthorized",
|
|
27
|
+
402: "Payment Required",
|
|
28
|
+
403: "Forbidden",
|
|
29
|
+
404: "Not Found",
|
|
30
|
+
405: "Method Not Allowed",
|
|
31
|
+
406: "Not Acceptable",
|
|
32
|
+
407: "Proxy Authentication Required",
|
|
33
|
+
408: "Request Timeout",
|
|
34
|
+
409: "Conflict",
|
|
35
|
+
410: "Gone",
|
|
36
|
+
411: "Length Required",
|
|
37
|
+
412: "Precondition Failed",
|
|
38
|
+
413: "Payload Too Large",
|
|
39
|
+
414: "URI Too Long",
|
|
40
|
+
415: "Unsupported Media Type",
|
|
41
|
+
416: "Range Not Satisfiable",
|
|
42
|
+
417: "Expectation Failed",
|
|
43
|
+
418: "I'm a Teapot",
|
|
44
|
+
421: "Misdirected Request",
|
|
45
|
+
422: "Unprocessable Entity",
|
|
46
|
+
423: "Locked",
|
|
47
|
+
424: "Failed Dependency",
|
|
48
|
+
425: "Too Early",
|
|
49
|
+
426: "Upgrade Required",
|
|
50
|
+
428: "Precondition Required",
|
|
51
|
+
429: "Too Many Requests",
|
|
52
|
+
431: "Request Header Fields Too Large",
|
|
53
|
+
451: "Unavailable For Legal Reasons",
|
|
54
|
+
500: "Internal Server Error",
|
|
55
|
+
501: "Not Implemented",
|
|
56
|
+
502: "Bad Gateway",
|
|
57
|
+
503: "Service Unavailable",
|
|
58
|
+
504: "Gateway Timeout",
|
|
59
|
+
505: "HTTP Version Not Supported",
|
|
60
|
+
506: "Variant Also Negotiates",
|
|
61
|
+
507: "Insufficient Storage",
|
|
62
|
+
508: "Loop Detected",
|
|
63
|
+
510: "Not Extended",
|
|
64
|
+
511: "Network Authentication Required",
|
|
65
|
+
};
|
package/utils/staticFile.js
CHANGED
|
@@ -145,7 +145,10 @@ export async function getFiles(dir, basePath = "/", ref, option) {
|
|
|
145
145
|
ctx.headers.set("Cache-Control", option.cacheControl);
|
|
146
146
|
}
|
|
147
147
|
if (option.headers) {
|
|
148
|
-
|
|
148
|
+
for (const key in option.headers) {
|
|
149
|
+
let value = option.headers?.[key];
|
|
150
|
+
ctx.headers.set(key, value);
|
|
151
|
+
}
|
|
149
152
|
}
|
|
150
153
|
return ctx.sendFile(r.file);
|
|
151
154
|
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IncomingMessage } from "node:http";
|
|
2
|
+
/**
|
|
3
|
+
* Convert Node.js IncomingMessage to a standard Web Fetch API Request with full support:
|
|
4
|
+
* - Absolute URL resolution
|
|
5
|
+
* - Streaming body (duplex)
|
|
6
|
+
* - AbortSignal linked to client disconnect
|
|
7
|
+
*
|
|
8
|
+
* @param {IncomingMessage} req Node.js HTTP request object
|
|
9
|
+
* @returns {Request} Web Fetch API Request instance
|
|
10
|
+
*/
|
|
11
|
+
export declare function toWebRequest(req: IncomingMessage, method?: string): Request;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
export function toWebRequest(req, method = "GET") {
|
|
3
|
+
const headers = {};
|
|
4
|
+
for (const [key, value] of Object.entries(req.headers)) {
|
|
5
|
+
if (Array.isArray(value)) {
|
|
6
|
+
headers[key] = value.join(", ");
|
|
7
|
+
}
|
|
8
|
+
else if (typeof value === "string") {
|
|
9
|
+
headers[key] = value;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const isEncrypted = (req.socket && req.socket.encrypted) || false;
|
|
13
|
+
const protocol = isEncrypted ? "https:" : "http:";
|
|
14
|
+
let host = "localhost";
|
|
15
|
+
const hostHeader = req.headers.host;
|
|
16
|
+
if (typeof hostHeader === "string") {
|
|
17
|
+
host = hostHeader;
|
|
18
|
+
}
|
|
19
|
+
const urlStr = req.url ?? "/";
|
|
20
|
+
const fullUrl = new URL(urlStr, `${protocol}//${host}`);
|
|
21
|
+
const hasBody = !["GET", "HEAD"].includes(method.toUpperCase());
|
|
22
|
+
const body = hasBody ? Readable.toWeb(req) : undefined;
|
|
23
|
+
const abortController = new AbortController();
|
|
24
|
+
req?.once("close", () => abortController.abort());
|
|
25
|
+
return new Request(fullUrl.href, {
|
|
26
|
+
method,
|
|
27
|
+
headers,
|
|
28
|
+
body,
|
|
29
|
+
signal: abortController.signal,
|
|
30
|
+
duplex: hasBody ? "half" : undefined,
|
|
31
|
+
});
|
|
32
|
+
}
|
package/adapter/node.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
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
|
-
export declare function nodeAdapter<T extends Record<string, any> = {}>(TezX: TezX<T>, options?: TezXServerOptions): {
|
|
13
|
-
listen: {
|
|
14
|
-
(callback?: () => void): any;
|
|
15
|
-
(port?: number): any;
|
|
16
|
-
(port?: number, callback?: () => void): any;
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
export {};
|
package/cjs/core/header.js
DELETED
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.HeadersParser = void 0;
|
|
4
|
-
class HeadersParser {
|
|
5
|
-
headers = new Map();
|
|
6
|
-
constructor(init) {
|
|
7
|
-
if (init) {
|
|
8
|
-
this.add(init);
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
add(headers) {
|
|
12
|
-
if (Array.isArray(headers)) {
|
|
13
|
-
for (const [key, value] of headers) {
|
|
14
|
-
this.set(key, value);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
else if (typeof Headers !== "undefined" && headers instanceof Headers) {
|
|
18
|
-
for (const [key, value] of headers.entries()) {
|
|
19
|
-
this.set(key, value);
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
else if (typeof headers === "object") {
|
|
23
|
-
for (const key in headers) {
|
|
24
|
-
if (Object.prototype.hasOwnProperty.call(headers, key)) {
|
|
25
|
-
this.set(key, headers[key]);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
return this;
|
|
30
|
-
}
|
|
31
|
-
set(key, value) {
|
|
32
|
-
this.headers.set(key.toLowerCase(), Array.isArray(value) ? value : [value]);
|
|
33
|
-
return this;
|
|
34
|
-
}
|
|
35
|
-
clear() {
|
|
36
|
-
this.headers.clear();
|
|
37
|
-
return this;
|
|
38
|
-
}
|
|
39
|
-
get(key) {
|
|
40
|
-
const values = this.headers.get(key.toLowerCase());
|
|
41
|
-
return values ? values[0] : undefined;
|
|
42
|
-
}
|
|
43
|
-
getAll(key) {
|
|
44
|
-
return this.headers.get(key.toLowerCase()) || [];
|
|
45
|
-
}
|
|
46
|
-
has(key) {
|
|
47
|
-
return this.headers.has(key.toLowerCase());
|
|
48
|
-
}
|
|
49
|
-
delete(key) {
|
|
50
|
-
return this.headers.delete(key.toLowerCase());
|
|
51
|
-
}
|
|
52
|
-
append(key, value) {
|
|
53
|
-
const lowerKey = key.toLowerCase();
|
|
54
|
-
if (this.headers.has(lowerKey)) {
|
|
55
|
-
this.headers.get(lowerKey).push(value);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
this.headers.set(lowerKey, [value]);
|
|
59
|
-
}
|
|
60
|
-
return this;
|
|
61
|
-
}
|
|
62
|
-
entries() {
|
|
63
|
-
return this.headers.entries();
|
|
64
|
-
}
|
|
65
|
-
keys() {
|
|
66
|
-
return this.headers.keys();
|
|
67
|
-
}
|
|
68
|
-
values() {
|
|
69
|
-
return this.headers.values();
|
|
70
|
-
}
|
|
71
|
-
forEach(callback) {
|
|
72
|
-
for (const [key, value] of this.headers) {
|
|
73
|
-
callback(value, key);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
toObject() {
|
|
77
|
-
const obj = {};
|
|
78
|
-
for (const [key, value] of this.headers.entries()) {
|
|
79
|
-
obj[key] = value.length > 1 ? value : value[0];
|
|
80
|
-
}
|
|
81
|
-
return obj;
|
|
82
|
-
}
|
|
83
|
-
toJSON() {
|
|
84
|
-
const obj = {};
|
|
85
|
-
for (const [key, value] of this.headers.entries()) {
|
|
86
|
-
obj[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
87
|
-
}
|
|
88
|
-
return obj;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
exports.HeadersParser = HeadersParser;
|
|
92
|
-
Object.defineProperty(HeadersParser, "name", { value: "Headers" });
|
package/core/header.d.ts
DELETED
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
export declare class HeadersParser {
|
|
2
|
-
private headers;
|
|
3
|
-
constructor(init?: [string, string | string[]][] | Record<string, string>);
|
|
4
|
-
/**
|
|
5
|
-
* Adds multiple headers to the parser.
|
|
6
|
-
* @param headers - Headers as an array of tuples or a record object.
|
|
7
|
-
*/
|
|
8
|
-
add(headers: [string, string | string[]][] | Record<string, string>): this;
|
|
9
|
-
/**
|
|
10
|
-
* Sets a header value.
|
|
11
|
-
* @param key - Header name.
|
|
12
|
-
* @param value - Header value(s).
|
|
13
|
-
*/
|
|
14
|
-
set(key: string, value: string | string[]): this;
|
|
15
|
-
clear(): this;
|
|
16
|
-
/**
|
|
17
|
-
* Retrieves the first value of a header.
|
|
18
|
-
* @param key - Header name.
|
|
19
|
-
* @returns The first header value or undefined if not found.
|
|
20
|
-
*/
|
|
21
|
-
get(key: string): string | undefined;
|
|
22
|
-
/**
|
|
23
|
-
* Retrieves all values of a header.
|
|
24
|
-
* @param key - Header name.
|
|
25
|
-
* @returns An array of header values.
|
|
26
|
-
*/
|
|
27
|
-
getAll(key: string): string[];
|
|
28
|
-
/**
|
|
29
|
-
* Checks if a header exists.
|
|
30
|
-
* @param key - Header name.
|
|
31
|
-
* @returns True if the header exists, false otherwise.
|
|
32
|
-
*/
|
|
33
|
-
has(key: string): boolean;
|
|
34
|
-
/**
|
|
35
|
-
* Deletes a header.
|
|
36
|
-
* @param key - Header name.
|
|
37
|
-
* @returns True if deleted successfully, false otherwise.
|
|
38
|
-
*/
|
|
39
|
-
delete(key: string): boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Appends a value to an existing header or creates a new one.
|
|
42
|
-
* @param key - Header name.
|
|
43
|
-
* @param value - Value to append.
|
|
44
|
-
*/
|
|
45
|
-
append(key: string, value: string): this;
|
|
46
|
-
/**
|
|
47
|
-
* Returns an iterator over header entries.
|
|
48
|
-
* @returns IterableIterator of header key-value pairs.
|
|
49
|
-
*/
|
|
50
|
-
entries(): IterableIterator<[string, string[]]>;
|
|
51
|
-
/**
|
|
52
|
-
* Returns an iterator over header keys.
|
|
53
|
-
* @returns IterableIterator of header names.
|
|
54
|
-
*/
|
|
55
|
-
keys(): IterableIterator<string>;
|
|
56
|
-
/**
|
|
57
|
-
* Returns an iterator over header values.
|
|
58
|
-
* @returns IterableIterator of header values arrays.
|
|
59
|
-
*/
|
|
60
|
-
values(): IterableIterator<string[]>;
|
|
61
|
-
/**
|
|
62
|
-
* Iterates over headers and executes a callback function.
|
|
63
|
-
* @param callback - Function to execute for each header.
|
|
64
|
-
*/
|
|
65
|
-
forEach(callback: (value: string[], key: string) => void): void;
|
|
66
|
-
/**
|
|
67
|
-
* Converts headers into a plain object.
|
|
68
|
-
* @returns A record of headers where single-value headers are returned as a string.
|
|
69
|
-
*/
|
|
70
|
-
toObject(): Record<string, string | string[]>;
|
|
71
|
-
/**
|
|
72
|
-
* Converts headers to a JSON-safe plain object (only single string values).
|
|
73
|
-
* Multi-value headers are joined by commas.
|
|
74
|
-
* @returns A record of headers with string values.
|
|
75
|
-
*/
|
|
76
|
-
toJSON(): Record<string, string>;
|
|
77
|
-
}
|
package/core/header.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
export class HeadersParser {
|
|
2
|
-
headers = new Map();
|
|
3
|
-
constructor(init) {
|
|
4
|
-
if (init) {
|
|
5
|
-
this.add(init);
|
|
6
|
-
}
|
|
7
|
-
}
|
|
8
|
-
add(headers) {
|
|
9
|
-
if (Array.isArray(headers)) {
|
|
10
|
-
for (const [key, value] of headers) {
|
|
11
|
-
this.set(key, value);
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
else if (typeof Headers !== "undefined" && headers instanceof Headers) {
|
|
15
|
-
for (const [key, value] of headers.entries()) {
|
|
16
|
-
this.set(key, value);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
else if (typeof headers === "object") {
|
|
20
|
-
for (const key in headers) {
|
|
21
|
-
if (Object.prototype.hasOwnProperty.call(headers, key)) {
|
|
22
|
-
this.set(key, headers[key]);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
set(key, value) {
|
|
29
|
-
this.headers.set(key.toLowerCase(), Array.isArray(value) ? value : [value]);
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
clear() {
|
|
33
|
-
this.headers.clear();
|
|
34
|
-
return this;
|
|
35
|
-
}
|
|
36
|
-
get(key) {
|
|
37
|
-
const values = this.headers.get(key.toLowerCase());
|
|
38
|
-
return values ? values[0] : undefined;
|
|
39
|
-
}
|
|
40
|
-
getAll(key) {
|
|
41
|
-
return this.headers.get(key.toLowerCase()) || [];
|
|
42
|
-
}
|
|
43
|
-
has(key) {
|
|
44
|
-
return this.headers.has(key.toLowerCase());
|
|
45
|
-
}
|
|
46
|
-
delete(key) {
|
|
47
|
-
return this.headers.delete(key.toLowerCase());
|
|
48
|
-
}
|
|
49
|
-
append(key, value) {
|
|
50
|
-
const lowerKey = key.toLowerCase();
|
|
51
|
-
if (this.headers.has(lowerKey)) {
|
|
52
|
-
this.headers.get(lowerKey).push(value);
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
this.headers.set(lowerKey, [value]);
|
|
56
|
-
}
|
|
57
|
-
return this;
|
|
58
|
-
}
|
|
59
|
-
entries() {
|
|
60
|
-
return this.headers.entries();
|
|
61
|
-
}
|
|
62
|
-
keys() {
|
|
63
|
-
return this.headers.keys();
|
|
64
|
-
}
|
|
65
|
-
values() {
|
|
66
|
-
return this.headers.values();
|
|
67
|
-
}
|
|
68
|
-
forEach(callback) {
|
|
69
|
-
for (const [key, value] of this.headers) {
|
|
70
|
-
callback(value, key);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
toObject() {
|
|
74
|
-
const obj = {};
|
|
75
|
-
for (const [key, value] of this.headers.entries()) {
|
|
76
|
-
obj[key] = value.length > 1 ? value : value[0];
|
|
77
|
-
}
|
|
78
|
-
return obj;
|
|
79
|
-
}
|
|
80
|
-
toJSON() {
|
|
81
|
-
const obj = {};
|
|
82
|
-
for (const [key, value] of this.headers.entries()) {
|
|
83
|
-
obj[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
84
|
-
}
|
|
85
|
-
return obj;
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
Object.defineProperty(HeadersParser, "name", { value: "Headers" });
|