@avleon/core 0.0.4 → 0.0.6

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 (44) hide show
  1. package/README.md +3 -0
  2. package/dist/authentication.d.ts +7 -0
  3. package/dist/authentication.js +11 -0
  4. package/dist/collection.d.ts +52 -0
  5. package/dist/collection.js +282 -0
  6. package/dist/config.d.ts +7 -8
  7. package/dist/config.js +10 -8
  8. package/dist/container.d.ts +5 -5
  9. package/dist/container.js +10 -13
  10. package/dist/controller.d.ts +2 -1
  11. package/dist/controller.js +17 -3
  12. package/dist/decorators.d.ts +2 -1
  13. package/dist/decorators.js +12 -2
  14. package/dist/environment-variables.d.ts +3 -0
  15. package/dist/environment-variables.js +33 -0
  16. package/dist/exceptions/http-exceptions.d.ts +24 -1
  17. package/dist/exceptions/http-exceptions.js +33 -2
  18. package/dist/helpers.d.ts +9 -1
  19. package/dist/helpers.js +78 -27
  20. package/dist/icore.d.ts +70 -16
  21. package/dist/icore.js +408 -135
  22. package/dist/index.d.ts +11 -6
  23. package/dist/index.js +7 -1
  24. package/dist/map-types.js +1 -2
  25. package/dist/middleware.d.ts +24 -0
  26. package/dist/middleware.js +59 -0
  27. package/dist/params.d.ts +1 -0
  28. package/dist/params.js +13 -9
  29. package/dist/queue.d.ts +30 -0
  30. package/dist/queue.js +96 -0
  31. package/dist/render.d.ts +1 -0
  32. package/dist/render.js +8 -0
  33. package/dist/response.d.ts +3 -2
  34. package/dist/response.js +9 -15
  35. package/dist/types/app-builder.interface.d.ts +9 -0
  36. package/dist/types/app-builder.interface.js +2 -0
  37. package/dist/types/application.interface.d.ts +2 -0
  38. package/dist/types/application.interface.js +2 -0
  39. package/dist/validation.d.ts +23 -0
  40. package/dist/validation.js +98 -0
  41. package/dist/validator-extend.js +2 -2
  42. package/package.json +45 -39
  43. package/dist/repository.d.ts +0 -0
  44. package/dist/repository.js +0 -1
package/dist/icore.js CHANGED
@@ -32,208 +32,481 @@ var __importStar = (this && this.__importStar) || (function () {
32
32
  return result;
33
33
  };
34
34
  })();
35
+ var __rest = (this && this.__rest) || function (s, e) {
36
+ var t = {};
37
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
38
+ t[p] = s[p];
39
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
40
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
41
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
42
+ t[p[i]] = s[p[i]];
43
+ }
44
+ return t;
45
+ };
46
+ var __asyncValues = (this && this.__asyncValues) || function (o) {
47
+ if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
48
+ var m = o[Symbol.asyncIterator], i;
49
+ return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
50
+ function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
51
+ function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
52
+ };
35
53
  var __importDefault = (this && this.__importDefault) || function (mod) {
36
54
  return (mod && mod.__esModule) ? mod : { "default": mod };
37
55
  };
38
56
  Object.defineProperty(exports, "__esModule", { value: true });
39
- exports.AppBuilder = void 0;
57
+ exports.Builder = void 0;
40
58
  const fastify_1 = __importDefault(require("fastify"));
41
59
  const typedi_1 = __importDefault(require("typedi"));
42
- const promises_1 = __importDefault(require("fs/promises")); // Use promises for asynchronous file operations
60
+ const promises_1 = __importDefault(require("fs/promises"));
43
61
  const path_1 = __importDefault(require("path"));
44
62
  const container_1 = __importStar(require("./container"));
45
63
  const helpers_1 = require("./helpers");
46
64
  const system_exception_1 = require("./exceptions/system-exception");
47
- const isTsNode = process.env.TS_NODE_DEV || process.env.TS_NODE_PROJECT || process[Symbol.for("ts-node.register.instance")];
65
+ const fs_1 = require("fs");
66
+ const exceptions_1 = require("./exceptions");
67
+ const swagger_1 = __importDefault(require("@fastify/swagger"));
68
+ const fastify_api_reference_1 = __importDefault(require("@scalar/fastify-api-reference"));
69
+ const environment_variables_1 = require("./environment-variables");
70
+ const isTsNode = process.env.TS_NODE_DEV ||
71
+ process.env.TS_NODE_PROJECT ||
72
+ process[Symbol.for("ts-node.register.instance")];
48
73
  const controllerDir = path_1.default.join(process.cwd(), isTsNode ? "./src/controllers" : "./dist/cotrollers");
