tspace-spear 1.1.0 → 1.1.2
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/build/lib/core/decorators/context.js +25 -49
- package/build/lib/core/decorators/context.js.map +1 -1
- package/build/lib/core/decorators/headers.js +3 -14
- package/build/lib/core/decorators/headers.js.map +1 -1
- package/build/lib/core/decorators/statusCode.js +3 -14
- package/build/lib/core/decorators/statusCode.js.map +1 -1
- package/build/lib/core/decorators/swagger.js +4 -1
- package/build/lib/core/decorators/swagger.js.map +1 -1
- package/build/lib/core/server/index.d.ts +19 -16
- package/build/lib/core/server/index.js +257 -252
- package/build/lib/core/server/index.js.map +1 -1
- package/build/lib/core/server/parser-factory.js +81 -94
- package/build/lib/core/server/parser-factory.js.map +1 -1
- package/build/lib/core/server/router.js +1 -3
- package/build/lib/core/server/router.js.map +1 -1
- package/build/tests/benchmark.test.js +51 -71
- package/build/tests/benchmark.test.js.map +1 -1
- package/package.json +10 -8
|
@@ -22,15 +22,6 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
22
22
|
__setModuleDefault(result, mod);
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
26
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
27
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
28
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
29
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
30
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
31
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
32
|
-
});
|
|
33
|
-
};
|
|
34
25
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
35
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
36
27
|
};
|
|
@@ -62,87 +53,41 @@ const parser_factory_1 = require("./parser-factory");
|
|
|
62
53
|
*
|
|
63
54
|
*/
|
|
64
55
|
class Spear {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
info: {
|
|
78
|
-
title: "API Documentation",
|
|
79
|
-
description: "This is a sample documentation",
|
|
80
|
-
version: "1.0.0"
|
|
56
|
+
_controllers;
|
|
57
|
+
_middlewares;
|
|
58
|
+
_globalPrefix;
|
|
59
|
+
_cluster;
|
|
60
|
+
_router = (0, find_my_way_1.default)();
|
|
61
|
+
_parser = new parser_factory_1.ParserFactory();
|
|
62
|
+
_swagger = {
|
|
63
|
+
use: false,
|
|
64
|
+
path: '/api/docs',
|
|
65
|
+
servers: [
|
|
66
|
+
{
|
|
67
|
+
url: 'http://localhost:3000'
|
|
81
68
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const headers = request.headers;
|
|
105
|
-
const query = Object.assign({}, (0, url_1.parse)(String(req.url), true).query);
|
|
106
|
-
const RecordOrEmptyRecord = (data) => {
|
|
107
|
-
if (data == null)
|
|
108
|
-
return {};
|
|
109
|
-
return Object.keys(data).length ? data : {};
|
|
110
|
-
};
|
|
111
|
-
const ctx = {
|
|
112
|
-
req,
|
|
113
|
-
res: response,
|
|
114
|
-
headers: RecordOrEmptyRecord(headers),
|
|
115
|
-
params: RecordOrEmptyRecord(params),
|
|
116
|
-
query: RecordOrEmptyRecord(query),
|
|
117
|
-
body: RecordOrEmptyRecord(body),
|
|
118
|
-
files: RecordOrEmptyRecord(files),
|
|
119
|
-
cookies: RecordOrEmptyRecord(cookies)
|
|
120
|
-
};
|
|
121
|
-
if (index === handlers.length - 1) {
|
|
122
|
-
return this._wrapResponse(handlers[index].bind(handlers[index]))(ctx, this._nextFunction(ctx));
|
|
123
|
-
}
|
|
124
|
-
return handlers[index](ctx, () => {
|
|
125
|
-
return runHandler(index + 1);
|
|
126
|
-
});
|
|
127
|
-
};
|
|
128
|
-
try {
|
|
129
|
-
runHandler();
|
|
130
|
-
}
|
|
131
|
-
catch (err) {
|
|
132
|
-
const ctx = {
|
|
133
|
-
req,
|
|
134
|
-
res: this._customizeResponse(req, res),
|
|
135
|
-
params: Object.keys(params).length ? params : {},
|
|
136
|
-
headers: {},
|
|
137
|
-
query: {},
|
|
138
|
-
body: {},
|
|
139
|
-
files: {},
|
|
140
|
-
cookies: {}
|
|
141
|
-
};
|
|
142
|
-
return this._nextFunction(ctx)(err);
|
|
143
|
-
}
|
|
144
|
-
};
|
|
145
|
-
};
|
|
69
|
+
],
|
|
70
|
+
tags: [],
|
|
71
|
+
info: {
|
|
72
|
+
title: "API Documentation",
|
|
73
|
+
description: "This is a sample documentation",
|
|
74
|
+
version: "1.0.0"
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
_swaggerAdditional = [];
|
|
78
|
+
_errorHandler = null;
|
|
79
|
+
_globalMiddlewares = [];
|
|
80
|
+
_formatResponse = null;
|
|
81
|
+
_onListeners = [];
|
|
82
|
+
_fileUploadOptions = {
|
|
83
|
+
limit: Infinity,
|
|
84
|
+
tempFileDir: 'tmp',
|
|
85
|
+
removeTempFile: {
|
|
86
|
+
remove: false,
|
|
87
|
+
ms: 1000 * 60 * 10
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
constructor({ controllers, middlewares, globalPrefix, logger, cluster } = {}) {
|
|
146
91
|
if (logger)
|
|
147
92
|
this.useLogger();
|
|
148
93
|
this._cluster = cluster;
|
|
@@ -227,38 +172,27 @@ class Spear {
|
|
|
227
172
|
return this;
|
|
228
173
|
}
|
|
229
174
|
/**
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
* @property {boolean} removeTempFile.remove
|
|
237
|
-
* @property {number} removeTempFile.ms
|
|
238
|
-
* @returns
|
|
239
|
-
*/
|
|
240
|
-
useFileUpload({ limit, tempFileDir, removeTempFile } = {}) {
|
|
241
|
-
if (limit != null) {
|
|
242
|
-
this._fileUploadOptions.limit = limit;
|
|
243
|
-
}
|
|
244
|
-
if (tempFileDir != null) {
|
|
245
|
-
this._fileUploadOptions.tempFileDir = tempFileDir;
|
|
246
|
-
}
|
|
247
|
-
if (removeTempFile != null) {
|
|
248
|
-
this._fileUploadOptions.removeTempFile = removeTempFile;
|
|
249
|
-
}
|
|
175
|
+
* The 'useBodyParser' method is a middleware used to parse the request body of incoming HTTP requests.
|
|
176
|
+
* @param {object?}
|
|
177
|
+
* @property {array?} except the body parser with some methods
|
|
178
|
+
* @returns {this}
|
|
179
|
+
*/
|
|
180
|
+
useBodyParser({ except } = {}) {
|
|
250
181
|
this._globalMiddlewares.push(({ req }, next) => {
|
|
251
|
-
const contentType = req
|
|
182
|
+
const contentType = req?.headers['content-type'];
|
|
252
183
|
const isFileUpload = contentType && contentType.startsWith('multipart/form-data');
|
|
253
|
-
|
|
254
|
-
|
|
184
|
+
if (except != null && Array.isArray(except)) {
|
|
185
|
+
if (except.some(v => v.toLocaleLowerCase() === (req.method)?.toLocaleLowerCase())) {
|
|
186
|
+
return next();
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (isFileUpload)
|
|
255
190
|
return next();
|
|
256
|
-
if (
|
|
191
|
+
if (req?.body != null)
|
|
257
192
|
return next();
|
|
258
|
-
Promise.resolve(this._parser.
|
|
193
|
+
Promise.resolve(this._parser.body(req))
|
|
259
194
|
.then(r => {
|
|
260
|
-
req.
|
|
261
|
-
req.body = r.body;
|
|
195
|
+
req.body = r;
|
|
262
196
|
return next();
|
|
263
197
|
})
|
|
264
198
|
.catch(_ => next());
|
|
@@ -266,21 +200,40 @@ class Spear {
|
|
|
266
200
|
return this;
|
|
267
201
|
}
|
|
268
202
|
/**
|
|
269
|
-
* The '
|
|
203
|
+
* The 'useFileUpload' method is a middleware used to handler file uploads. It adds a file upload of incoming HTTP requests.
|
|
270
204
|
*
|
|
271
|
-
* @
|
|
205
|
+
* @param {?Object}
|
|
206
|
+
* @property {?number} limits
|
|
207
|
+
* @property {?string} tempFileDir
|
|
208
|
+
* @property {?Object} removeTempFile
|
|
209
|
+
* @property {boolean} removeTempFile.remove
|
|
210
|
+
* @property {number} removeTempFile.ms
|
|
211
|
+
* @returns
|
|
272
212
|
*/
|
|
273
|
-
|
|
213
|
+
useFileUpload({ limit, tempFileDir, removeTempFile } = {}) {
|
|
214
|
+
if (limit != null) {
|
|
215
|
+
this._fileUploadOptions.limit = limit;
|
|
216
|
+
}
|
|
217
|
+
if (tempFileDir != null) {
|
|
218
|
+
this._fileUploadOptions.tempFileDir = tempFileDir;
|
|
219
|
+
}
|
|
220
|
+
if (removeTempFile != null) {
|
|
221
|
+
this._fileUploadOptions.removeTempFile = removeTempFile;
|
|
222
|
+
}
|
|
274
223
|
this._globalMiddlewares.push(({ req }, next) => {
|
|
275
|
-
const contentType = req
|
|
224
|
+
const contentType = req?.headers['content-type'];
|
|
276
225
|
const isFileUpload = contentType && contentType.startsWith('multipart/form-data');
|
|
277
|
-
if (
|
|
226
|
+
if (req.method === 'GET') {
|
|
227
|
+
return next();
|
|
228
|
+
}
|
|
229
|
+
if (!isFileUpload)
|
|
278
230
|
return next();
|
|
279
|
-
if (
|
|
231
|
+
if (req?.files != null)
|
|
280
232
|
return next();
|
|
281
|
-
Promise.resolve(this._parser.
|
|
233
|
+
Promise.resolve(this._parser.files({ req, options: this._fileUploadOptions }))
|
|
282
234
|
.then(r => {
|
|
283
|
-
req.
|
|
235
|
+
req.files = r.files;
|
|
236
|
+
req.body = r.body;
|
|
284
237
|
return next();
|
|
285
238
|
})
|
|
286
239
|
.catch(_ => next());
|
|
@@ -294,7 +247,7 @@ class Spear {
|
|
|
294
247
|
*/
|
|
295
248
|
useCookiesParser() {
|
|
296
249
|
this._globalMiddlewares.push(({ req }, next) => {
|
|
297
|
-
if (
|
|
250
|
+
if (req?.cookies != null)
|
|
298
251
|
return next();
|
|
299
252
|
req.cookies = this._parser.cookies(req);
|
|
300
253
|
return next();
|
|
@@ -328,10 +281,10 @@ class Spear {
|
|
|
328
281
|
useSwagger({ path, servers, info, tags } = {}) {
|
|
329
282
|
this._swagger = {
|
|
330
283
|
use: true,
|
|
331
|
-
path: path
|
|
332
|
-
servers: servers
|
|
333
|
-
tags: tags
|
|
334
|
-
info: info
|
|
284
|
+
path: path ?? this._swagger.path,
|
|
285
|
+
servers: servers ?? this._swagger.servers,
|
|
286
|
+
tags: tags ?? this._swagger.tags,
|
|
287
|
+
info: info ?? this._swagger.info
|
|
335
288
|
};
|
|
336
289
|
return this;
|
|
337
290
|
}
|
|
@@ -342,35 +295,32 @@ class Spear {
|
|
|
342
295
|
* @param {function} callback
|
|
343
296
|
* @returns
|
|
344
297
|
*/
|
|
345
|
-
listen() {
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
this._cluster || typeof this._cluster === 'number') {
|
|
355
|
-
this._clusterMode(server, Number(port), callback);
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
server.listen(port == null ? 3000 : port, () => {
|
|
359
|
-
if (callback)
|
|
360
|
-
callback({ server, port });
|
|
361
|
-
});
|
|
362
|
-
server.on('listening', () => {
|
|
363
|
-
this._onListeners.forEach(listener => listener());
|
|
364
|
-
if (this._swagger.use) {
|
|
365
|
-
this._swaggerHandler();
|
|
366
|
-
}
|
|
367
|
-
});
|
|
368
|
-
server.on('error', (_) => {
|
|
369
|
-
port = Math.floor(Math.random() * 8999) + 1000;
|
|
370
|
-
server.listen(port);
|
|
371
|
-
});
|
|
298
|
+
async listen(port = 3000, callback) {
|
|
299
|
+
if (arguments.length === 1 && typeof port === 'function') {
|
|
300
|
+
callback = port;
|
|
301
|
+
port = 3000;
|
|
302
|
+
}
|
|
303
|
+
const server = await this._createServer();
|
|
304
|
+
if (this._cluster != null &&
|
|
305
|
+
this._cluster || typeof this._cluster === 'number') {
|
|
306
|
+
this._clusterMode(server, Number(port), callback);
|
|
372
307
|
return;
|
|
308
|
+
}
|
|
309
|
+
server.listen(port == null ? 3000 : port, () => {
|
|
310
|
+
if (callback)
|
|
311
|
+
callback({ server, port });
|
|
312
|
+
});
|
|
313
|
+
server.on('listening', () => {
|
|
314
|
+
this._onListeners.forEach(listener => listener());
|
|
315
|
+
if (this._swagger.use) {
|
|
316
|
+
this._swaggerHandler();
|
|
317
|
+
}
|
|
318
|
+
});
|
|
319
|
+
server.on('error', (_) => {
|
|
320
|
+
port = Math.floor(Math.random() * 8999) + 1000;
|
|
321
|
+
server.listen(port);
|
|
373
322
|
});
|
|
323
|
+
return;
|
|
374
324
|
}
|
|
375
325
|
/**
|
|
376
326
|
* The 'enableCors' is used to enable the cors origins on the server.
|
|
@@ -382,8 +332,7 @@ class Spear {
|
|
|
382
332
|
*/
|
|
383
333
|
enableCors({ origins, credentials } = {}) {
|
|
384
334
|
this._globalMiddlewares.push(({ req, res }, next) => {
|
|
385
|
-
|
|
386
|
-
const origin = (_a = req.headers) === null || _a === void 0 ? void 0 : _a.origin;
|
|
335
|
+
const origin = req.headers?.origin;
|
|
387
336
|
if (origin == null)
|
|
388
337
|
return next();
|
|
389
338
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS');
|
|
@@ -571,57 +520,33 @@ class Spear {
|
|
|
571
520
|
}
|
|
572
521
|
return;
|
|
573
522
|
}
|
|
574
|
-
_import(dir, pattern) {
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
const
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
return directory.isDirectory() ? this._import(newDir) : newDir;
|
|
581
|
-
}
|
|
582
|
-
return directory.isDirectory()
|
|
583
|
-
? this._import(newDir)
|
|
584
|
-
: pattern.test(directory.name)
|
|
585
|
-
? newDir
|
|
586
|
-
: null;
|
|
587
|
-
}))).filter(d => d != null);
|
|
588
|
-
return [].concat(...files);
|
|
589
|
-
});
|
|
590
|
-
}
|
|
591
|
-
_registerControllers() {
|
|
592
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
593
|
-
var _a, _b, _c, _d, _e, _f;
|
|
594
|
-
if (this._controllers == null)
|
|
595
|
-
return;
|
|
596
|
-
if (!Array.isArray(this._controllers)) {
|
|
597
|
-
const controllers = yield this._import(this._controllers.folder, this._controllers.name);
|
|
598
|
-
for (const file of controllers) {
|
|
599
|
-
const response = yield Promise.resolve(`${file}`).then(s => __importStar(require(s)));
|
|
600
|
-
const controller = response === null || response === void 0 ? void 0 : response.default;
|
|
601
|
-
const controllerInstance = new controller();
|
|
602
|
-
const prefixPath = (_a = Reflect.getMetadata("controllers", controller)) !== null && _a !== void 0 ? _a : '';
|
|
603
|
-
const routers = (_b = Reflect.getMetadata("routers", controller)) !== null && _b !== void 0 ? _b : [];
|
|
604
|
-
const swaggers = (_c = Reflect.getMetadata("swaggers", controller)) !== null && _c !== void 0 ? _c : [];
|
|
605
|
-
if (prefixPath == null)
|
|
606
|
-
continue;
|
|
607
|
-
for (const { method, path, handler } of Array.from(routers)) {
|
|
608
|
-
const find = Array.from(swaggers).find(s => s.handler === handler);
|
|
609
|
-
if (find != null) {
|
|
610
|
-
this._swaggerAdditional = [
|
|
611
|
-
...this._swaggerAdditional,
|
|
612
|
-
Object.assign(Object.assign({}, find), { path: this._normalizePath(this._globalPrefix, prefixPath, path), method })
|
|
613
|
-
];
|
|
614
|
-
}
|
|
615
|
-
this[method](this._normalizePath(this._globalPrefix, prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
|
|
616
|
-
}
|
|
617
|
-
}
|
|
618
|
-
return;
|
|
523
|
+
async _import(dir, pattern) {
|
|
524
|
+
const directories = fs_1.default.readdirSync(dir, { withFileTypes: true });
|
|
525
|
+
const files = (await Promise.all(directories.map((directory) => {
|
|
526
|
+
const newDir = path_1.default.resolve(String(dir), directory.name);
|
|
527
|
+
if (pattern == null) {
|
|
528
|
+
return directory.isDirectory() ? this._import(newDir) : newDir;
|
|
619
529
|
}
|
|
620
|
-
|
|
530
|
+
return directory.isDirectory()
|
|
531
|
+
? this._import(newDir)
|
|
532
|
+
: pattern.test(directory.name)
|
|
533
|
+
? newDir
|
|
534
|
+
: null;
|
|
535
|
+
}))).filter(d => d != null);
|
|
536
|
+
return [].concat(...files);
|
|
537
|
+
}
|
|
538
|
+
async _registerControllers() {
|
|
539
|
+
if (this._controllers == null)
|
|
540
|
+
return;
|
|
541
|
+
if (!Array.isArray(this._controllers)) {
|
|
542
|
+
const controllers = await this._import(this._controllers.folder, this._controllers.name);
|
|
543
|
+
for (const file of controllers) {
|
|
544
|
+
const response = await Promise.resolve(`${file}`).then(s => __importStar(require(s)));
|
|
545
|
+
const controller = response?.default;
|
|
621
546
|
const controllerInstance = new controller();
|
|
622
|
-
const prefixPath =
|
|
623
|
-
const routers =
|
|
624
|
-
const swaggers =
|
|
547
|
+
const prefixPath = Reflect.getMetadata("controllers", controller) ?? '';
|
|
548
|
+
const routers = Reflect.getMetadata("routers", controller) ?? [];
|
|
549
|
+
const swaggers = Reflect.getMetadata("swaggers", controller) ?? [];
|
|
625
550
|
if (prefixPath == null)
|
|
626
551
|
continue;
|
|
627
552
|
for (const { method, path, handler } of Array.from(routers)) {
|
|
@@ -629,33 +554,58 @@ class Spear {
|
|
|
629
554
|
if (find != null) {
|
|
630
555
|
this._swaggerAdditional = [
|
|
631
556
|
...this._swaggerAdditional,
|
|
632
|
-
|
|
557
|
+
{
|
|
558
|
+
...find,
|
|
559
|
+
path: this._normalizePath(this._globalPrefix, prefixPath, path),
|
|
560
|
+
method
|
|
561
|
+
}
|
|
633
562
|
];
|
|
634
563
|
}
|
|
635
564
|
this[method](this._normalizePath(this._globalPrefix, prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
|
|
636
565
|
}
|
|
637
566
|
}
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
567
|
+
return;
|
|
568
|
+
}
|
|
569
|
+
for (const controller of this._controllers) {
|
|
570
|
+
const controllerInstance = new controller();
|
|
571
|
+
const prefixPath = Reflect.getMetadata("controllers", controller) ?? '';
|
|
572
|
+
const routers = Reflect.getMetadata("routers", controller) ?? [];
|
|
573
|
+
const swaggers = Reflect.getMetadata("swaggers", controller) ?? [];
|
|
574
|
+
if (prefixPath == null)
|
|
575
|
+
continue;
|
|
576
|
+
for (const { method, path, handler } of Array.from(routers)) {
|
|
577
|
+
const find = Array.from(swaggers).find(s => s.handler === handler);
|
|
578
|
+
if (find != null) {
|
|
579
|
+
this._swaggerAdditional = [
|
|
580
|
+
...this._swaggerAdditional,
|
|
581
|
+
{
|
|
582
|
+
...find,
|
|
583
|
+
path: this._normalizePath(this._globalPrefix, prefixPath, path),
|
|
584
|
+
method
|
|
585
|
+
}
|
|
586
|
+
];
|
|
650
587
|
}
|
|
651
|
-
|
|
588
|
+
this[method](this._normalizePath(this._globalPrefix, prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
|
|
652
589
|
}
|
|
653
|
-
|
|
654
|
-
|
|
590
|
+
}
|
|
591
|
+
}
|
|
592
|
+
async _registerMiddlewares() {
|
|
593
|
+
if (this._middlewares == null)
|
|
594
|
+
return;
|
|
595
|
+
if (!Array.isArray(this._middlewares)) {
|
|
596
|
+
const middlewares = await this._import(this._middlewares.folder, this._middlewares.name);
|
|
597
|
+
for (const file of middlewares) {
|
|
598
|
+
const response = await Promise.resolve(`${file}`).then(s => __importStar(require(s)));
|
|
599
|
+
const middleware = response?.default;
|
|
655
600
|
this.use(middleware);
|
|
656
601
|
}
|
|
657
602
|
return;
|
|
658
|
-
}
|
|
603
|
+
}
|
|
604
|
+
const middlewares = this._middlewares;
|
|
605
|
+
for (const middleware of middlewares) {
|
|
606
|
+
this.use(middleware);
|
|
607
|
+
}
|
|
608
|
+
return;
|
|
659
609
|
}
|
|
660
610
|
_customizeResponse(req, res) {
|
|
661
611
|
const response = res;
|
|
@@ -676,9 +626,13 @@ class Spear {
|
|
|
676
626
|
return res.end();
|
|
677
627
|
}
|
|
678
628
|
if (this._formatResponse != null) {
|
|
679
|
-
return res.end(JSON.stringify(this._formatResponse(
|
|
629
|
+
return res.end(JSON.stringify(this._formatResponse({
|
|
630
|
+
...results
|
|
631
|
+
}, res.statusCode), null, 2));
|
|
680
632
|
}
|
|
681
|
-
return res.end(JSON.stringify(
|
|
633
|
+
return res.end(JSON.stringify({
|
|
634
|
+
...results,
|
|
635
|
+
}, null, 2));
|
|
682
636
|
};
|
|
683
637
|
response.send = (results) => {
|
|
684
638
|
res.writeHead(res.statusCode, { 'Content-Type': 'text/plain' });
|
|
@@ -689,16 +643,15 @@ class Spear {
|
|
|
689
643
|
return res.end(results);
|
|
690
644
|
};
|
|
691
645
|
response.error = (err) => {
|
|
692
|
-
|
|
693
|
-
let code = +((_b = (_a = err.response) === null || _a === void 0 ? void 0 : _a.data) === null || _b === void 0 ? void 0 : _b.code) ||
|
|
646
|
+
let code = +err.response?.data?.code ||
|
|
694
647
|
+err.code ||
|
|
695
648
|
+err.status ||
|
|
696
649
|
+err.statusCode ||
|
|
697
|
-
+
|
|
650
|
+
+err.response?.data?.statusCode ||
|
|
698
651
|
500;
|
|
699
652
|
code = (code == null || typeof code !== 'number') ? 500 : Number.isNaN(code) ? 500 : code < 400 ? 500 : code;
|
|
700
|
-
const message =
|
|
701
|
-
|
|
653
|
+
const message = err.response?.data?.errorMessage ||
|
|
654
|
+
err.response?.data?.message ||
|
|
702
655
|
err.message ||
|
|
703
656
|
`The url '${req.url}' resulted in a server error. Please investigate.`;
|
|
704
657
|
response.status(code);
|
|
@@ -726,7 +679,7 @@ class Spear {
|
|
|
726
679
|
};
|
|
727
680
|
response.badRequest = (message) => {
|
|
728
681
|
response.status(400);
|
|
729
|
-
message = message
|
|
682
|
+
message = message ?? `The url '${req.url}' resulted in a bad request. Please review the data and try again.`;
|
|
730
683
|
if (this._formatResponse != null) {
|
|
731
684
|
return res.end(JSON.stringify(this._formatResponse({ message }, 400), null, 2));
|
|
732
685
|
}
|
|
@@ -736,7 +689,7 @@ class Spear {
|
|
|
736
689
|
};
|
|
737
690
|
response.unauthorized = (message) => {
|
|
738
691
|
response.status(401);
|
|
739
|
-
message = message
|
|
692
|
+
message = message ?? `The url '${req.url}' is unauthorized. Please verify.`;
|
|
740
693
|
if (this._formatResponse != null) {
|
|
741
694
|
return res.end(JSON.stringify(this._formatResponse({ message }, 401), null, 2));
|
|
742
695
|
}
|
|
@@ -746,7 +699,7 @@ class Spear {
|
|
|
746
699
|
};
|
|
747
700
|
response.paymentRequired = (message) => {
|
|
748
701
|
response.status(402);
|
|
749
|
-
message = message
|
|
702
|
+
message = message ?? `The url '${req.url}' requires payment. Please proceed with payment.`;
|
|
750
703
|
if (this._formatResponse != null) {
|
|
751
704
|
return res.end(JSON.stringify(this._formatResponse({ message }, 402), null, 2));
|
|
752
705
|
}
|
|
@@ -756,7 +709,7 @@ class Spear {
|
|
|
756
709
|
};
|
|
757
710
|
response.forbidden = (message) => {
|
|
758
711
|
response.status(403);
|
|
759
|
-
message = message
|
|
712
|
+
message = message ?? `The url '${req.url}' is forbidden. Please check the permissions or access rights.`;
|
|
760
713
|
if (this._formatResponse != null) {
|
|
761
714
|
return res.end(JSON.stringify(this._formatResponse({ message }, 403), null, 2));
|
|
762
715
|
}
|
|
@@ -766,7 +719,7 @@ class Spear {
|
|
|
766
719
|
};
|
|
767
720
|
response.notFound = (message) => {
|
|
768
721
|
response.status(404);
|
|
769
|
-
message = message
|
|
722
|
+
message = message ?? `The url '${req.url}' was not found. Please re-check the your url again`;
|
|
770
723
|
if (this._formatResponse != null) {
|
|
771
724
|
return res.end(JSON.stringify(this._formatResponse({ message }, 404), null, 2));
|
|
772
725
|
}
|
|
@@ -776,7 +729,7 @@ class Spear {
|
|
|
776
729
|
};
|
|
777
730
|
response.serverError = (message) => {
|
|
778
731
|
response.status(500);
|
|
779
|
-
message = message
|
|
732
|
+
message = message ?? `The url '${req.url}' resulted in a server error. Please investigate.`;
|
|
780
733
|
if (this._formatResponse != null) {
|
|
781
734
|
return res.end(JSON.stringify(this._formatResponse({ message }, 500), null, 2));
|
|
782
735
|
}
|
|
@@ -827,11 +780,11 @@ class Spear {
|
|
|
827
780
|
ctx.res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
828
781
|
if (this._formatResponse != null) {
|
|
829
782
|
return ctx.res.end(JSON.stringify(this._formatResponse({
|
|
830
|
-
message: err
|
|
783
|
+
message: err?.message,
|
|
831
784
|
}, ctx.res.statusCode), null, 2));
|
|
832
785
|
}
|
|
833
786
|
return ctx.res.end(JSON.stringify({
|
|
834
|
-
message: err
|
|
787
|
+
message: err?.message,
|
|
835
788
|
}, null, 2));
|
|
836
789
|
}
|
|
837
790
|
if (this._errorHandler != null) {
|
|
@@ -848,6 +801,56 @@ class Spear {
|
|
|
848
801
|
}, null, 2));
|
|
849
802
|
};
|
|
850
803
|
}
|
|
804
|
+
_wrapHandlers = (...handlers) => {
|
|
805
|
+
return (req, res, params) => {
|
|
806
|
+
const runHandler = (index = 0) => {
|
|
807
|
+
const response = this._customizeResponse(req, res);
|
|
808
|
+
const request = req;
|
|
809
|
+
const body = request.body;
|
|
810
|
+
const files = request.files;
|
|
811
|
+
const cookies = request.cookies;
|
|
812
|
+
const headers = request.headers;
|
|
813
|
+
const query = { ...(0, url_1.parse)(String(req.url), true).query };
|
|
814
|
+
const RecordOrEmptyRecord = (data) => {
|
|
815
|
+
if (data == null)
|
|
816
|
+
return {};
|
|
817
|
+
return Object.keys(data).length ? data : {};
|
|
818
|
+
};
|
|
819
|
+
const ctx = {
|
|
820
|
+
req,
|
|
821
|
+
res: response,
|
|
822
|
+
headers: RecordOrEmptyRecord(headers),
|
|
823
|
+
params: RecordOrEmptyRecord(params),
|
|
824
|
+
query: RecordOrEmptyRecord(query),
|
|
825
|
+
body: RecordOrEmptyRecord(body),
|
|
826
|
+
files: RecordOrEmptyRecord(files),
|
|
827
|
+
cookies: RecordOrEmptyRecord(cookies)
|
|
828
|
+
};
|
|
829
|
+
if (index === handlers.length - 1) {
|
|
830
|
+
return this._wrapResponse(handlers[index].bind(handlers[index]))(ctx, this._nextFunction(ctx));
|
|
831
|
+
}
|
|
832
|
+
return handlers[index](ctx, () => {
|
|
833
|
+
return runHandler(index + 1);
|
|
834
|
+
});
|
|
835
|
+
};
|
|
836
|
+
try {
|
|
837
|
+
runHandler();
|
|
838
|
+
}
|
|
839
|
+
catch (err) {
|
|
840
|
+
const ctx = {
|
|
841
|
+
req,
|
|
842
|
+
res: this._customizeResponse(req, res),
|
|
843
|
+
params: Object.keys(params).length ? params : {},
|
|
844
|
+
headers: {},
|
|
845
|
+
query: {},
|
|
846
|
+
body: {},
|
|
847
|
+
files: {},
|
|
848
|
+
cookies: {}
|
|
849
|
+
};
|
|
850
|
+
return this._nextFunction(ctx)(err);
|
|
851
|
+
}
|
|
852
|
+
};
|
|
853
|
+
};
|
|
851
854
|
_wrapResponse(handler) {
|
|
852
855
|
return (ctx, next) => {
|
|
853
856
|
Promise.resolve(handler(ctx, next))
|
|
@@ -895,19 +898,17 @@ class Spear {
|
|
|
895
898
|
});
|
|
896
899
|
};
|
|
897
900
|
}
|
|
898
|
-
_createServer() {
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
return this._router.lookup(req, res);
|
|
904
|
-
});
|
|
905
|
-
server.timeout = 0;
|
|
906
|
-
server.keepAliveTimeout = 0;
|
|
907
|
-
server.headersTimeout = 0;
|
|
908
|
-
server.requestTimeout = 0;
|
|
909
|
-
return server;
|
|
901
|
+
async _createServer() {
|
|
902
|
+
await this._registerMiddlewares();
|
|
903
|
+
await this._registerControllers();
|
|
904
|
+
const server = http_1.default.createServer((req, res) => {
|
|
905
|
+
return this._router.lookup(req, res);
|
|
910
906
|
});
|
|
907
|
+
server.timeout = 0;
|
|
908
|
+
server.keepAliveTimeout = 0;
|
|
909
|
+
server.headersTimeout = 0;
|
|
910
|
+
server.requestTimeout = 0;
|
|
911
|
+
return server;
|
|
911
912
|
}
|
|
912
913
|
_normalizePath(...paths) {
|
|
913
914
|
const path = paths
|
|
@@ -920,7 +921,11 @@ class Spear {
|
|
|
920
921
|
_swaggerHandler() {
|
|
921
922
|
const routes = this.routers
|
|
922
923
|
.routes.filter(r => ["GET", "POST", "PUT", "PATCH", "DELETE"].includes(r.method));
|
|
923
|
-
const { path, html, staticSwaggerHandler, staticUrl } = this._parser.swagger(
|
|
924
|
+
const { path, html, staticSwaggerHandler, staticUrl } = this._parser.swagger({
|
|
925
|
+
...this._swagger,
|
|
926
|
+
options: this._swaggerAdditional,
|
|
927
|
+
routes
|
|
928
|
+
});
|
|
924
929
|
this._router.get(staticUrl, staticSwaggerHandler);
|
|
925
930
|
this._router.get(String(path), (req, res) => {
|
|
926
931
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|