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.
@@ -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
- constructor({ controllers, middlewares, globalPrefix, logger, cluster } = {}) {
66
- this._router = (0, find_my_way_1.default)();
67
- this._parser = new parser_factory_1.ParserFactory();
68
- this._swagger = {
69
- use: false,
70
- path: '/api/docs',
71
- servers: [
72
- {
73
- url: 'http://localhost:3000'
74
- }
75
- ],
76
- tags: [],
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
- this._swaggerAdditional = [];
84
- this._errorHandler = null;
85
- this._globalMiddlewares = [];
86
- this._formatResponse = null;
87
- this._onListeners = [];
88
- this._fileUploadOptions = {
89
- limit: Infinity,
90
- tempFileDir: 'tmp',
91
- removeTempFile: {
92
- remove: false,
93
- ms: 1000 * 60 * 10
94
- }
95
- };
96
- this._wrapHandlers = (...handlers) => {
97
- return (req, res, params) => {
98
- const runHandler = (index = 0) => {
99
- const response = this._customizeResponse(req, res);
100
- const request = req;
101
- const body = request.body;
102
- const files = request.files;
103
- const cookies = request.cookies;
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
- * The 'useFileUpload' method is a middleware used to handler file uploads. It adds a file upload of incoming HTTP requests.
231
- *
232
- * @param {?Object}
233
- * @property {?number} limits
234
- * @property {?string} tempFileDir
235
- * @property {?Object} removeTempFile
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 === null || req === void 0 ? void 0 : req.headers['content-type'];
182
+ const contentType = req?.headers['content-type'];
252
183
  const isFileUpload = contentType && contentType.startsWith('multipart/form-data');
253
- const isListMethods = ['POST', 'PATCH', 'PUT', 'DELETE'].includes(String(req.method));
254
- if (!isListMethods || !isFileUpload)
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 ((req === null || req === void 0 ? void 0 : req.files) != null)
191
+ if (req?.body != null)
257
192
  return next();
258
- Promise.resolve(this._parser.files({ req, options: this._fileUploadOptions }))
193
+ Promise.resolve(this._parser.body(req))
259
194
  .then(r => {
260
- req.files = r.files;
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 'useBodyParser' method is a middleware used to parse the request body of incoming HTTP requests.
203
+ * The 'useFileUpload' method is a middleware used to handler file uploads. It adds a file upload of incoming HTTP requests.
270
204
  *
271
- * @returns {this}
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
- useBodyParser() {
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 === null || req === void 0 ? void 0 : req.headers['content-type'];
224
+ const contentType = req?.headers['content-type'];
276
225
  const isFileUpload = contentType && contentType.startsWith('multipart/form-data');
277
- if (isFileUpload)
226
+ if (req.method === 'GET') {
227
+ return next();
228
+ }
229
+ if (!isFileUpload)
278
230
  return next();
279
- if ((req === null || req === void 0 ? void 0 : req.body) != null)
231
+ if (req?.files != null)
280
232
  return next();
281
- Promise.resolve(this._parser.body(req))
233
+ Promise.resolve(this._parser.files({ req, options: this._fileUploadOptions }))
282
234
  .then(r => {
283
- req.body = r;
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 ((req === null || req === void 0 ? void 0 : req.cookies) != null)
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 !== null && path !== void 0 ? path : this._swagger.path,
332
- servers: servers !== null && servers !== void 0 ? servers : this._swagger.servers,
333
- tags: tags !== null && tags !== void 0 ? tags : this._swagger.tags,
334
- info: info !== null && info !== void 0 ? info : this._swagger.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
- var arguments_1 = arguments;
347
- return __awaiter(this, arguments, void 0, function* (port = 3000, callback) {
348
- if (arguments_1.length === 1 && typeof port === 'function') {
349
- callback = port;
350
- port = 3000;
351
- }
352
- const server = yield this._createServer();
353
- if (this._cluster != null &&
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
- var _a;
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
- return __awaiter(this, void 0, void 0, function* () {
576
- const directories = fs_1.default.readdirSync(dir, { withFileTypes: true });
577
- const files = (yield Promise.all(directories.map((directory) => {
578
- const newDir = path_1.default.resolve(String(dir), directory.name);
579
- if (pattern == null) {
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
- for (const controller of this._controllers) {
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 = (_d = Reflect.getMetadata("controllers", controller)) !== null && _d !== void 0 ? _d : '';
623
- const routers = (_e = Reflect.getMetadata("routers", controller)) !== null && _e !== void 0 ? _e : [];
624
- const swaggers = (_f = Reflect.getMetadata("swaggers", controller)) !== null && _f !== void 0 ? _f : [];
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
- Object.assign(Object.assign({}, find), { path: this._normalizePath(this._globalPrefix, prefixPath, path), method })
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
- _registerMiddlewares() {
641
- return __awaiter(this, void 0, void 0, function* () {
642
- if (this._middlewares == null)
643
- return;
644
- if (!Array.isArray(this._middlewares)) {
645
- const middlewares = yield this._import(this._middlewares.folder, this._middlewares.name);
646
- for (const file of middlewares) {
647
- const response = yield Promise.resolve(`${file}`).then(s => __importStar(require(s)));
648
- const middleware = response === null || response === void 0 ? void 0 : response.default;
649
- this.use(middleware);
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
- return;
588
+ this[method](this._normalizePath(this._globalPrefix, prefixPath, path), controllerInstance[String(handler)].bind(controllerInstance));
652
589
  }
653
- const middlewares = this._middlewares;
654
- for (const middleware of middlewares) {
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(Object.assign({}, results), res.statusCode), null, 2));
629
+ return res.end(JSON.stringify(this._formatResponse({
630
+ ...results
631
+ }, res.statusCode), null, 2));
680
632
  }
681
- return res.end(JSON.stringify(Object.assign({}, results), null, 2));
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
- var _a, _b, _c, _d, _e, _f, _g, _h;
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
- +((_d = (_c = err.response) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.statusCode) ||
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 = ((_f = (_e = err.response) === null || _e === void 0 ? void 0 : _e.data) === null || _f === void 0 ? void 0 : _f.errorMessage) ||
701
- ((_h = (_g = err.response) === null || _g === void 0 ? void 0 : _g.data) === null || _h === void 0 ? void 0 : _h.message) ||
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 !== null && message !== void 0 ? message : `The url '${req.url}' resulted in a bad request. Please review the data and try again.`;
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 !== null && message !== void 0 ? message : `The url '${req.url}' is unauthorized. Please verify.`;
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 !== null && message !== void 0 ? message : `The url '${req.url}' requires payment. Please proceed with payment.`;
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 !== null && message !== void 0 ? message : `The url '${req.url}' is forbidden. Please check the permissions or access rights.`;
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 !== null && message !== void 0 ? message : `The url '${req.url}' was not found. Please re-check the your url again`;
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 !== null && message !== void 0 ? message : `The url '${req.url}' resulted in a server error. Please investigate.`;
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 === null || err === void 0 ? void 0 : err.message,
783
+ message: err?.message,
831
784
  }, ctx.res.statusCode), null, 2));
832
785
  }
833
786
  return ctx.res.end(JSON.stringify({
834
- message: err === null || err === void 0 ? void 0 : err.message,
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
- return __awaiter(this, void 0, void 0, function* () {
900
- yield this._registerMiddlewares();
901
- yield this._registerControllers();
902
- const server = http_1.default.createServer((req, res) => {
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(Object.assign(Object.assign({}, this._swagger), { options: this._swaggerAdditional, routes }));
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' });