49
- class _InternalApplication {
74
+ // InternalApplication
75
+ class AvleonApplication {
50
76
  constructor() {
51
77
  this.routeSet = new Set(); // Use Set for fast duplicate detection
52
78
  this.alreadyRun = false;
53
79
  this.routes = new Map();
80
+ this.middlewares = new Map();
81
+ this.rMap = new Map();
82
+ this.hasSwagger = false;
83
+ this.globalSwaggerOptions = {};
84
+ this.controllers = [];
85
+ this.authorizeMiddleware = undefined;
86
+ this.metaCache = new Map();
54
87
  this.app = (0, fastify_1.default)();
88
+ // this.app.setValidatorCompiler(() => () => true);
55
89
  }
56
90
  static getInternalApp(buildOptions) {
57
- if (!_InternalApplication.instance) {
58
- _InternalApplication.instance = new _InternalApplication();
91
+ if (!AvleonApplication.instance) {
92
+ AvleonApplication.instance = new AvleonApplication();
93
+ }
94
+ AvleonApplication.buildOptions = buildOptions;
95
+ if (buildOptions.controllers) {
96
+ }
97
+ return AvleonApplication.instance;
98
+ }
99
+ isDevelopment() {
100
+ return environment_variables_1.env["NODE_ENV"] == "development";
101
+ }
102
+ async initSwagger(options) {
103
+ const { routePrefix } = options, restOptions = __rest(options, ["routePrefix"]);
104
+ this.app.register(swagger_1.default, {
105
+ openapi: Object.assign({ openapi: "3.0.0" }, restOptions),
106
+ });
107
+ const rPrefix = routePrefix ? routePrefix : "/docs";
108
+ //import fastifyApiReference from "@scalar/fastify-api-reference";
109
+ await this.app.register(fastify_api_reference_1.default, {
110
+ routePrefix: rPrefix,
111
+ configuration: {
112
+ metaData: {
113
+ title: "Avleon Api",
114
+ ogTitle: "Avleon",
115
+ },
116
+ theme: "kepler",
117
+ favicon: "/static/favicon.png",
118
+ },
119
+ });
120
+ }
121
+ async useSwagger(options) {
122
+ this.hasSwagger = true;
123
+ this.globalSwaggerOptions = options;
124
+ }
125
+ handleMiddlewares(mclasses) {
126
+ for (const mclass of mclasses) {
127
+ const cls = typedi_1.default.get(mclass.constructor);
128
+ this.middlewares.set(mclass.name, cls);
129
+ this.app.addHook("preHandler", cls.invoke);
59
130
  }
60
- _InternalApplication.buildOptions = buildOptions;
61
- return _InternalApplication.instance;
131
+ }
132
+ executeMiddlewares(target, propertyKey) {
133
+ const classMiddlewares = Reflect.getMetadata("controller:middleware", target.constructor) || [];
134
+ const methodMiddlewares = propertyKey
135
+ ? Reflect.getMetadata("route:middleware", target, propertyKey) || []
136
+ : [];
137
+ return [...classMiddlewares, ...methodMiddlewares];
62
138
  }
63
139
  async buildController(controller) {
140
+ var _a, e_1, _b, _c;
64
141
  const ctrl = typedi_1.default.get(controller);
65
142
  const controllerMeta = Reflect.getMetadata(container_1.CONTROLLER_META_KEY, ctrl.constructor);
66
143
  if (!controllerMeta)
67
144
  return;
68
145
  const prototype = Object.getPrototypeOf(ctrl);
69
146
  const methods = Object.getOwnPropertyNames(prototype).filter((name) => name !== "constructor");
70
- for (const method of methods) {
71
- const methodMeta = Reflect.getMetadata(container_1.ROUTE_META_KEY, prototype, method);
72
- if (!methodMeta)
73
- continue;
74
- const methodmetaOptions = { method: methodMeta.method.toLowerCase(), path: (0, helpers_1.formatUrl)(controllerMeta.path + methodMeta.path) };
75
- const routeKey = `${methodmetaOptions.method}:${methodmetaOptions.path}`;
76
- if (this.routeSet.has(routeKey)) {
77
- throw new system_exception_1.SystemUseError(`Duplicate Error: Duplicate route found for methoed ${methodMeta.method}: ${methodMeta.path} in ${controller.name}`);
78
- }
79
- this.routeSet.add(routeKey);
80
- const allMeta = this._processMeta(prototype, controllerMeta, method, methodMeta);
81
- this.app.route({
82
- url: methodmetaOptions.path == "" ? "/" : methodmetaOptions.path,
83
- method: methodmetaOptions.method.toUpperCase(),
84
- preHandler: async (req, res, next) => {
85
- for (let bodyMeta of allMeta.body) {
86
- const args = await this._mapArgs(req, allMeta);
87
- if (bodyMeta.validatorClass) {
88
- const err = await (0, helpers_1.validateObjectByInstance)(bodyMeta.dataType, args[bodyMeta.index]);
89
- if (err) {
90
- console.log("Has validation error", err);
91
- return await res.code(400).send({
92
- code: 400,
93
- errorType: "ValidationError",
94
- errors: err,
95
- message: err.message
96
- });
147
+ let classMiddlewares = [];
148
+ const tag = ctrl.constructor.name.replace("Controller", "");
149
+ const swaggerControllerMeta = Reflect.getMetadata("controller:openapi", ctrl.constructor) || {};
150
+ const authClsMeata = Reflect.getMetadata(container_1.AUTHORIZATION_META_KEY, ctrl.constructor) || { authorize: false, options: undefined };
151
+ if (authClsMeata.authorize && this.authorizeMiddleware) {
152
+ this.app.addHook("preHandler", (req, res) => {
153
+ return this.authorizeMiddleware.authorize(req);
154
+ });
155
+ }
156
+ console.log("ClassMiddlware:", tag + ":", authClsMeata);
157
+ try {
158
+ for (var _d = true, methods_1 = __asyncValues(methods), methods_1_1; methods_1_1 = await methods_1.next(), _a = methods_1_1.done, !_a; _d = true) {
159
+ _c = methods_1_1.value;
160
+ _d = false;
161
+ const method = _c;
162
+ const methodMeta = Reflect.getMetadata(container_1.ROUTE_META_KEY, prototype, method);
163
+ if (!methodMeta)
164
+ continue;
165
+ const methodmetaOptions = {
166
+ method: methodMeta.method.toLowerCase(),
167
+ path: (0, helpers_1.formatUrl)(controllerMeta.path + methodMeta.path),
168
+ };
169
+ const routeKey = `${methodmetaOptions.method}:${methodmetaOptions.path}`;
170
+ if (!this.routeSet.has(routeKey)) {
171
+ this.routeSet.add(routeKey);
172
+ }
173
+ const classMiddlewares = this.executeMiddlewares(ctrl, method);
174
+ // handle openapi data
175
+ const swaggerMeta = Reflect.getMetadata("route:openapi", prototype, method) || {};
176
+ const authClsMethodMeata = Reflect.getMetadata(container_1.AUTHORIZATION_META_KEY, ctrl.constructor, method) || { authorize: false, options: undefined };
177
+ console.log(tag, ":", method, authClsMethodMeata);
178
+ // if (authClsMethodMeata.authorize && this.authorizeMiddleware) {
179
+ // this.app.addHook('preHandler', async (req, res) => {
180
+ // if (res.sent) return;
181
+ // console.log(this.authorizeMiddleware)
182
+ // const cls = container.get(this.authorizeMiddleware) as any;
183
+ // console.log(cls)
184
+ // cls.authorize(req);
185
+ // })
186
+ // }
187
+ const allMeta = this._processMeta(prototype, method);
188
+ const routePath = methodmetaOptions.path == "" ? "/" : methodmetaOptions.path;
189
+ this.app.route({
190
+ url: routePath,
191
+ method: methodmetaOptions.method.toUpperCase(),
192
+ schema: Object.assign(Object.assign(Object.assign({}, swaggerControllerMeta), swaggerMeta), { tags: [tag] }),
193
+ handler: async (req, res) => {
194
+ let reqClone = req;
195
+ if (authClsMethodMeata.authorize && this.authorizeMiddleware) {
196
+ const cls = container_1.default.get(this.authorizeMiddleware);
197
+ await cls.authorize(reqClone, authClsMethodMeata.options);
198
+ if (res.sent)
199
+ return;
200
+ }
201
+ if (classMiddlewares.length > 0) {
202
+ for (let m of classMiddlewares) {
203
+ const cls = typedi_1.default.get(m.constructor);
204
+ reqClone = (await cls.invoke(reqClone, res));
205
+ if (res.sent)
206
+ return;
97
207
  }
98
208
  }
99
- }
100
- next();
101
- },
102
- handler: async (req, res) => {
103
- const args = await this._mapArgs(req, allMeta);
104
- try {
105
- return await prototype[method].apply(ctrl, args);
106
- }
107
- catch (err) {
108
- console.error(err);
109
- return res.code(err.statusCode || 500).send({
110
- code: err.statusCode || 500,
111
- errorType: err.name || "InternalServerError",
112
- message: err.message,
113
- });
114
- }
115
- },
116
- });
209
+ const args = await this._mapArgs(reqClone, allMeta);
210
+ for (let bodyMeta of allMeta.body) {
211
+ if (bodyMeta.validatorClass) {
212
+ const err = await (0, helpers_1.validateObjectByInstance)(bodyMeta.dataType, args[bodyMeta.index]);
213
+ if (err) {
214
+ return await res.code(400).send({
215
+ code: 400,
216
+ error: "ValidationError",
217
+ errors: err,
218
+ message: err.message,
219
+ });
220
+ }
221
+ }
222
+ }
223
+ const result = await prototype[method].apply(ctrl, args);
224
+ return result;
225
+ },
226
+ });
227
+ }
228
+ }
229
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
230
+ finally {
231
+ try {
232
+ if (!_d && !_a && (_b = methods_1.return)) await _b.call(methods_1);
233
+ }
234
+ finally { if (e_1) throw e_1.error; }
117
235
  }
118
236
  }
119
237
  async _mapArgs(req, meta) {
120
- const args = [];
121
- if (meta.params.length > 0) {
122
- meta.params.forEach((param) => {
123
- const value = param.key === "all" ? req.params : req.params[param.key];
124
- args[param.index] = value;
238
+ if (!req.hasOwnProperty("_argsCache")) {
239
+ Object.defineProperty(req, "_argsCache", {
240
+ value: new Map(),
241
+ enumerable: false,
125
242
  });
126
243
  }
127
- if (meta.query.length > 0) {
128
- meta.query.forEach((q) => {
129
- const value = q.key === "all" ? req.query : req === null || req === void 0 ? void 0 : req.query[q.key];
130
- args[q.index] = value;
131
- });
244
+ const cache = req._argsCache;
245
+ const cacheKey = JSON.stringify(meta); // Faster key-based lookup
246
+ if (cache.has(cacheKey)) {
247
+ return cache.get(cacheKey);
132
248
  }
133
- if (meta.body.length > 0) {
134
- meta.body.forEach(async (body) => {
135
- args[body.index] = req.body;
136
- });
249
+ const args = meta.params.map((p) => req.params[p.key] || null);
250
+ meta.query.forEach((q) => (args[q.index] = q.key === "all" ? req.query : req.query[q.key]));
251
+ meta.body.forEach((body) => (args[body.index] = req.body));
252
+ meta.currentUser.forEach((user) => (args[user.index] = req.user));
253
+ meta.headers.forEach((header) => (args[header.index] =
254
+ header.key === "all" ? req.headers : req.headers[header.key]));
255
+ cache.set(cacheKey, args);
256
+ return args;
257
+ }
258
+ _processMeta(prototype, method) {
259
+ const cacheKey = `${prototype.constructor.name}_${method}`;
260
+ if (this.metaCache.has(cacheKey)) {
261
+ return this.metaCache.get(cacheKey);
137
262
  }
138
- if (meta.headers.length > 0) {
139
- meta.headers.forEach((header) => {
140
- const value = header.key === "all" ? req.headers : req.headers[header.key];
141
- args[header.index] = value;
142
- });
263
+ const meta = {
264
+ params: Reflect.getMetadata(container_1.PARAM_META_KEY, prototype, method) || [],
265
+ query: Reflect.getMetadata(container_1.QUERY_META_KEY, prototype, method) || [],
266
+ body: Reflect.getMetadata(container_1.REQUEST_BODY_META_KEY, prototype, method) || [],
267
+ headers: Reflect.getMetadata(container_1.REQUEST_HEADER_META_KEY, prototype, method) || [],
268
+ currentUser: Reflect.getMetadata(container_1.REQUEST_USER_META_KEY, prototype, method) || [],
269
+ // swagger: Reflect.getMetadata("route:openapi", prototype, method) || {}
270
+ };
271
+ this.metaCache.set(cacheKey, meta);
272
+ return meta;
273
+ }
274
+ async autoControllers() {
275
+ const controllers = [];
276
+ const files = await promises_1.default.readdir(controllerDir);
277
+ for (const file of files) {
278
+ if (isTsNode ? file.endsWith(".ts") : file.endsWith(".js")) {
279
+ const filePath = path_1.default.join(controllerDir, file);
280
+ const module = await Promise.resolve(`${filePath}`).then(s => __importStar(require(s)));
281
+ for (const exported of Object.values(module)) {
282
+ if (typeof exported === "function" && (0, container_1.isApiController)(exported)) {
283
+ //controllers.push(exported);
284
+ this.buildController(exported);
285
+ }
286
+ }
287
+ }
143
288
  }
144
- return args;
145
289
  }
146
- _processMeta(prototype, controllerMeta, method, methodMeta) {
147
- const paramsMetaList = Reflect.getMetadata(container_1.PARAM_META_KEY, prototype, method) || [];
148
- const queryMetaList = Reflect.getMetadata(container_1.QUERY_META_KEY, prototype, method) || [];
149
- const bodyMetaList = Reflect.getMetadata(container_1.REQUEST_BODY_META_KEY, prototype, method) || [];
150
- const headerMetaList = Reflect.getMetadata(container_1.REQUEST_HEADER_META_KEY, prototype, method) || [];
151
- return { params: paramsMetaList, query: queryMetaList, body: bodyMetaList, headers: headerMetaList };
290
+ mapControllers(controllers) {
291
+ this.controllers = controllers;
152
292
  }
153
- async mapControllers() {
154
- // const controllers = getRegisteredControllers();
155
- // await Promise.all(controllers.map((controller) => this.buildController(controller)));
156
- await this._mapControllers();
293
+ async _mapControllers() {
294
+ if (this.controllers.length > 0) {
295
+ for (let controller of this.controllers) {
296
+ if ((0, container_1.isApiController)(controller)) {
297
+ this.buildController(controller);
298
+ }
299
+ }
300
+ }
157
301
  }
158
- async mapGroup(path) {
302
+ mapControllersAuto() {
303
+ const isExists = (0, fs_1.existsSync)(controllerDir);
304
+ if (isExists) {
305
+ this.autoControllers();
306
+ }
159
307
  }
160
308
  async handleRoute(args) {
161
309
  console.log(args);
162
310
  }
163
- async mapGet(path = '', fn) {
164
- this.app.get(path, async (req, res) => {
165
- const result = await fn.apply(this, [req, res]);
166
- return res.send(result);
311
+ async mapFn(fn) {
312
+ const original = fn;
313
+ fn = function () {
314
+ console.log(arguments);
315
+ };
316
+ return fn;
317
+ }
318
+ useMiddlewares(mclasses) {
319
+ for (const mclass of mclasses) {
320
+ const cls = typedi_1.default.get(mclass);
321
+ this.middlewares.set(mclass.name, cls);
322
+ this.app.addHook("preHandler", cls.invoke);
323
+ }
324
+ }
325
+ useAuthoriztion(middleware) {
326
+ this.authorizeMiddleware = middleware;
327
+ }
328
+ _handleError(error) {
329
+ if (error instanceof exceptions_1.BaseHttpException) {
330
+ return {
331
+ code: error.code,
332
+ error: error.name,
333
+ message: (0, helpers_1.isValidJsonString)(error.message)
334
+ ? JSON.parse(error.message)
335
+ : error.message,
336
+ };
337
+ }
338
+ return {
339
+ code: 500,
340
+ error: "INTERNALERROR",
341
+ message: error.message ? error.message : "Something going wrong.",
342
+ };
343
+ }
344
+ async mapRoute(method, path = "", fn) {
345
+ await this.mapFn(fn); // Assuming mapFn is needed for all methods
346
+ this.app[method](path, async (req, res) => {
347
+ // Dynamic method call
348
+ try {
349
+ const result = await fn.apply(this, [req, res]);
350
+ if (typeof result === "object" && result !== null) {
351
+ res.json(result); // Use res.json for objects
352
+ }
353
+ else {
354
+ res.send(result); // Fallback for other types
355
+ }
356
+ }
357
+ catch (error) {
358
+ console.error(`Error in ${method} route handler:`, error);
359
+ const handledErr = this._handleError(error);
360
+ res.status(handledErr.code).send(handledErr);
361
+ }
167
362
  });
168
- /* this.handleRoute = fn.apply(this, arguments);
169
-
170
- this.routes.set(path, async (...args: any[]) => {
171
- try {
172
- const result = await fn(...args);
173
- return result;
174
- } catch (error) {
175
- console.error(`Error handling route ${path}:`, error);
176
- throw error;
177
- }
178
- }); */
179
363
  }
180
- async mapPost() { }
181
- async mapPut() { }
182
- async mapDelete() { }
183
- async _mapControllers() {
184
- const controllers = (0, container_1.getRegisteredControllers)();
185
- await Promise.all(controllers.map((controller) => this.buildController(controller)));
364
+ _routeHandler(routePath, method, fn) {
365
+ const routeKey = method + ":" + routePath;
366
+ this.rMap.set(routeKey, {
367
+ handler: fn,
368
+ middlewares: [],
369
+ schema: {},
370
+ });
371
+ this.mapFn(fn);
372
+ const route = {
373
+ useMiddleware: (middlewares) => {
374
+ const midds = Array.isArray(middlewares) ? middlewares : [middlewares];
375
+ const ms = midds.map((mclass) => {
376
+ const cls = typedi_1.default.get(mclass);
377
+ this.middlewares.set(mclass.name, cls);
378
+ return cls.invoke; // Ensure `invoke` runs in the correct context
379
+ });
380
+ const r = this.rMap.get(routeKey);
381
+ if (r) {
382
+ r.middlewares = ms; // Update middlewares array
383
+ }
384
+ return route; // Ensure chaining by returning the same route object
385
+ },
386
+ useSwagger: (options) => {
387
+ const r = this.rMap.get(routeKey);
388
+ if (r) {
389
+ r.schema = options; // Update schema
390
+ }
391
+ return route; // Ensure chaining
392
+ },
393
+ };
394
+ return route;
395
+ }
396
+ mapGet(path = "", fn) {
397
+ return this._routeHandler(path, "GET", fn);
398
+ }
399
+ mapPost(path = "", fn) {
400
+ return this._routeHandler(path, "POST", fn);
401
+ }
402
+ mapPut(path = "", fn) {
403
+ return this._routeHandler(path, "PUT", fn);
404
+ }
405
+ mapDelete(path = "", fn) {
406
+ return this._routeHandler(path, "DELETE", fn);
407
+ }
408
+ useStaticFiles(options = { path: undefined, prefix: undefined }) {
409
+ this.app.register(require("@fastify/static"), {
410
+ root: options.path ? options.path : path_1.default.join(process.cwd(), "public"),
411
+ prefix: options.prefix ? options.prefix : "/static/",
412
+ });
186
413
  }
187
414
  async run(port = 4000) {
188
415
  if (this.alreadyRun)
189
416
  throw new system_exception_1.SystemUseError("App already running");
190
417
  this.alreadyRun = true;
191
- if (_InternalApplication.buildOptions.database) {
418
+ if (AvleonApplication.buildOptions.database) {
419
+ }
420
+ //this.app.swagger();
421
+ if (this.hasSwagger) {
422
+ await this.initSwagger(this.globalSwaggerOptions);
192
423
  }
193
- ///await this._mapControllers();
424
+ await this._mapControllers();
425
+ // this.controllers.forEach(controller => {
426
+ // this.buildController(controller)
427
+ // })
428
+ this.rMap.forEach((value, key) => {
429
+ const [m, r] = key.split(":");
430
+ this.app.route({
431
+ method: m,
432
+ url: r,
433
+ schema: value.schema || {},
434
+ preHandler: value.middlewares ? value.middlewares : [],
435
+ handler: async (req, res) => {
436
+ const result = await value.handler.apply(this, [req, res]);
437
+ return result;
438
+ },
439
+ });
440
+ });
441
+ this.app.setErrorHandler(async (error, req, res) => {
442
+ const handledErr = this._handleError(error);
443
+ if (error instanceof exceptions_1.ValidationErrorException) {
444
+ return res.status(handledErr.code).send({
445
+ code: handledErr.code,
446
+ error: handledErr.error,
447
+ errors: handledErr.message,
448
+ });
449
+ }
450
+ return res.status(handledErr.code).send(handledErr);
451
+ });
452
+ await this.app.ready();
194
453
  await this.app.listen({ port });
195
- console.log(`Application running on port: ${port}`);
454
+ console.log(`Application running on port: 0.0.0.0:${port}`);
455
+ }
456
+ getTestApp(app) {
457
+ return this.app;
196
458
  }
197
459
  }
198
- _InternalApplication.buildOptions = {};
199
- class AppBuilder {
460
+ AvleonApplication.buildOptions = {};
461
+ // Applciation Builder
462
+ class Builder {
200
463
  constructor() {
201
464
  this.alreadyBuilt = false;
202
- this.databse = false;
465
+ this.database = false;
466
+ }
467
+ static createAppBuilder() {
468
+ if (!Builder.instance) {
469
+ Builder.instance = new Builder();
470
+ }
471
+ return Builder.instance;
203
472
  }
204
- static createBuilder() {
205
- if (!AppBuilder.instance) {
206
- AppBuilder.instance = new AppBuilder();
473
+ static creatTestAppBilder() {
474
+ if (!Builder.instance) {
475
+ Builder.instance = new Builder();
207
476
  }
208
- return AppBuilder.instance;
477
+ return Builder.instance;
209
478
  }
210
479
  async registerPlugin(plugin, options) {
211
480
  container_1.default.set(plugin, plugin.prototype);
212
481
  }
213
- async useDatabase() {
214
- this.databse = true;
482
+ async addDataSource(config) {
483
+ if (this.database) {
484
+ throw new system_exception_1.SystemUseError("Datasource already added.");
485
+ }
486
+ this.database = true;
487
+ try {
488
+ const typeorm = await Promise.resolve().then(() => __importStar(require("typeorm")));
489
+ if (!typeorm) {
490
+ throw new system_exception_1.SystemUseError("TypeOrm not installed");
491
+ }
492
+ const datasource = new typeorm.DataSource(config);
493
+ typedi_1.default.set("idatasource", datasource);
494
+ this.dataSource = datasource;
495
+ await datasource.initialize();
496
+ }
497
+ catch (error) {
498
+ console.log(error);
499
+ console.error("Database Initialize Error:", error.message);
500
+ }
215
501
  }
216
- async build() {
217
- //console.log("Hello", hello())
502
+ build() {
218
503
  if (this.alreadyBuilt)
219
504
  throw new Error("Already built");
220
505
  this.alreadyBuilt = true;
221
- const controllers = [];
222
- const files = await promises_1.default.readdir(controllerDir);
223
- for (const file of files) {
224
- if (isTsNode ? file.endsWith(".ts") : file.endsWith(".js")) {
225
- const filePath = path_1.default.join(controllerDir, file);
226
- const module = await Promise.resolve(`${filePath}`).then(s => __importStar(require(s)));
227
- for (const exported of Object.values(module)) {
228
- if (typeof exported === "function" && (0, container_1.isApiController)(exported)) {
229
- controllers.push(exported);
230
- }
231
- }
232
- }
233
- }
234
- const app = _InternalApplication.getInternalApp({ database: this.databse });
235
- controllers.forEach(container_1.registerController);
506
+ const app = AvleonApplication.getInternalApp({
507
+ database: this.database,
508
+ });
236
509
  return app;
237
510
  }
238
511
  }
239
- exports.AppBuilder = AppBuilder;
512
+ exports.Builder = Builder;
package/dist/index.d.ts CHANGED
@@ -1,10 +1,15 @@
1
- export * from './icore';
2
- export { inject } from './helpers';
1
+ export * from "./icore";
2
+ export { inject, validateRequestBody } from "./helpers";
3
3
  export * from "./decorators";
4
+ export * from "./middleware";
4
5
  export * from "./config";
5
6
  export * from "./openapi";
6
7
  export * from "./map-types";
7
- export * from './response';
8
- export * from './exceptions';
9
- export * from './validator-extend';
10
- export { default as Container } from './container';
8
+ export * from "./response";
9
+ export * from "./exceptions";
10
+ export * from "./validator-extend";
11
+ export * from "./validation";
12
+ export * from "./environment-variables";
13
+ export * from "./collection";
14
+ export * from "./queue";
15
+ export { default as Container } from "./container";