web_api_base 3.6.8 → 3.7.1

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.
Files changed (65) hide show
  1. package/dist/Application.d.ts +24 -24
  2. package/dist/Application.js +449 -421
  3. package/dist/Application.js.map +1 -1
  4. package/dist/ApplicationConfiguration.d.ts +18 -18
  5. package/dist/ApplicationConfiguration.js +126 -126
  6. package/dist/bin/CreateApplication.d.ts +1 -1
  7. package/dist/bin/CreateApplication.js +16 -16
  8. package/dist/bin/CreateController.d.ts +1 -1
  9. package/dist/bin/CreateController.js +21 -21
  10. package/dist/controllers/base/ControllerBase.d.ts +19 -19
  11. package/dist/controllers/base/ControllerBase.js +46 -46
  12. package/dist/decorators/controllers/ControllerDecorators.d.ts +50 -46
  13. package/dist/decorators/controllers/ControllerDecorators.js +172 -166
  14. package/dist/decorators/controllers/ControllerDecorators.js.map +1 -1
  15. package/dist/decorators/documentation/DocumentationDecorators.d.ts +17 -17
  16. package/dist/decorators/documentation/DocumentationDecorators.js +38 -38
  17. package/dist/decorators/validations/ValidationDecorators.d.ts +53 -53
  18. package/dist/decorators/validations/ValidationDecorators.js +180 -180
  19. package/dist/decorators/validations/ValidationDecorators.js.map +1 -1
  20. package/dist/dependencyInjection/DependecyService.d.ts +28 -28
  21. package/dist/dependencyInjection/DependecyService.js +135 -135
  22. package/dist/dependencyInjection/DependecyService.js.map +1 -1
  23. package/dist/dependencyInjection/IDIContext.d.ts +7 -7
  24. package/dist/dependencyInjection/IDIContext.js +2 -2
  25. package/dist/documentation/CSS.d.ts +6 -6
  26. package/dist/documentation/CSS.js +18 -18
  27. package/dist/documentation/CSS.js.map +1 -1
  28. package/dist/documentation/Documentation.d.ts +7 -7
  29. package/dist/documentation/Documentation.js +80 -80
  30. package/dist/documentation/HTML.d.ts +4 -4
  31. package/dist/documentation/HTML.js +13 -13
  32. package/dist/documentation/HTML.js.map +1 -1
  33. package/dist/documentation/JS.d.ts +5 -5
  34. package/dist/documentation/JS.js +36 -34
  35. package/dist/documentation/JS.js.map +1 -1
  36. package/dist/enums/httpVerbs/HttpVerbs.d.ts +6 -6
  37. package/dist/enums/httpVerbs/HttpVerbs.js +10 -10
  38. package/dist/enums/httpVerbs/HttpVerbs.js.map +1 -1
  39. package/dist/exceptions/ArgumentNullException.d.ts +3 -3
  40. package/dist/exceptions/ArgumentNullException.js +9 -9
  41. package/dist/exceptions/ControllerLoadException.d.ts +3 -3
  42. package/dist/exceptions/ControllerLoadException.js +9 -9
  43. package/dist/exceptions/Exception.d.ts +4 -4
  44. package/dist/exceptions/Exception.js +9 -9
  45. package/dist/exceptions/FindDependencyException.d.ts +3 -3
  46. package/dist/exceptions/FindDependencyException.js +9 -9
  47. package/dist/index.d.ts +47 -45
  48. package/dist/index.js +155 -147
  49. package/dist/index.js.map +1 -1
  50. package/dist/interfaces/IApplication.d.ts +13 -13
  51. package/dist/interfaces/IApplication.js +2 -2
  52. package/dist/interfaces/IApplicationConfiguration.d.ts +12 -12
  53. package/dist/interfaces/IApplicationConfiguration.js +2 -2
  54. package/dist/interfaces/IController.d.ts +5 -5
  55. package/dist/interfaces/IController.js +2 -2
  56. package/dist/metadata/FunctionAnalizer.d.ts +8 -8
  57. package/dist/metadata/FunctionAnalizer.js +22 -22
  58. package/dist/metadata/OwnMetaDataContainer.d.ts +12 -12
  59. package/dist/metadata/OwnMetaDataContainer.js +32 -32
  60. package/dist/metadata/OwnMetaDataContainer.js.map +1 -1
  61. package/dist/metadata/Type.d.ts +4 -4
  62. package/dist/metadata/Type.js +36 -36
  63. package/dist/midlewares/IMidleware.d.ts +19 -19
  64. package/dist/midlewares/IMidleware.js +2 -2
  65. package/package.json +8 -11
