tspace-spear 1.2.3 → 1.2.5
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 +268 -19
- package/dist/lib/core/const/index.d.ts +153 -0
- package/dist/lib/core/const/index.js +105 -0
- package/dist/lib/core/const/index.js.map +1 -0
- package/dist/lib/core/decorators/context.d.ts +16 -9
- package/dist/lib/core/decorators/context.js +85 -59
- package/dist/lib/core/decorators/context.js.map +1 -1
- package/dist/lib/core/decorators/headers.d.ts +2 -2
- package/dist/lib/core/decorators/headers.js +1 -1
- package/dist/lib/core/decorators/headers.js.map +1 -1
- package/dist/lib/core/decorators/methods.d.ts +7 -7
- package/dist/lib/core/decorators/methods.js.map +1 -1
- package/dist/lib/core/decorators/middleware.d.ts +3 -3
- package/dist/lib/core/decorators/middleware.js +2 -2
- package/dist/lib/core/decorators/middleware.js.map +1 -1
- package/dist/lib/core/decorators/statusCode.d.ts +1 -1
- package/dist/lib/core/decorators/statusCode.js.map +1 -1
- package/dist/lib/core/decorators/swagger.d.ts +1 -1
- package/dist/lib/core/decorators/swagger.js.map +1 -1
- package/dist/lib/core/server/fast-router.d.ts +133 -0
- package/dist/lib/core/server/fast-router.js +277 -0
- package/dist/lib/core/server/fast-router.js.map +1 -0
- package/dist/lib/core/server/index.d.ts +34 -37
- package/dist/lib/core/server/index.js +192 -501
- package/dist/lib/core/server/index.js.map +1 -1
- package/dist/lib/core/server/net/index.d.ts +20 -0
- package/dist/lib/core/server/net/index.js +393 -0
- package/dist/lib/core/server/net/index.js.map +1 -0
- package/dist/lib/core/server/parser-factory.d.ts +10 -11
- package/dist/lib/core/server/parser-factory.js +259 -437
- package/dist/lib/core/server/parser-factory.js.map +1 -1
- package/dist/lib/core/server/response.d.ts +6 -0
- package/dist/lib/core/server/response.js +168 -0
- package/dist/lib/core/server/response.js.map +1 -0
- package/dist/lib/core/server/router.d.ts +2 -12
- package/dist/lib/core/server/router.js +2 -13
- package/dist/lib/core/server/router.js.map +1 -1
- package/dist/lib/core/server/uWS/index.d.ts +30 -0
- package/dist/lib/core/server/uWS/index.js +357 -0
- package/dist/lib/core/server/uWS/index.js.map +1 -0
- package/dist/lib/core/types/index.d.ts +144 -43
- package/dist/lib/core/utils/index.d.ts +12 -0
- package/dist/lib/core/utils/index.js +137 -0
- package/dist/lib/core/utils/index.js.map +1 -0
- package/dist/lib/index.d.ts +3 -3
- package/dist/lib/index.js +3 -2
- package/dist/lib/index.js.map +1 -1
- package/package.json +19 -14
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.uWSPipeStream = exports.uWSfiles = exports.uWSBody = exports.uWSAdaptRequestResponse = void 0;
|
|
7
|
+
const fs_1 = __importDefault(require("fs"));
|
|
8
|
+
const path_1 = __importDefault(require("path"));
|
|
9
|
+
const mime_types_1 = __importDefault(require("mime-types"));
|
|
10
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
11
|
+
const const_1 = require("../../const");
|
|
12
|
+
const utils_1 = require("../../utils");
|
|
13
|
+
const uWSAdaptRequestResponse = (uwsReq, uwsRes) => {
|
|
14
|
+
const headers = {};
|
|
15
|
+
uwsReq.forEach((key, value) => {
|
|
16
|
+
headers[key.toLowerCase()] = value;
|
|
17
|
+
});
|
|
18
|
+
const req = {
|
|
19
|
+
uWS: uwsReq,
|
|
20
|
+
method: String(uwsReq.getMethod()).toUpperCase(),
|
|
21
|
+
url: uwsReq.getUrl() + (uwsReq.getQuery() ? `?${uwsReq.getQuery()}` : ""),
|
|
22
|
+
headers: headers,
|
|
23
|
+
};
|
|
24
|
+
const _writeHead = (status, context) => {
|
|
25
|
+
const statusMessage = const_1.HTTP_STATUS_MESSAGES[status] ||
|
|
26
|
+
const_1.HTTP_STATUS_MESSAGES[500];
|
|
27
|
+
res.uWS.writeStatus(`${status} ${statusMessage}`);
|
|
28
|
+
res.uWS.writeHeader(Object.keys(context)[0], Object.values(context)[0]);
|
|
29
|
+
return res;
|
|
30
|
+
};
|
|
31
|
+
const res = {
|
|
32
|
+
writeHeader: (key, value) => {
|
|
33
|
+
if (!res.aborted) {
|
|
34
|
+
uwsRes.writeHeader(key, value);
|
|
35
|
+
}
|
|
36
|
+
return res;
|
|
37
|
+
},
|
|
38
|
+
setHeader: (key, value) => {
|
|
39
|
+
if (!res.aborted) {
|
|
40
|
+
uwsRes.writeHeader(key, value);
|
|
41
|
+
}
|
|
42
|
+
return res;
|
|
43
|
+
},
|
|
44
|
+
writeHead(status, context) {
|
|
45
|
+
res.writeHeaders = {
|
|
46
|
+
...res.writeHeaders,
|
|
47
|
+
[status]: context,
|
|
48
|
+
};
|
|
49
|
+
res.headersSent = true;
|
|
50
|
+
res.statusCode = status;
|
|
51
|
+
return res;
|
|
52
|
+
},
|
|
53
|
+
writeStatus: (status) => {
|
|
54
|
+
if (!res.aborted) {
|
|
55
|
+
res.uWS.writeStatus(status);
|
|
56
|
+
}
|
|
57
|
+
return res;
|
|
58
|
+
},
|
|
59
|
+
end: (str) => {
|
|
60
|
+
if (res.aborted) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
if (str === undefined) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
uwsRes.cork(() => {
|
|
67
|
+
if (!res.aborted) {
|
|
68
|
+
res.aborted = true;
|
|
69
|
+
res.writableEnded = true;
|
|
70
|
+
for (const h in res.writeHeaders) {
|
|
71
|
+
_writeHead(+h, res.writeHeaders[h]);
|
|
72
|
+
}
|
|
73
|
+
uwsRes.end(str);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
},
|
|
78
|
+
writableEnded: false,
|
|
79
|
+
aborted: false,
|
|
80
|
+
writeHeaders: Object.create(null),
|
|
81
|
+
headersSent: false,
|
|
82
|
+
statusCode: 200,
|
|
83
|
+
uWS: uwsRes,
|
|
84
|
+
};
|
|
85
|
+
uwsRes.onAborted(() => {
|
|
86
|
+
res.aborted = true;
|
|
87
|
+
});
|
|
88
|
+
return { req, res };
|
|
89
|
+
};
|
|
90
|
+
exports.uWSAdaptRequestResponse = uWSAdaptRequestResponse;
|
|
91
|
+
const uWSBody = (req, res) => {
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
let buffer = [];
|
|
94
|
+
res.uWS.onAborted(() => {
|
|
95
|
+
reject(new Error("Request aborted"));
|
|
96
|
+
});
|
|
97
|
+
res.uWS.onData(async (chunk, isLast) => {
|
|
98
|
+
buffer.push(Buffer.from(chunk));
|
|
99
|
+
if (!isLast)
|
|
100
|
+
return;
|
|
101
|
+
const payload = Buffer.concat(buffer).toString("utf-8");
|
|
102
|
+
const contentType = req.headers["content-type"]?.toLowerCase() ?? null;
|
|
103
|
+
try {
|
|
104
|
+
const body = await (0, utils_1.normalizeRequestBody)({ contentType, payload });
|
|
105
|
+
return resolve(body);
|
|
106
|
+
}
|
|
107
|
+
catch (err) {
|
|
108
|
+
return reject(err);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
};
|
|
113
|
+
exports.uWSBody = uWSBody;
|
|
114
|
+
const uWSfiles = async ({ req, res, options, }) => {
|
|
115
|
+
const temp = options.tempFileDir;
|
|
116
|
+
if (!fs_1.default.existsSync(temp)) {
|
|
117
|
+
try {
|
|
118
|
+
fs_1.default.mkdirSync(temp, { recursive: true });
|
|
119
|
+
}
|
|
120
|
+
catch { }
|
|
121
|
+
}
|
|
122
|
+
const removeTemp = (fileTemp, ms) => {
|
|
123
|
+
const remove = () => {
|
|
124
|
+
try {
|
|
125
|
+
fs_1.default.unlinkSync(fileTemp);
|
|
126
|
+
}
|
|
127
|
+
catch (err) { }
|
|
128
|
+
};
|
|
129
|
+
setTimeout(remove, ms);
|
|
130
|
+
};
|
|
131
|
+
const contentType = req.headers["content-type"] ?? "";
|
|
132
|
+
const boundary = contentType.split("boundary=")[1];
|
|
133
|
+
if (!boundary) {
|
|
134
|
+
throw new Error("Invalid multipart/form-data (no boundary)");
|
|
135
|
+
}
|
|
136
|
+
const boundaryBuf = Buffer.from(`\r\n--${boundary}`);
|
|
137
|
+
return new Promise((resolve, reject) => {
|
|
138
|
+
let body = {};
|
|
139
|
+
let files = {};
|
|
140
|
+
let buffer = Buffer.alloc(0);
|
|
141
|
+
let currentFileStream = null;
|
|
142
|
+
let file = null;
|
|
143
|
+
let headerParsed = false;
|
|
144
|
+
let aborted = false;
|
|
145
|
+
const fail = (err) => {
|
|
146
|
+
if (aborted)
|
|
147
|
+
return;
|
|
148
|
+
aborted = true;
|
|
149
|
+
try {
|
|
150
|
+
currentFileStream?.destroy();
|
|
151
|
+
}
|
|
152
|
+
catch { }
|
|
153
|
+
try {
|
|
154
|
+
file?.tempFilePath && fs_1.default.unlinkSync(file.tempFilePath);
|
|
155
|
+
}
|
|
156
|
+
catch { }
|
|
157
|
+
try {
|
|
158
|
+
res.uWS.close();
|
|
159
|
+
}
|
|
160
|
+
catch { }
|
|
161
|
+
return reject(err);
|
|
162
|
+
};
|
|
163
|
+
res.uWS.onData((chunk, isLast) => {
|
|
164
|
+
if (aborted)
|
|
165
|
+
return;
|
|
166
|
+
const data = Buffer.from(new Uint8Array(chunk));
|
|
167
|
+
buffer = buffer.length === 0 ? data : Buffer.concat([buffer, data]);
|
|
168
|
+
try {
|
|
169
|
+
while (true) {
|
|
170
|
+
if (!headerParsed) {
|
|
171
|
+
const headerEnd = buffer.indexOf("\r\n\r\n");
|
|
172
|
+
if (headerEnd === -1)
|
|
173
|
+
break;
|
|
174
|
+
const header = buffer.slice(0, headerEnd).toString();
|
|
175
|
+
buffer = buffer.slice(headerEnd + 4);
|
|
176
|
+
const disposition = header.match(/name="([^"]+)"(?:; filename="([^"]+)")?/);
|
|
177
|
+
if (!disposition)
|
|
178
|
+
continue;
|
|
179
|
+
const fieldName = disposition[1];
|
|
180
|
+
const fileName = disposition[2];
|
|
181
|
+
if (!fileName) {
|
|
182
|
+
const nextBoundary = buffer.indexOf(boundaryBuf);
|
|
183
|
+
if (nextBoundary === -1)
|
|
184
|
+
break;
|
|
185
|
+
const value = buffer.slice(0, nextBoundary).toString().trim();
|
|
186
|
+
body[fieldName] = value;
|
|
187
|
+
buffer = buffer.slice(nextBoundary + boundaryBuf.length);
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
const contentTypeMatch = header.match(/Content-Type: ([^\r\n]+)/);
|
|
191
|
+
const mimetype = contentTypeMatch
|
|
192
|
+
? contentTypeMatch[1]
|
|
193
|
+
: "application/octet-stream";
|
|
194
|
+
const extension = mime_types_1.default.extension(mimetype) ||
|
|
195
|
+
path_1.default.extname(fileName).replace(".", "") ||
|
|
196
|
+
"bin";
|
|
197
|
+
const tempFilename = crypto_1.default.randomBytes(16).toString("hex");
|
|
198
|
+
const filePath = path_1.default.join(path_1.default.resolve(), `${temp}/${tempFilename}`);
|
|
199
|
+
currentFileStream = fs_1.default.createWriteStream(filePath);
|
|
200
|
+
file = {
|
|
201
|
+
name: fileName,
|
|
202
|
+
tempFilePath: filePath,
|
|
203
|
+
tempFileName: tempFilename,
|
|
204
|
+
mimetype: mimetype,
|
|
205
|
+
extension: extension,
|
|
206
|
+
size: 0,
|
|
207
|
+
sizes: {
|
|
208
|
+
bytes: 0,
|
|
209
|
+
kb: 0,
|
|
210
|
+
mb: 0,
|
|
211
|
+
gb: 0,
|
|
212
|
+
},
|
|
213
|
+
write: (to) => {
|
|
214
|
+
return new Promise((resolve, reject) => {
|
|
215
|
+
fs_1.default
|
|
216
|
+
.createReadStream(filePath)
|
|
217
|
+
.pipe(fs_1.default.createWriteStream(to))
|
|
218
|
+
.on("finish", () => {
|
|
219
|
+
return resolve(null);
|
|
220
|
+
})
|
|
221
|
+
.on("error", (err) => {
|
|
222
|
+
return reject(err);
|
|
223
|
+
});
|
|
224
|
+
});
|
|
225
|
+
},
|
|
226
|
+
remove: () => {
|
|
227
|
+
return new Promise((resolve) => setTimeout(() => {
|
|
228
|
+
fs_1.default.unlinkSync(filePath);
|
|
229
|
+
return resolve(null);
|
|
230
|
+
}, 100));
|
|
231
|
+
},
|
|
232
|
+
};
|
|
233
|
+
if (!files[fieldName])
|
|
234
|
+
files[fieldName] = [];
|
|
235
|
+
files[fieldName].push(file);
|
|
236
|
+
if (options.removeTempFile.remove) {
|
|
237
|
+
removeTemp(filePath, options.removeTempFile.ms);
|
|
238
|
+
}
|
|
239
|
+
headerParsed = true;
|
|
240
|
+
}
|
|
241
|
+
const boundaryIndex = buffer.indexOf(boundaryBuf);
|
|
242
|
+
if (boundaryIndex === -1) {
|
|
243
|
+
const safeLength = buffer.length - boundaryBuf.length;
|
|
244
|
+
if (safeLength > 0) {
|
|
245
|
+
const writeChunk = buffer.slice(0, safeLength);
|
|
246
|
+
currentFileStream.write(writeChunk);
|
|
247
|
+
file.size += writeChunk.length;
|
|
248
|
+
file.sizes = {
|
|
249
|
+
bytes: file.size,
|
|
250
|
+
kb: file.size / 1024,
|
|
251
|
+
mb: file.size / 1024 / 1024,
|
|
252
|
+
gb: file.size / 1024 / 1024 / 1024,
|
|
253
|
+
};
|
|
254
|
+
if (file.size > options.limit) {
|
|
255
|
+
return fail(new Error(`File too large (limit ${options.limit} bytes)`));
|
|
256
|
+
}
|
|
257
|
+
buffer = buffer.slice(safeLength);
|
|
258
|
+
}
|
|
259
|
+
break;
|
|
260
|
+
}
|
|
261
|
+
const filePart = buffer.slice(0, boundaryIndex);
|
|
262
|
+
currentFileStream.write(filePart);
|
|
263
|
+
file.size += filePart.length;
|
|
264
|
+
file.sizes = {
|
|
265
|
+
bytes: file.size,
|
|
266
|
+
kb: file.size / 1024,
|
|
267
|
+
mb: file.size / 1024 / 1024,
|
|
268
|
+
gb: file.size / 1024 / 1024 / 1024,
|
|
269
|
+
};
|
|
270
|
+
if (file.size > options.limit) {
|
|
271
|
+
return fail(new Error(`File too large (limit ${options.limit} bytes)`));
|
|
272
|
+
}
|
|
273
|
+
currentFileStream.end();
|
|
274
|
+
currentFileStream = null;
|
|
275
|
+
file = null;
|
|
276
|
+
buffer = buffer.slice(boundaryIndex + boundaryBuf.length);
|
|
277
|
+
headerParsed = false;
|
|
278
|
+
}
|
|
279
|
+
if (isLast && !aborted) {
|
|
280
|
+
if (currentFileStream)
|
|
281
|
+
currentFileStream.end();
|
|
282
|
+
return resolve({ body, files });
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
catch (err) {
|
|
286
|
+
return fail(err);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
});
|
|
290
|
+
};
|
|
291
|
+
exports.uWSfiles = uWSfiles;
|
|
292
|
+
const uWSPipeStream = async ({ req, res, filePath }) => {
|
|
293
|
+
//@ts-ignore
|
|
294
|
+
const uwsRes = res.uWS;
|
|
295
|
+
const stat = fs_1.default.statSync(filePath);
|
|
296
|
+
const fileSize = stat.size;
|
|
297
|
+
const range = req.headers["range"] ?? null;
|
|
298
|
+
const contentType = mime_types_1.default.lookup(filePath) || "application/octet-stream";
|
|
299
|
+
const isVideo = contentType.startsWith("video/");
|
|
300
|
+
//@ts-ignore
|
|
301
|
+
let aborted = res.aborted || false;
|
|
302
|
+
let stream;
|
|
303
|
+
let start = 0;
|
|
304
|
+
let end = fileSize - 1;
|
|
305
|
+
uwsRes.onAborted(() => {
|
|
306
|
+
aborted = true;
|
|
307
|
+
if (stream)
|
|
308
|
+
stream.destroy();
|
|
309
|
+
});
|
|
310
|
+
if (range && isVideo) {
|
|
311
|
+
const parts = range.replace(/bytes=/, "").split("-");
|
|
312
|
+
start = parseInt(parts[0], 10);
|
|
313
|
+
end = parts[1] ? parseInt(parts[1], 10) : end;
|
|
314
|
+
uwsRes.writeStatus("206 Partial Content");
|
|
315
|
+
uwsRes.writeHeader("Content-Range", `bytes ${start}-${end}/${fileSize}`);
|
|
316
|
+
}
|
|
317
|
+
else {
|
|
318
|
+
uwsRes.writeStatus("200 OK");
|
|
319
|
+
}
|
|
320
|
+
const chunkSize = end - start + 1;
|
|
321
|
+
uwsRes.writeHeader("Content-Type", contentType);
|
|
322
|
+
uwsRes.writeHeader("Accept-Ranges", "bytes");
|
|
323
|
+
uwsRes.writeHeader("Content-Length", chunkSize.toString());
|
|
324
|
+
stream = fs_1.default.createReadStream(filePath, { start, end });
|
|
325
|
+
stream.pause();
|
|
326
|
+
stream.on("data", (chunk) => {
|
|
327
|
+
if (aborted)
|
|
328
|
+
return;
|
|
329
|
+
const ok = uwsRes.cork(() => uwsRes.write(chunk));
|
|
330
|
+
if (!ok)
|
|
331
|
+
stream.pause();
|
|
332
|
+
});
|
|
333
|
+
uwsRes.onWritable(() => {
|
|
334
|
+
if (aborted)
|
|
335
|
+
return false;
|
|
336
|
+
stream.resume();
|
|
337
|
+
return true;
|
|
338
|
+
});
|
|
339
|
+
stream.on("end", () => {
|
|
340
|
+
if (!aborted) {
|
|
341
|
+
uwsRes.cork(() => {
|
|
342
|
+
uwsRes.end();
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
});
|
|
346
|
+
stream.on("error", () => {
|
|
347
|
+
if (!aborted) {
|
|
348
|
+
uwsRes.cork(() => {
|
|
349
|
+
uwsRes.writeStatus("500 Internal Server Error").end();
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
stream.resume();
|
|
354
|
+
return stream;
|
|
355
|
+
};
|
|
356
|
+
exports.uWSPipeStream = uWSPipeStream;
|
|
357
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/lib/core/server/uWS/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import http, { IncomingHttpHeaders, IncomingMessage, ServerResponse } from "http";
|
|
2
2
|
import WebSocket from "ws";
|
|
3
|
+
import net from 'net';
|
|
3
4
|
type TContext = {
|
|
4
5
|
req: TRequest;
|
|
5
6
|
res: TResponse;
|
|
@@ -10,8 +11,10 @@ type TContext = {
|
|
|
10
11
|
files: TFileUpload;
|
|
11
12
|
cookies: TCookies;
|
|
12
13
|
ip: TIp;
|
|
14
|
+
ips: TIps;
|
|
13
15
|
};
|
|
14
16
|
type TIp = string | null;
|
|
17
|
+
type TIps = string[];
|
|
15
18
|
type THeaders<T = IncomingHttpHeaders> = {
|
|
16
19
|
[K in keyof T]: T[K];
|
|
17
20
|
};
|
|
@@ -37,37 +40,121 @@ type TFile = {
|
|
|
37
40
|
};
|
|
38
41
|
type TFileUpload = Record<string, TFile[] | undefined>;
|
|
39
42
|
type TNextFunction<T = any> = (err?: Error) => T | Promise<T>;
|
|
40
|
-
type TRequest = IncomingMessage &
|
|
43
|
+
type TRequest = IncomingMessage & {
|
|
44
|
+
uWs: any;
|
|
45
|
+
query: TQuery;
|
|
46
|
+
files: TFileUpload;
|
|
47
|
+
body: TBody;
|
|
48
|
+
params: TParams;
|
|
49
|
+
} & Partial<any>;
|
|
41
50
|
type THttpResponder = {
|
|
42
|
-
/**
|
|
51
|
+
/**
|
|
52
|
+
* Raw uWS HttpResponse instance.
|
|
53
|
+
*/
|
|
54
|
+
uWS: any;
|
|
55
|
+
/** 200 OK - Standard successful response */
|
|
43
56
|
ok: (data?: Record<string, any>) => any;
|
|
57
|
+
/** 201 Created - Resource successfully created */
|
|
44
58
|
created: (data?: Record<string, any>) => any;
|
|
59
|
+
/** 202 Accepted - Request accepted for processing */
|
|
45
60
|
accepted: (data?: Record<string, any>) => any;
|
|
46
|
-
/**
|
|
61
|
+
/** 204 No Content - Successful request with no response body */
|
|
47
62
|
noContent: (message?: string) => any;
|
|
63
|
+
/** 400 Bad Request - Invalid request from client */
|
|
48
64
|
badRequest: (message?: string) => any;
|
|
65
|
+
/** 401 Unauthorized - Authentication required or failed */
|
|
49
66
|
unauthorized: (message?: string) => any;
|
|
67
|
+
/** 402 Payment Required - Reserved for future/payment flow */
|
|
50
68
|
paymentRequired: (message?: string) => any;
|
|
69
|
+
/** 403 Forbidden - Client does not have access rights */
|
|
51
70
|
forbidden: (message?: string) => any;
|
|
71
|
+
/** 422 Unprocessable Entity - Valid request but semantic errors */
|
|
52
72
|
unprocessable: (message?: string) => any;
|
|
73
|
+
/** 429 Too Many Requests - Rate limit exceeded */
|
|
53
74
|
tooManyRequests: (message?: string) => any;
|
|
75
|
+
/** 404 Not Found - Resource does not exist */
|
|
54
76
|
notFound: (message?: string) => any;
|
|
55
|
-
/**500
|
|
77
|
+
/** 500 Internal Server Error - Generic server failure */
|
|
56
78
|
serverError: (message?: string) => any;
|
|
79
|
+
/** 502 Bad Gateway - Invalid response from upstream server */
|
|
57
80
|
badGateway: (message?: string) => any;
|
|
81
|
+
/** 503 Service Unavailable - Server temporarily unavailable */
|
|
58
82
|
unavailable: (message?: string) => any;
|
|
83
|
+
/** 504 Gateway Timeout - Upstream server timeout */
|
|
59
84
|
gatewayTimeout: (message?: string) => any;
|
|
60
|
-
/**
|
|
85
|
+
/**
|
|
86
|
+
* Serve a media file (video, image, PDF, etc.) from file system.
|
|
87
|
+
* @param filePath Absolute or relative path to media file
|
|
88
|
+
*/
|
|
89
|
+
serveMedia: (filePath: string) => any;
|
|
90
|
+
/**
|
|
91
|
+
* Send JSON response.
|
|
92
|
+
* @param data JSON serializable object
|
|
93
|
+
*/
|
|
61
94
|
json: (data?: Record<string, any>) => any;
|
|
95
|
+
/**
|
|
96
|
+
* Send error response (generic wrapper).
|
|
97
|
+
* @param err Error object or message
|
|
98
|
+
*/
|
|
62
99
|
error: (err: any) => any;
|
|
100
|
+
/**
|
|
101
|
+
* Send plain text response.
|
|
102
|
+
* @param message Text content
|
|
103
|
+
*/
|
|
63
104
|
send: (message: string) => any;
|
|
105
|
+
/**
|
|
106
|
+
* Send HTML response.
|
|
107
|
+
* @param html HTML string
|
|
108
|
+
*/
|
|
64
109
|
html: (html: string) => any;
|
|
110
|
+
/**
|
|
111
|
+
* Set HTTP status code and return chained response helpers.
|
|
112
|
+
*
|
|
113
|
+
* This method does not send a response immediately.
|
|
114
|
+
* Instead, it sets the status code and returns a response builder
|
|
115
|
+
* that allows sending the response in different formats.
|
|
116
|
+
*
|
|
117
|
+
* @param code HTTP status code to set for the response
|
|
118
|
+
* @returns An object containing response methods bound to the given status
|
|
119
|
+
*
|
|
120
|
+
* @example
|
|
121
|
+
* res.status(200).json({ success: true });
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* res.status(404).send("Not Found");
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* res.status(204).end();
|
|
128
|
+
*/
|
|
65
129
|
status: (code: TStatusCode) => {
|
|
130
|
+
/**
|
|
131
|
+
* Send JSON response with the previously set status code.
|
|
132
|
+
*
|
|
133
|
+
* @param data JSON-serializable object to send as response body
|
|
134
|
+
*/
|
|
66
135
|
json: (data?: Record<string, any>) => any;
|
|
136
|
+
/**
|
|
137
|
+
* Send plain text response with the previously set status code.
|
|
138
|
+
*
|
|
139
|
+
* @param message Text response body
|
|
140
|
+
*/
|
|
67
141
|
send: (message: string) => any;
|
|
142
|
+
/**
|
|
143
|
+
* End the response with optional raw message body.
|
|
144
|
+
*
|
|
145
|
+
* Commonly used for empty responses (e.g. 204 No Content).
|
|
146
|
+
*
|
|
147
|
+
* @param message Optional raw response body
|
|
148
|
+
*/
|
|
149
|
+
end: (message?: string) => any;
|
|
68
150
|
};
|
|
151
|
+
/**
|
|
152
|
+
* Set HTTP cookies.
|
|
153
|
+
* @param cookies Key-value map or detailed cookie objects
|
|
154
|
+
*/
|
|
69
155
|
setCookies: (cookies: Record<string, string | {
|
|
70
156
|
value: string;
|
|
157
|
+
path?: string;
|
|
71
158
|
sameSite?: 'Strict' | 'Lax' | 'None';
|
|
72
159
|
domain?: string;
|
|
73
160
|
secure?: boolean;
|
|
@@ -89,16 +176,16 @@ type TRoute = {
|
|
|
89
176
|
};
|
|
90
177
|
type TMethod = 'get' | 'post' | 'patch' | 'put' | 'delete' | 'all' | 'head' | 'options';
|
|
91
178
|
type TMethodInput = Uppercase<TMethod>;
|
|
92
|
-
type
|
|
179
|
+
type HandlerUWS = (res: unknown, req: unknown) => void | Promise<void>;
|
|
93
180
|
type UWS = {
|
|
94
181
|
App: () => {
|
|
95
|
-
get: (path: string, handler:
|
|
96
|
-
post: (path: string, handler:
|
|
97
|
-
patch: (path: string, handler:
|
|
98
|
-
put: (path: string, handler:
|
|
99
|
-
del: (path: string, handler:
|
|
100
|
-
any: (path: string, handler:
|
|
101
|
-
options: (path: string, handler:
|
|
182
|
+
get: (path: string, handler: HandlerUWS) => any;
|
|
183
|
+
post: (path: string, handler: HandlerUWS) => any;
|
|
184
|
+
patch: (path: string, handler: HandlerUWS) => any;
|
|
185
|
+
put: (path: string, handler: HandlerUWS) => any;
|
|
186
|
+
del: (path: string, handler: HandlerUWS) => any;
|
|
187
|
+
any: (path: string, handler: HandlerUWS) => any;
|
|
188
|
+
options: (path: string, handler: HandlerUWS) => any;
|
|
102
189
|
listen: (...args: any[]) => any;
|
|
103
190
|
ws: (path: string, options: {
|
|
104
191
|
open?: (ws: any) => void;
|
|
@@ -107,22 +194,33 @@ type UWS = {
|
|
|
107
194
|
}) => any;
|
|
108
195
|
};
|
|
109
196
|
};
|
|
110
|
-
type TAdapter =
|
|
197
|
+
type TAdapter = {
|
|
198
|
+
kind: 'http';
|
|
199
|
+
server: typeof http;
|
|
200
|
+
} | {
|
|
201
|
+
kind: 'net';
|
|
202
|
+
server: typeof net;
|
|
203
|
+
} | {
|
|
204
|
+
kind: 'uWS';
|
|
205
|
+
server: UWS;
|
|
206
|
+
};
|
|
207
|
+
type TAdapterServer = typeof http | typeof net | UWS;
|
|
111
208
|
type TApplication = {
|
|
112
209
|
controllers?: (new () => any)[] | {
|
|
113
210
|
folder: string;
|
|
114
211
|
name?: RegExp;
|
|
115
212
|
};
|
|
116
|
-
middlewares?:
|
|
213
|
+
middlewares?: TContextHandler[] | {
|
|
117
214
|
folder: string;
|
|
118
215
|
name?: RegExp;
|
|
119
216
|
};
|
|
120
217
|
globalPrefix?: string;
|
|
121
218
|
logger?: boolean;
|
|
122
219
|
cluster?: boolean | number;
|
|
123
|
-
adapter?:
|
|
220
|
+
adapter?: TAdapterServer;
|
|
221
|
+
express?: boolean;
|
|
124
222
|
};
|
|
125
|
-
type
|
|
223
|
+
type TContextHandler = (ctx: TContext, next: TNextFunction) => any;
|
|
126
224
|
type TErrorFunction = (err: Error, ctx: TContext) => any;
|
|
127
225
|
type TSwaggerFormat = "string" | "number" | "integer" | "boolean" | "object" | "array" | "date" | "date-time" | "password" | "int32" | "int64" | "float" | "double" | "byte" | "binary" | "base64" | "email" | "uuid" | "uri" | "hostname" | "ipv4" | "ipv6" | "json" | "xml";
|
|
128
226
|
type TSwaggerType = "string" | "number" | "integer" | "boolean" | "object" | "array" | "date" | "date-time" | "file";
|
|
@@ -164,40 +262,40 @@ type TSwaggerDoc = {
|
|
|
164
262
|
example?: Record<string, any>;
|
|
165
263
|
}[];
|
|
166
264
|
};
|
|
265
|
+
type TSwaggerPropertyOptions = {
|
|
266
|
+
type: "array";
|
|
267
|
+
items: TSwaggerPropertyOptions;
|
|
268
|
+
enum?: never;
|
|
269
|
+
required?: boolean;
|
|
270
|
+
example?: any;
|
|
271
|
+
description?: string;
|
|
272
|
+
format?: TSwaggerFormat;
|
|
273
|
+
} | {
|
|
274
|
+
type?: Exclude<TSwaggerType, "array">;
|
|
275
|
+
enum?: (string | number)[];
|
|
276
|
+
required?: boolean;
|
|
277
|
+
example?: any;
|
|
278
|
+
description?: string;
|
|
279
|
+
format?: TSwaggerFormat;
|
|
280
|
+
items?: never;
|
|
281
|
+
};
|
|
167
282
|
type TSwagger = {
|
|
168
283
|
disabled?: boolean;
|
|
169
284
|
description?: string;
|
|
170
285
|
summary?: string;
|
|
171
286
|
bearerToken?: boolean;
|
|
172
287
|
tags?: string[];
|
|
173
|
-
params?: Record<string,
|
|
174
|
-
|
|
175
|
-
type?: TSwaggerType;
|
|
176
|
-
example?: any;
|
|
177
|
-
}>;
|
|
178
|
-
query?: Record<string, {
|
|
179
|
-
required?: boolean;
|
|
180
|
-
description?: string;
|
|
181
|
-
type?: TSwaggerType;
|
|
182
|
-
example?: any;
|
|
183
|
-
}>;
|
|
288
|
+
params?: Record<string, TSwaggerPropertyOptions>;
|
|
289
|
+
query?: Record<string, TSwaggerPropertyOptions>;
|
|
184
290
|
body?: {
|
|
185
291
|
required?: boolean;
|
|
186
292
|
description?: string;
|
|
187
|
-
properties: Record<string,
|
|
188
|
-
type: TSwaggerType;
|
|
189
|
-
example?: any;
|
|
190
|
-
}>;
|
|
293
|
+
properties: Record<string, TSwaggerPropertyOptions>;
|
|
191
294
|
};
|
|
192
295
|
files?: {
|
|
193
296
|
required?: boolean;
|
|
194
297
|
description?: string;
|
|
195
|
-
properties: Record<string,
|
|
196
|
-
type: TSwaggerType;
|
|
197
|
-
format?: TSwaggerFormat;
|
|
198
|
-
items?: any;
|
|
199
|
-
example?: any;
|
|
200
|
-
}>;
|
|
298
|
+
properties: Record<string, TSwaggerPropertyOptions>;
|
|
201
299
|
};
|
|
202
300
|
cookies?: {
|
|
203
301
|
names: string[];
|
|
@@ -211,13 +309,14 @@ type TSwagger = {
|
|
|
211
309
|
}[];
|
|
212
310
|
};
|
|
213
311
|
type TWSHandler = {
|
|
214
|
-
connection: (ws: WebSocket) => void | string | Buffer;
|
|
215
|
-
message: (ws: WebSocket
|
|
216
|
-
close: (ws: WebSocket
|
|
217
|
-
error: (ws: WebSocket
|
|
312
|
+
connection: (ws: WebSocket & Partial<any>) => void | string | Buffer;
|
|
313
|
+
message: (ws: WebSocket & Partial<any>, data: WebSocket.Data) => void | string | Buffer;
|
|
314
|
+
close: (ws: WebSocket & Partial<any>, code: number, reason: Buffer) => void;
|
|
315
|
+
error: (ws: WebSocket & Partial<any>, error: Error) => void;
|
|
218
316
|
};
|
|
219
317
|
export declare namespace T {
|
|
220
318
|
type Adapter = TAdapter;
|
|
319
|
+
type AdapterServer = TAdapterServer;
|
|
221
320
|
type Application = TApplication;
|
|
222
321
|
type NextFunction = TNextFunction;
|
|
223
322
|
type File = TFile;
|
|
@@ -227,7 +326,7 @@ export declare namespace T {
|
|
|
227
326
|
type Method = TMethod;
|
|
228
327
|
type ErrorFunction = TErrorFunction;
|
|
229
328
|
type HttpStatus = THttpResponder;
|
|
230
|
-
type
|
|
329
|
+
type ContextHandler = TContextHandler;
|
|
231
330
|
type WebSocketHandler = TWSHandler;
|
|
232
331
|
type StatusCode = TStatusCode;
|
|
233
332
|
type MethodInput = TMethodInput;
|
|
@@ -239,6 +338,8 @@ export declare namespace T {
|
|
|
239
338
|
type Query<T = Record<string, string>> = TQuery<T>;
|
|
240
339
|
type Body<T = Record<string, any>> = TBody<T>;
|
|
241
340
|
type Headers<T = IncomingHttpHeaders> = THeaders<T>;
|
|
341
|
+
type Ip = TIp;
|
|
342
|
+
type Ips = TIps;
|
|
242
343
|
namespace Swagger {
|
|
243
344
|
type Spec = TSwagger;
|
|
244
345
|
type Format = TSwaggerFormat;
|