@@ -1,422 +1,450 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || function (mod) {
19
- if (mod && mod.__esModule) return mod;
20
- var result = {};
21
- if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
- __setModuleDefault(result, mod);
23
- return result;
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
- var __importDefault = (this && this.__importDefault) || function (mod) {
35
- return (mod && mod.__esModule) ? mod : { "default": mod };
36
- };
37
- Object.defineProperty(exports, "__esModule", { value: true });
38
- const express_1 = __importDefault(require("express"));
39
- const ApplicationConfiguration_1 = __importDefault(require("./ApplicationConfiguration"));
40
- const ControllerDecorators_1 = __importDefault(require("./decorators/controllers/ControllerDecorators"));
41
- const DependecyService_1 = __importDefault(require("./dependencyInjection/DependecyService"));
42
- const HttpVerbs_1 = require("./enums/httpVerbs/HttpVerbs");
43
- const fs_1 = __importDefault(require("fs"));
44
- const path_1 = __importDefault(require("path"));
45
- const ValidationDecorators_1 = __importDefault(require("./decorators/validations/ValidationDecorators"));
46
- const ControllerLoadException_1 = __importDefault(require("./exceptions/ControllerLoadException"));
47
- const Exception_1 = __importDefault(require("./exceptions/Exception"));
48
- const Documentation_1 = __importDefault(require("./documentation/Documentation"));
49
- class Application {
50
- constructor() {
51
- this._createdControllers = [];
52
- this.ApplicationConfiguration = new ApplicationConfiguration_1.default();
53
- this.Express = (0, express_1.default)();
54
- }
55
- StartAsync() {
56
- return __awaiter(this, void 0, void 0, function* () {
57
- yield this.ApplicationConfiguration.LoadAsync();
58
- Application.Configurations = this.ApplicationConfiguration;
59
- this.Express.use(express_1.default.json({ limit: 50 * 1024 * 1024 }));
60
- yield this.ConfigureAsync(this.ApplicationConfiguration);
61
- yield this.ApplicationConfiguration.SaveAsync();
62
- this.Express.listen(this.ApplicationConfiguration.Port, this.ApplicationConfiguration.Host, () => {
63
- console.log(`Application running on ${this.ApplicationConfiguration.Host}:${this.ApplicationConfiguration.Port}`);
64
- });
65
- });
66
- }
67
- UseCors() {
68
- this.Express.use(require('cors')());
69
- }
70
- GetIgnoredPaths() {
71
- return [
72
- ".git",
73
- ".vscode",
74
- "coverage",
75
- "node_modules"
76
- ];
77
- }
78
- TryFindControllerFolder(path) {
79
- if (this.GetIgnoredPaths().filter(s => path.endsWith(s)).length > 0)
80
- return undefined;
81
- if (path.indexOf("node_modules") > -1)
82
- return undefined;
83
- if (!fs_1.default.existsSync(path))
84
- return undefined;
85
- if (fs_1.default.readdirSync(path).filter(s => s.toLowerCase().endsWith("controller.js")).length > 0)
86
- return path;
87
- let folder = fs_1.default.readdirSync(path).filter(s => !fs_1.default.lstatSync(path_1.default.join(path, s)).isFile());
88
- if (folder.length == 0)
89
- return undefined;
90
- for (let f of folder) {
91
- let find = this.TryFindControllerFolder(path_1.default.join(path, f));
92
- if (find && find.toLowerCase().endsWith("controllers"))
93
- return find;
94
- }
95
- return undefined;
96
- }
97
- UseControllersAsync(root) {
98
- return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
99
- let controllersPath = this.TryFindControllerFolder(path_1.default.join(root !== null && root !== void 0 ? root : this.ApplicationConfiguration.RootPath, "controllers"));
100
- if (!controllersPath)
101
- controllersPath = this.TryFindControllerFolder(root !== null && root !== void 0 ? root : this.ApplicationConfiguration.RootPath);
102
- if (!controllersPath || !fs_1.default.existsSync(controllersPath))
103
- return;
104
- console.debug(`reading controllers in ${controllersPath}`);
105
- let files = fs_1.default.readdirSync(controllersPath).filter(s => s.toLocaleLowerCase().endsWith("controller.js"));
106
- for (let controllerFile of files) {
107
- let controllerModule = yield Promise.resolve().then(() => __importStar(require(path_1.default.join(controllersPath, controllerFile))));
108
- let controllerClass = undefined;
109
- if (controllerModule.default == undefined) {
110
- for (let c in controllerModule) {
111
- if (c.toLocaleLowerCase().endsWith("controller")) {
112
- controllerClass = controllerModule[c];
113
- }
114
- }
115
- }
116
- else
117
- controllerClass = controllerModule.default;
118
- if (controllerClass == undefined)
119
- throw new ControllerLoadException_1.default(`Can find any controller from file : ${controllerFile}`);
120
- let controller = Reflect.construct(controllerClass.prototype.constructor, []);
121
- if (controller != undefined && controller != null) {
122
- this.AppendController(controllerClass.prototype.constructor);
123
- }
124
- else {
125
- throw new ControllerLoadException_1.default(`Can not load ${controllerClass.name} controller from file : ${controllerFile}`);
126
- }
127
- }
128
- resolve();
129
- }));
130
- }
131
- AppendController(ctor) {
132
- let empty = new ctor();
133
- let methods = Reflect.ownKeys(empty.constructor.prototype).filter(m => {
134
- return typeof empty[m] == "function";
135
- });
136
- let route = ControllerDecorators_1.default.GetRoute(empty);
137
- let validateBody = ControllerDecorators_1.default.IsToValidate(empty);
138
- if (!route)
139
- return;
140
- this._createdControllers.push(ctor);
141
- for (let method of methods) {
142
- let action = ControllerDecorators_1.default.GetAction(empty, method.toString());
143
- if (!action) {
144
- continue;
145
- }
146
- let verb = ControllerDecorators_1.default.GetVerb(empty, method.toString());
147
- let fromBody = ControllerDecorators_1.default.GetFromBodyArgs(empty.constructor, method.toString());
148
- let fromQuery = ControllerDecorators_1.default.GetFromQueryArgs(empty.constructor, method.toString());
149
- if (!verb)
150
- verb = HttpVerbs_1.HTTPVerbs.GET;
151
- console.debug("appended : ", verb, `${route}${action}`);
152
- this.Express[verb.toString().toLowerCase()](`${route}${action}`, (request, response) => {
153
- let midlewares = ControllerDecorators_1.default.GetMidlewares(empty).reverse();
154
- midlewares.push(...ControllerDecorators_1.default.GetBefores(empty, method.toString()).reverse());
155
- let afters = ControllerDecorators_1.default.GetMidlewaresAfter(empty).reverse();
156
- afters.push(...ControllerDecorators_1.default.GetAfters(empty, method.toString()).reverse());
157
- let handler = (context) => {
158
- var _a;
159
- let params = [];
160
- let ts = (_a = Reflect.getMetadata("design:paramtypes", empty, method.toString())) !== null && _a !== void 0 ? _a : Reflect.getMetadata("design:paramtypes", empty.constructor, method.toString());
161
- let fromBodyParams = [];
162
- if (fromBody.length > 0) {
163
- fromBody.sort((a, b) => a.Index - b.Index).forEach(f => {
164
- let obj = undefined;
165
- if (!f.Field || f.Type.name == "Object")
166
- obj = request.body;
167
- else
168
- obj = request.body[f.Field];
169
- if (["string", "number", "boolean", "bigint"].filter(s => s == ts[f.Index].name.toLocaleLowerCase()).length == 0) {
170
- try {
171
- obj.__proto__ = ts[f.Index];
172
- }
173
- catch (_a) { }
174
- if (f.Type.name == "Object") {
175
- fromBodyParams.push(obj);
176
- params[f.Index] = obj;
177
- }
178
- else {
179
- let t = Reflect.construct(ts[f.Index], []);
180
- Object.assign(t, obj);
181
- fromBodyParams.push(t);
182
- params[f.Index] = t;
183
- }
184
- }
185
- else {
186
- if (obj && obj.indexOf('"') == 0 && obj.lastIndexOf('"') == obj.length - 1)
187
- obj = obj.substring(1, obj.length - 1);
188
- if (obj && ts[f.Index].name.toLocaleLowerCase() == "number") {
189
- let number = Number.parseFloat(obj.toString());
190
- if (number != Number.NaN) {
191
- fromBodyParams.push(number);
192
- params[f.Index] = number;
193
- }
194
- }
195
- else if (obj && ts[f.Index].name.toLocaleLowerCase() == "string") {
196
- fromBodyParams.push(obj.toString());
197
- params[f.Index] = obj.toString();
198
- }
199
- else if (obj && ts[f.Index].name.toLocaleLowerCase() == "date") {
200
- try {
201
- fromBodyParams.push(new Date(obj));
202
- params[f.Index] = new Date(obj);
203
- }
204
- catch (_b) { }
205
- }
206
- else {
207
- fromBodyParams.push(obj);
208
- params[f.Index] = obj;
209
- }
210
- }
211
- });
212
- }
213
- let fromQueryParams = [];
214
- if (fromQuery.length > 0) {
215
- fromQuery.sort((a, b) => a.Index - b.Index).forEach((f, j) => {
216
- var _a;
217
- let obj;
218
- obj = (_a = request.query[f.Field]) === null || _a === void 0 ? void 0 : _a.toString();
219
- if (obj && obj.indexOf('"') == 0 && obj.lastIndexOf('"') == obj.length - 1)
220
- obj = obj.substring(1, obj.length - 1);
221
- if (obj && f.Type.name.toLocaleLowerCase() == "number") {
222
- let number = Number.parseFloat(obj.toString());
223
- if (number != Number.NaN) {
224
- fromQueryParams.push(number);
225
- params[f.Index] = number;
226
- }
227
- }
228
- else if (obj && f.Type.name.toLocaleLowerCase() == "string") {
229
- fromQueryParams.push(obj.toString());
230
- params[f.Index] = obj.toString();
231
- }
232
- else if (obj && f.Type.name.toLocaleLowerCase() == "date") {
233
- try {
234
- fromQueryParams.push(new Date(obj));
235
- params[f.Index] = new Date(obj);
236
- }
237
- catch (_b) { }
238
- }
239
- else {
240
- fromQueryParams.push(obj);
241
- params[f.Index] = obj;
242
- }
243
- });
244
- }
245
- if (params.length > 0) {
246
- if (validateBody) {
247
- let erros = [];
248
- if (fromBody.length > fromBodyParams.filter(s => s != undefined).length || (fromBody.length > 0 && request.headers["content-length"] == '0')) {
249
- response.status(400);
250
- response.json({
251
- Message: "Model binding fail",
252
- Detailts: ["Some expected body parameter was not provided"]
253
- });
254
- return;
255
- }
256
- if (fromQuery.length > fromQueryParams.filter(s => s != undefined).length) {
257
- response.status(400);
258
- response.json({
259
- Message: "Model binding fail",
260
- Detailts: ["Some expected url query string parameter was not provided"]
261
- });
262
- return;
263
- }
264
- for (let a of fromBodyParams) {
265
- erros.push(...ValidationDecorators_1.default.Validate(a).map(s => s.Message));
266
- }
267
- if (erros.length > 0) {
268
- response.status(400);
269
- response.json({
270
- Message: "Validation fail",
271
- Detailts: erros
272
- });
273
- return;
274
- }
275
- }
276
- }
277
- let controller = DependecyService_1.default.ResolveCtor(empty.constructor);
278
- if (controller == undefined)
279
- controller = new ctor();
280
- try {
281
- DependecyService_1.default.CheckForDependenciesAndResolve(controller);
282
- }
283
- catch (err) {
284
- this.CallErrorHandler(request, response, this.CastToExpection(err));
285
- }
286
- controller.Request = context.Request;
287
- controller.Response = context.Response;
288
- try {
289
- let exceutionTask = controller[method](...params);
290
- if (exceutionTask instanceof Promise) {
291
- exceutionTask.then(c => {
292
- for (let afterHandler of afters) {
293
- afterHandler({
294
- Request: request,
295
- Response: response,
296
- Result: exceutionTask
297
- });
298
- }
299
- }).catch(err => {
300
- for (let afterHandler of afters) {
301
- afterHandler({
302
- Exception: this.CastToExpection(err),
303
- Request: request,
304
- Response: response
305
- });
306
- }
307
- if (afters.length == 0)
308
- this.CallErrorHandler(request, response, this.CastToExpection(err));
309
- });
310
- }
311
- else {
312
- for (let afterHandler of afters) {
313
- try {
314
- afterHandler({
315
- Request: request,
316
- Response: response,
317
- Result: exceutionTask
318
- });
319
- }
320
- catch (err) {
321
- this.CallErrorHandler(request, response, this.CastToExpection(err));
322
- }
323
- }
324
- }
325
- }
326
- catch (err) {
327
- for (let afterHandler of afters) {
328
- try {
329
- afterHandler({
330
- Exception: this.CastToExpection(err),
331
- Request: request,
332
- Response: response
333
- });
334
- }
335
- catch (err) {
336
- this.CallErrorHandler(request, response, this.CastToExpection(err));
337
- }
338
- }
339
- if (afters.length == 0)
340
- this.CallErrorHandler(request, response, this.CastToExpection(err));
341
- }
342
- };
343
- if (midlewares && midlewares.length > 0) {
344
- let httpRequestContexts = [];
345
- let pipeline = [];
346
- for (let i = 0; i <= midlewares.length; i++) {
347
- httpRequestContexts.push({
348
- Request: request,
349
- Response: response,
350
- Next: () => { }
351
- });
352
- }
353
- for (let i = 0; i < httpRequestContexts.length; i++) {
354
- let box = {
355
- v: i
356
- };
357
- pipeline.push({
358
- Execute: () => {
359
- pipeline.length - 1 == box.v ? handler(httpRequestContexts[box.v]) : midlewares[box.v](httpRequestContexts[box.v]);
360
- }
361
- });
362
- }
363
- for (let i = 0; i < pipeline.length; i++) {
364
- httpRequestContexts[i].Next = i == pipeline.length - 1 ? () => { } : () => pipeline[i + 1].Execute();
365
- }
366
- pipeline[0].Execute();
367
- }
368
- else {
369
- handler({
370
- Request: request,
371
- Response: response,
372
- Next: () => { }
373
- });
374
- }
375
- });
376
- }
377
- }
378
- CreateDocumentation() {
379
- new Documentation_1.default().CreateDocumentation(this._createdControllers, this.Express);
380
- }
381
- CastToExpection(err) {
382
- let ex;
383
- if (err instanceof Exception_1.default)
384
- ex = err;
385
- else {
386
- ex = new Exception_1.default(err.message);
387
- ex.stack = err.stack;
388
- }
389
- return ex;
390
- }
391
- CallErrorHandler(request, response, exception) {
392
- let defaultHandler = (request, response, exception) => {
393
- try {
394
- response.status(500);
395
- response.json(exception);
396
- }
397
- catch (err) {
398
- console.log("Error while trying handle the error");
399
- console.log(err);
400
- }
401
- finally {
402
- console.log("Inner exception");
403
- console.log(exception);
404
- }
405
- };
406
- if (this.ApplicationThreadExeptionHandler != undefined) {
407
- try {
408
- this.ApplicationThreadExeptionHandler(request, response, this.CastToExpection(exception));
409
- }
410
- catch (err) {
411
- console.log("Error while trying handle the error with custom delegate");
412
- console.log(err);
413
- defaultHandler(request, response, this.CastToExpection(err));
414
- }
415
- }
416
- else {
417
- defaultHandler(request, response, this.CastToExpection(exception));
418
- }
419
- }
420
- }
421
- exports.default = Application;
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
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
+ var __importDefault = (this && this.__importDefault) || function (mod) {
35
+ return (mod && mod.__esModule) ? mod : { "default": mod };
36
+ };
37
+ Object.defineProperty(exports, "__esModule", { value: true });
38
+ const express_1 = __importDefault(require("express"));
39
+ const ApplicationConfiguration_1 = __importDefault(require("./ApplicationConfiguration"));
40
+ const ControllerDecorators_1 = __importDefault(require("./decorators/controllers/ControllerDecorators"));
41
+ const DependecyService_1 = __importDefault(require("./dependencyInjection/DependecyService"));
42
+ const HttpVerbs_1 = require("./enums/httpVerbs/HttpVerbs");
43
+ const fs_1 = __importDefault(require("fs"));
44
+ const path_1 = __importDefault(require("path"));
45
+ const ValidationDecorators_1 = __importDefault(require("./decorators/validations/ValidationDecorators"));
46
+ const ControllerLoadException_1 = __importDefault(require("./exceptions/ControllerLoadException"));
47
+ const Exception_1 = __importDefault(require("./exceptions/Exception"));
48
+ const Documentation_1 = __importDefault(require("./documentation/Documentation"));
49
+ class Application {
50
+ constructor() {
51
+ this._createdControllers = [];
52
+ this.ApplicationConfiguration = new ApplicationConfiguration_1.default();
53
+ this.Express = (0, express_1.default)();
54
+ }
55
+ StartAsync() {
56
+ return __awaiter(this, void 0, void 0, function* () {
57
+ yield this.ApplicationConfiguration.LoadAsync();
58
+ Application.Configurations = this.ApplicationConfiguration;
59
+ this.Express.use(express_1.default.json({ limit: 50 * 1024 * 1024 }));
60
+ yield this.ConfigureAsync(this.ApplicationConfiguration);
61
+ yield this.ApplicationConfiguration.SaveAsync();
62
+ this.Express.listen(this.ApplicationConfiguration.Port, this.ApplicationConfiguration.Host, () => {
63
+ console.log(`Application running on ${this.ApplicationConfiguration.Host}:${this.ApplicationConfiguration.Port}`);
64
+ });
65
+ });
66
+ }
67
+ UseCors() {
68
+ this.Express.use(require('cors')());
69
+ }
70
+ GetIgnoredPaths() {
71
+ return [
72
+ ".git",
73
+ ".vscode",
74
+ "coverage",
75
+ "node_modules"
76
+ ];
77
+ }
78
+ TryFindControllerFolder(path) {
79
+ if (this.GetIgnoredPaths().filter(s => path.endsWith(s)).length > 0)
80
+ return undefined;
81
+ if (path.indexOf("node_modules") > -1)
82
+ return undefined;
83
+ if (!fs_1.default.existsSync(path))
84
+ return undefined;
85
+ if (fs_1.default.readdirSync(path).filter(s => s.toLowerCase().endsWith("controller.js")).length > 0)
86
+ return path;
87
+ let folder = fs_1.default.readdirSync(path).filter(s => !fs_1.default.lstatSync(path_1.default.join(path, s)).isFile());
88
+ if (folder.length == 0)
89
+ return undefined;
90
+ for (let f of folder) {
91
+ let find = this.TryFindControllerFolder(path_1.default.join(path, f));
92
+ if (find && find.toLowerCase().endsWith("controllers"))
93
+ return find;
94
+ }
95
+ return undefined;
96
+ }
97
+ UseControllersAsync(root) {
98
+ return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () {
99
+ let controllersPath = this.TryFindControllerFolder(path_1.default.join(root !== null && root !== void 0 ? root : this.ApplicationConfiguration.RootPath, "controllers"));
100
+ if (!controllersPath)
101
+ controllersPath = this.TryFindControllerFolder(root !== null && root !== void 0 ? root : this.ApplicationConfiguration.RootPath);
102
+ if (!controllersPath || !fs_1.default.existsSync(controllersPath))
103
+ return;
104
+ console.debug(`reading controllers in ${controllersPath}`);
105
+ let files = fs_1.default.readdirSync(controllersPath).filter(s => s.toLowerCase().endsWith("controller.js"));
106
+ for (let controllerFile of files) {
107
+ let controllerModule = yield Promise.resolve(`${path_1.default.join(controllersPath, controllerFile)}`).then(s => __importStar(require(s)));
108
+ let controllerClass = undefined;
109
+ if (controllerModule.default == undefined) {
110
+ for (let c in controllerModule) {
111
+ if (c.toLowerCase().endsWith("controller")) {
112
+ controllerClass = controllerModule[c];
113
+ }
114
+ }
115
+ }
116
+ else
117
+ controllerClass = controllerModule.default;
118
+ if (controllerClass == undefined)
119
+ throw new ControllerLoadException_1.default(`Can find any controller from file : ${controllerFile}`);
120
+ let controller = Reflect.construct(controllerClass.prototype.constructor, []);
121
+ if (controller != undefined && controller != null) {
122
+ this.AppendController(controllerClass.prototype.constructor);
123
+ }
124
+ else {
125
+ throw new ControllerLoadException_1.default(`Can not load ${controllerClass.name} controller from file : ${controllerFile}`);
126
+ }
127
+ }
128
+ resolve();
129
+ }));
130
+ }
131
+ AppendController(ctor) {
132
+ let empty = new ctor();
133
+ let methods = Reflect.ownKeys(empty.constructor.prototype).filter(m => {
134
+ return typeof empty[m] == "function";
135
+ });
136
+ let route = ControllerDecorators_1.default.GetRoute(empty);
137
+ let validateBody = ControllerDecorators_1.default.IsToValidate(empty);
138
+ if (!route)
139
+ return;
140
+ this._createdControllers.push(ctor);
141
+ for (let method of methods) {
142
+ let action = ControllerDecorators_1.default.GetAction(empty, method.toString());
143
+ if (!action) {
144
+ continue;
145
+ }
146
+ let verb = ControllerDecorators_1.default.GetVerb(empty, method.toString());
147
+ let fromBody = ControllerDecorators_1.default.GetFromBodyArgs(empty.constructor, method.toString());
148
+ let fromQuery = ControllerDecorators_1.default.GetFromQueryArgs(empty.constructor, method.toString());
149
+ if (!verb)
150
+ verb = HttpVerbs_1.HTTPVerbs.GET;
151
+ console.debug("appended : ", verb, `${route}${action}`);
152
+ this.Express[verb.toString().toLowerCase()](`${route}${action}`, (request, response) => {
153
+ let midlewares = ControllerDecorators_1.default.GetMidlewares(empty).reverse();
154
+ midlewares.push(...ControllerDecorators_1.default.GetBefores(empty, method.toString()).reverse());
155
+ let afters = ControllerDecorators_1.default.GetMidlewaresAfter(empty).reverse();
156
+ afters.push(...ControllerDecorators_1.default.GetAfters(empty, method.toString()).reverse());
157
+ let handler = (context) => {
158
+ var _a;
159
+ let params = [];
160
+ let ts = (_a = Reflect.getMetadata("design:paramtypes", empty, method.toString())) !== null && _a !== void 0 ? _a : Reflect.getMetadata("design:paramtypes", empty.constructor, method.toString());
161
+ let fromBodyParams = [];
162
+ if (fromBody.length > 0) {
163
+ fromBody.sort((a, b) => a.Index - b.Index).forEach(f => {
164
+ let obj = undefined;
165
+ if (!f.Field || f.Type.name == "Object")
166
+ obj = request.body;
167
+ else
168
+ obj = request.body[f.Field];
169
+ if (["string", "number", "boolean", "bigint"].filter(s => s == ts[f.Index].name.toLowerCase()).length == 0) {
170
+ try {
171
+ obj.__proto__ = ts[f.Index];
172
+ }
173
+ catch (_a) { }
174
+ if (f.Type.name == "Object") {
175
+ fromBodyParams.push(obj);
176
+ params[f.Index] = obj;
177
+ }
178
+ else {
179
+ let t = Reflect.construct(ts[f.Index], []);
180
+ Object.assign(t, obj);
181
+ fromBodyParams.push(t);
182
+ params[f.Index] = t;
183
+ }
184
+ }
185
+ else {
186
+ if (obj != undefined && obj.indexOf('"') == 0 && obj.lastIndexOf('"') == obj.length - 1)
187
+ obj = obj.substring(1, obj.length - 1);
188
+ if (obj != undefined && ts[f.Index].name.toLowerCase() == "number") {
189
+ let number = Number.parseFloat(obj.toString());
190
+ if (number != Number.NaN) {
191
+ fromBodyParams.push(number);
192
+ params[f.Index] = number;
193
+ }
194
+ }
195
+ else if (obj != undefined && ts[f.Index].name.toLowerCase() == "string") {
196
+ fromBodyParams.push(obj.toString());
197
+ params[f.Index] = obj.toString();
198
+ }
199
+ else if (obj != undefined && ts[f.Index].name.toLowerCase() == "date") {
200
+ try {
201
+ fromBodyParams.push(new Date(obj));
202
+ params[f.Index] = new Date(obj);
203
+ }
204
+ catch (_b) { }
205
+ }
206
+ else {
207
+ fromBodyParams.push(obj);
208
+ params[f.Index] = obj;
209
+ }
210
+ }
211
+ });
212
+ }
213
+ let fromQueryParams = [];
214
+ if (fromQuery.length > 0) {
215
+ fromQuery.sort((a, b) => a.Index - b.Index).forEach((f, j) => {
216
+ var _a;
217
+ let obj;
218
+ obj = (_a = request.query[f.Field]) === null || _a === void 0 ? void 0 : _a.toString();
219
+ if (obj != undefined && obj.indexOf('"') == 0 && obj.lastIndexOf('"') == obj.length - 1)
220
+ obj = obj.substring(1, obj.length - 1);
221
+ if (obj != undefined && f.Type.name.toLowerCase() == "number") {
222
+ let number = Number.parseFloat(obj.toString());
223
+ if (number != Number.NaN) {
224
+ fromQueryParams.push(number);
225
+ params[f.Index] = number;
226
+ }
227
+ }
228
+ else if (obj != undefined && f.Type.name.toLowerCase() == "string") {
229
+ fromQueryParams.push(obj.toString());
230
+ params[f.Index] = obj.toString();
231
+ }
232
+ else if (obj != undefined && f.Type.name.toLowerCase() == "date") {
233
+ try {
234
+ fromQueryParams.push(new Date(obj));
235
+ params[f.Index] = new Date(obj);
236
+ }
237
+ catch (_b) { }
238
+ }
239
+ else if (obj != undefined && f.Type.name.toLowerCase() == "boolean") {
240
+ try {
241
+ if (typeof obj != "boolean") {
242
+ let v = obj.toString().toLowerCase() == "true";
243
+ fromQueryParams.push(v);
244
+ params[f.Index] = v;
245
+ }
246
+ else {
247
+ fromQueryParams.push(obj);
248
+ params[f.Index] = obj;
249
+ }
250
+ }
251
+ catch (_c) { }
252
+ }
253
+ else {
254
+ fromQueryParams.push(obj);
255
+ params[f.Index] = obj;
256
+ }
257
+ });
258
+ }
259
+ if (validateBody) {
260
+ if (fromBody.length > 0) {
261
+ let modelBindErros = [];
262
+ for (let p of fromBody) {
263
+ if (p.Required && (params.length <= p.Index || params[p.Index] == undefined)) {
264
+ modelBindErros.push(p);
265
+ }
266
+ }
267
+ if (modelBindErros.length > 0) {
268
+ response.status(400);
269
+ response.json({
270
+ Message: "Model binding fail",
271
+ Detailts: modelBindErros.map(s => `Parameter "${s.Field}" is required`)
272
+ });
273
+ return;
274
+ }
275
+ }
276
+ if (fromQuery.length > 0) {
277
+ let modelBindErros = [];
278
+ for (let p of fromQuery) {
279
+ if (p.Required && (params.length <= p.Index || params[p.Index] == undefined)) {
280
+ modelBindErros.push(p);
281
+ }
282
+ }
283
+ if (modelBindErros.length > 0) {
284
+ response.status(400);
285
+ response.json({
286
+ Message: "Model binding fail",
287
+ Detailts: modelBindErros.map(s => `Parameter "${s.Field}" is required`)
288
+ });
289
+ return;
290
+ }
291
+ }
292
+ let validationsErrors = [];
293
+ for (let a of fromBodyParams) {
294
+ validationsErrors.push(...ValidationDecorators_1.default.Validate(a).map(s => s.Message));
295
+ }
296
+ if (validationsErrors.length > 0) {
297
+ response.status(400);
298
+ response.json({
299
+ Message: "Validation fail",
300
+ Detailts: validationsErrors
301
+ });
302
+ return;
303
+ }
304
+ }
305
+ let controller = DependecyService_1.default.ResolveCtor(empty.constructor);
306
+ if (controller == undefined)
307
+ controller = new ctor();
308
+ try {
309
+ DependecyService_1.default.CheckForDependenciesAndResolve(controller);
310
+ }
311
+ catch (err) {
312
+ this.CallErrorHandler(request, response, this.CastToExpection(err));
313
+ }
314
+ controller.Request = context.Request;
315
+ controller.Response = context.Response;
316
+ try {
317
+ let exceutionTask = controller[method](...params);
318
+ if (exceutionTask instanceof Promise) {
319
+ exceutionTask.then(c => {
320
+ for (let afterHandler of afters) {
321
+ afterHandler({
322
+ Request: request,
323
+ Response: response,
324
+ Result: exceutionTask
325
+ });
326
+ }
327
+ }).catch(err => {
328
+ for (let afterHandler of afters) {
329
+ afterHandler({
330
+ Exception: this.CastToExpection(err),
331
+ Request: request,
332
+ Response: response
333
+ });
334
+ }
335
+ if (afters.length == 0)
336
+ this.CallErrorHandler(request, response, this.CastToExpection(err));
337
+ });
338
+ }
339
+ else {
340
+ for (let afterHandler of afters) {
341
+ try {
342
+ afterHandler({
343
+ Request: request,
344
+ Response: response,
345
+ Result: exceutionTask
346
+ });
347
+ }
348
+ catch (err) {
349
+ this.CallErrorHandler(request, response, this.CastToExpection(err));
350
+ }
351
+ }
352
+ }
353
+ }
354
+ catch (err) {
355
+ for (let afterHandler of afters) {
356
+ try {
357
+ afterHandler({
358
+ Exception: this.CastToExpection(err),
359
+ Request: request,
360
+ Response: response
361
+ });
362
+ }
363
+ catch (err) {
364
+ this.CallErrorHandler(request, response, this.CastToExpection(err));
365
+ }
366
+ }
367
+ if (afters.length == 0)
368
+ this.CallErrorHandler(request, response, this.CastToExpection(err));
369
+ }
370
+ };
371
+ if (midlewares && midlewares.length > 0) {
372
+ let httpRequestContexts = [];
373
+ let pipeline = [];
374
+ for (let i = 0; i <= midlewares.length; i++) {
375
+ httpRequestContexts.push({
376
+ Request: request,
377
+ Response: response,
378
+ Next: () => { }
379
+ });
380
+ }
381
+ for (let i = 0; i < httpRequestContexts.length; i++) {
382
+ let box = {
383
+ v: i
384
+ };
385
+ pipeline.push({
386
+ Execute: () => {
387
+ pipeline.length - 1 == box.v ? handler(httpRequestContexts[box.v]) : midlewares[box.v](httpRequestContexts[box.v]);
388
+ }
389
+ });
390
+ }
391
+ for (let i = 0; i < pipeline.length; i++) {
392
+ httpRequestContexts[i].Next = i == pipeline.length - 1 ? () => { } : () => pipeline[i + 1].Execute();
393
+ }
394
+ pipeline[0].Execute();
395
+ }
396
+ else {
397
+ handler({
398
+ Request: request,
399
+ Response: response,
400
+ Next: () => { }
401
+ });
402
+ }
403
+ });
404
+ }
405
+ }
406
+ CreateDocumentation() {
407
+ new Documentation_1.default().CreateDocumentation(this._createdControllers, this.Express);
408
+ }
409
+ CastToExpection(err) {
410
+ let ex;
411
+ if (err instanceof Exception_1.default)
412
+ ex = err;
413
+ else {
414
+ ex = new Exception_1.default(err.message);
415
+ ex.stack = err.stack;
416
+ }
417
+ return ex;
418
+ }
419
+ CallErrorHandler(request, response, exception) {
420
+ let defaultHandler = (request, response, exception) => {
421
+ try {
422
+ response.status(500);
423
+ response.json(exception);
424
+ }
425
+ catch (err) {
426
+ console.log("Error while trying handle the error");
427
+ console.log(err);
428
+ }
429
+ finally {
430
+ console.log("Inner exception");
431
+ console.log(exception);
432
+ }
433
+ };
434
+ if (this.ApplicationThreadExeptionHandler != undefined) {
435
+ try {
436
+ this.ApplicationThreadExeptionHandler(request, response, this.CastToExpection(exception));
437
+ }
438
+ catch (err) {
439
+ console.log("Error while trying handle the error with custom delegate");
440
+ console.log(err);
441
+ defaultHandler(request, response, this.CastToExpection(err));
442
+ }
443
+ }
444
+ else {
445
+ defaultHandler(request, response, this.CastToExpection(exception));
446
+ }
447
+ }
448
+ }
449
+ exports.default = Application;
422
450
  //# sourceMappingURL=Application.js.map