@avleon/core 0.0.7 → 0.0.10

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 (46) hide show
  1. package/dist/authentication.d.ts +6 -0
  2. package/dist/authentication.js +7 -2
  3. package/dist/collection.js +7 -0
  4. package/dist/config.d.ts +14 -27
  5. package/dist/config.js +21 -9
  6. package/dist/container.d.ts +8 -0
  7. package/dist/container.js +9 -1
  8. package/dist/controller.js +6 -0
  9. package/dist/decorators.d.ts +6 -0
  10. package/dist/decorators.js +6 -0
  11. package/dist/environment-variables.d.ts +12 -3
  12. package/dist/environment-variables.js +46 -23
  13. package/dist/exceptions/http-exceptions.d.ts +6 -0
  14. package/dist/exceptions/http-exceptions.js +6 -0
  15. package/dist/exceptions/system-exception.d.ts +9 -0
  16. package/dist/exceptions/system-exception.js +7 -1
  17. package/dist/file-storage.d.ts +17 -0
  18. package/dist/file-storage.js +153 -0
  19. package/dist/helpers.js +7 -1
  20. package/dist/icore.d.ts +108 -8
  21. package/dist/icore.js +208 -46
  22. package/dist/index.d.ts +9 -0
  23. package/dist/index.js +9 -1
  24. package/dist/map-types.d.ts +6 -1
  25. package/dist/map-types.js +6 -1
  26. package/dist/middleware.js +6 -0
  27. package/dist/multipart.d.ts +17 -0
  28. package/dist/multipart.js +62 -0
  29. package/dist/openapi.d.ts +6 -0
  30. package/dist/params.js +6 -0
  31. package/dist/queue.d.ts +6 -0
  32. package/dist/queue.js +6 -0
  33. package/dist/response.d.ts +6 -0
  34. package/dist/response.js +8 -1
  35. package/dist/security.d.ts +4 -0
  36. package/dist/security.js +15 -0
  37. package/dist/swagger-schema.d.ts +6 -0
  38. package/dist/swagger-schema.js +6 -0
  39. package/dist/types/app-builder.interface.d.ts +6 -0
  40. package/dist/types/app-builder.interface.js +6 -0
  41. package/dist/types/application.interface.d.ts +6 -0
  42. package/dist/validation.d.ts +6 -0
  43. package/dist/validation.js +6 -0
  44. package/dist/validator-extend.d.ts +6 -0
  45. package/dist/validator-extend.js +6 -0
  46. package/package.json +15 -8
package/dist/icore.d.ts CHANGED
@@ -1,9 +1,20 @@
1
+ /**
2
+ * @copyright 2024
3
+ * @author Tareq Hossain
4
+ * @email xtrinsic96@gmail.com
5
+ * @url https://github.com/xtareq
6
+ */
1
7
  import { FastifyInstance, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify";
8
+ import { Constructable } from "typedi";
2
9
  import { Constructor } from "./helpers";
3
10
  import { PathLike } from "fs";
4
11
  import { DataSourceOptions } from "typeorm";
5
12
  import { AppMiddleware } from "./middleware";
6
13
  import { OpenApiOptions, OpenApiUiOptions } from "./openapi";
14
+ import { IConfig } from "./config";
15
+ import { FastifyCorsOptions } from "@fastify/cors";
16
+ import { FastifyMultipartOptions } from "@fastify/multipart";
17
+ import { MultipartFile } from "./multipart";
7
18
  export type FuncRoute = {
8
19
  handler: any;
9
20
  middlewares?: any[];
@@ -28,7 +39,7 @@ export interface ParamMetaOptions {
28
39
  validate: boolean;
29
40
  dataType: any;
30
41
  validatorClass: boolean;
31
- type: "route:param" | "route:query" | "route:body" | "route:header" | "route:user";
42
+ type: "route:param" | "route:query" | "route:body" | "route:header" | "route:user" | "route:file" | "route:files";
32
43
  }
33
44
  export interface MethodParamMeta {
34
45
  params: ParamMetaOptions[];
@@ -37,12 +48,44 @@ export interface MethodParamMeta {
37
48
  headers: ParamMetaOptions[];
38
49
  currentUser: ParamMetaOptions[];
39
50
  swagger?: OpenApiUiOptions;
51
+ file?: any[];
52
+ files?: MultipartFile[];
40
53
  }
41
54
  type StaticFileOptions = {
42
55
  path?: PathLike;
43
56
  prefix?: string;
44
57
  };
45
- declare class AvleonApplication {
58
+ type MultipartOptions = {
59
+ destination: PathLike;
60
+ } & FastifyMultipartOptions;
61
+ type AvleonApp = FastifyInstance;
62
+ export type TestAppOptions = {
63
+ controllers: Constructor[];
64
+ };
65
+ export interface AvleonTestAppliction {
66
+ addDataSource: (dataSourceOptions: DataSourceOptions) => void;
67
+ getApp: (options?: TestAppOptions) => any;
68
+ getController: <T>(controller: Constructor<T>) => T;
69
+ }
70
+ export interface IAvleonApplication {
71
+ isDevelopment(): boolean;
72
+ useCors(corsOptions?: FastifyCorsOptions): void;
73
+ useOpenApi<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
74
+ useSwagger(options: OpenApiUiOptions): Promise<void>;
75
+ useMultipart(options: MultipartOptions): IAvleonApplication;
76
+ useMiddlewares<T extends AppMiddleware>(mclasses: Constructor<T>[]): void;
77
+ useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
78
+ mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string, fn: T): Promise<void>;
79
+ mapGet<T extends (...args: any[]) => any>(path: string, fn: T): any;
80
+ mapPost<T extends (...args: any[]) => any>(path: string, fn: T): any;
81
+ mapPut<T extends (...args: any[]) => any>(path: string, fn: T): any;
82
+ mapDelete<T extends (...args: any[]) => any>(path: string, fn: T): any;
83
+ mapControllers(controllers: any[]): any;
84
+ useStaticFiles(options?: StaticFileOptions): void;
85
+ run(port?: number): Promise<void>;
86
+ getTestApp(): any;
87
+ }
88
+ declare class AvleonApplication implements IAvleonApplication {
46
89
  private static instance;
47
90
  private static buildOptions;
48
91
  private app;
@@ -53,18 +96,46 @@ declare class AvleonApplication {
53
96
  private rMap;
54
97
  private hasSwagger;
55
98
  private globalSwaggerOptions;
99
+ private dataSourceOptions?;
56
100
  private controllers;
57
101
  private authorizeMiddleware?;
102
+ private appConfig;
103
+ private dataSource?;
104
+ private metaCache;
105
+ private multipartOptions;
58
106
  private constructor();
59
107
  static getInternalApp(buildOptions: any): AvleonApplication;
60
108
  isDevelopment(): boolean;
61
109
  private initSwagger;
110
+ useCors(corsOptions?: FastifyCorsOptions): void;
111
+ useOpenApi<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
112
+ /**
113
+ * @deprecated
114
+ * Will remove in next major version
115
+ */
62
116
  useSwagger(options: OpenApiUiOptions): Promise<void>;
117
+ useMultipart(options: MultipartOptions): this;
63
118
  private handleMiddlewares;
64
119
  private executeMiddlewares;
120
+ /**
121
+ * build controller
122
+ * @param controller
123
+ * @returns void
124
+ */
65
125
  private buildController;
126
+ /**
127
+ * map all request parameters
128
+ * @param req
129
+ * @param meta
130
+ * @returns
131
+ */
66
132
  private _mapArgs;
67
- private metaCache;
133
+ /**
134
+ * Process Meta for controlelr class methods
135
+ * @param prototype
136
+ * @param method
137
+ * @returns
138
+ */
68
139
  private _processMeta;
69
140
  autoControllers(): Promise<void>;
70
141
  mapControllers(controllers: Function[]): void;
@@ -94,19 +165,48 @@ declare class AvleonApplication {
94
165
  useSwagger: (options: OpenApiOptions) => /*elided*/ any;
95
166
  };
96
167
  useStaticFiles(options?: StaticFileOptions): void;
168
+ initializeDatabase(): Promise<void>;
97
169
  run(port?: number): Promise<void>;
98
- getTestApp(app: AvleonApplication): FastifyInstance<import("fastify").RawServerDefault, import("http").IncomingMessage, import("http").ServerResponse<import("http").IncomingMessage>, import("fastify").FastifyBaseLogger, import("fastify").FastifyTypeProviderDefault>;
170
+ getTestApp(buildOptions?: any): Promise<any>;
171
+ }
172
+ export type Application = typeof AvleonApplication;
173
+ export interface ITestBuilder {
174
+ getTestApplication(): AvleonTestAppliction;
175
+ createTestApplication(options: any): AvleonTestAppliction;
176
+ }
177
+ export interface IAppBuilder {
178
+ registerPlugin<T extends Function, S extends {}>(plugin: T, options: S): Promise<void>;
179
+ addDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
180
+ build<T extends IAvleonApplication>(): T;
181
+ }
182
+ export declare class TestBuilder {
183
+ private static instance;
184
+ private app;
185
+ private dataSourceOptions?;
186
+ private constructor();
187
+ static createBuilder(): TestBuilder;
188
+ getController<T>(controller: Constructor<T>): T;
189
+ getService<T>(service: Constructor<T>): T;
190
+ getTestApplication(options: TestAppOptions): Promise<AvleonApp>;
191
+ build(app: IAvleonApplication): any;
192
+ fromApplication(app: IAvleonApplication): any;
99
193
  }
100
- export declare class Builder {
194
+ export declare class Builder implements ITestBuilder, IAppBuilder {
101
195
  private static instance;
102
196
  private alreadyBuilt;
103
197
  private database;
104
198
  private dataSource?;
199
+ private multipartOptions;
200
+ private dataSourceOptions?;
201
+ private testBuilder;
202
+ private appConfig;
105
203
  private constructor();
204
+ getTestApplication(): AvleonTestAppliction;
106
205
  static createAppBuilder(): Builder;
107
- static creatTestAppBilder(): Builder;
206
+ static creatTestAppBuilder(): ITestBuilder;
108
207
  registerPlugin<T extends Function, S extends {}>(plugin: T, options: S): Promise<void>;
109
- addDataSource(config: DataSourceOptions): Promise<void>;
110
- build(): AvleonApplication;
208
+ addDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
209
+ createTestApplication<T extends AvleonTestAppliction>(buildOptions?: any): any;
210
+ build<T extends IAvleonApplication>(): T;
111
211
  }
112
212
  export {};
package/dist/icore.js CHANGED
@@ -54,7 +54,13 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
54
54
  return (mod && mod.__esModule) ? mod : { "default": mod };
55
55
  };
56
56
  Object.defineProperty(exports, "__esModule", { value: true });
57
- exports.Builder = void 0;
57
+ exports.Builder = exports.TestBuilder = void 0;
58
+ /**
59
+ * @copyright 2024
60
+ * @author Tareq Hossain
61
+ * @email xtrinsic96@gmail.com
62
+ * @url https://github.com/xtareq
63
+ */
58
64
  const fastify_1 = __importDefault(require("fastify"));
59
65
  const typedi_1 = __importDefault(require("typedi"));
60
66
  const promises_1 = __importDefault(require("fs/promises"));
@@ -65,7 +71,10 @@ const system_exception_1 = require("./exceptions/system-exception");
65
71
  const fs_1 = require("fs");
66
72
  const exceptions_1 = require("./exceptions");
67
73
  const swagger_1 = __importDefault(require("@fastify/swagger"));
74
+ const config_1 = require("./config");
68
75
  const environment_variables_1 = require("./environment-variables");
76
+ const cors_1 = __importDefault(require("@fastify/cors"));
77
+ const multipart_1 = __importDefault(require("@fastify/multipart"));
69
78
  const isTsNode = process.env.TS_NODE_DEV ||
70
79
  process.env.TS_NODE_PROJECT ||
71
80
  process[Symbol.for("ts-node.register.instance")];
@@ -80,10 +89,13 @@ class AvleonApplication {
80
89
  this.rMap = new Map();
81
90
  this.hasSwagger = false;
82
91
  this.globalSwaggerOptions = {};
92
+ this.dataSourceOptions = undefined;
83
93
  this.controllers = [];
84
94
  this.authorizeMiddleware = undefined;
95
+ this.dataSource = undefined;
85
96
  this.metaCache = new Map();
86
97
  this.app = (0, fastify_1.default)();
98
+ this.appConfig = new config_1.AppConfig();
87
99
  // this.app.setValidatorCompiler(() => () => true);
88
100
  }
89
101
  static getInternalApp(buildOptions) {
@@ -93,10 +105,19 @@ class AvleonApplication {
93
105
  AvleonApplication.buildOptions = buildOptions;
94
106
  if (buildOptions.controllers) {
95
107
  }
108
+ if (buildOptions.dataSourceOptions) {
109
+ AvleonApplication.instance.dataSourceOptions =
110
+ buildOptions.dataSourceOptions;
111
+ const typeorm = require("typeorm");
112
+ const datasource = new typeorm.DataSource(buildOptions.dataSourceOptions);
113
+ typedi_1.default.set("idatasource", datasource);
114
+ AvleonApplication.instance.dataSource = datasource;
115
+ }
96
116
  return AvleonApplication.instance;
97
117
  }
98
118
  isDevelopment() {
99
- return environment_variables_1.env["NODE_ENV"] == "development";
119
+ const env = container_1.default.get(environment_variables_1.Environment);
120
+ return env.get("NODE_ENV") == "development";
100
121
  }
101
122
  async initSwagger(options) {
102
123
  const { routePrefix, logo, theme } = options, restOptions = __rest(options, ["routePrefix", "logo", "theme"]);
@@ -104,8 +125,6 @@ class AvleonApplication {
104
125
  openapi: Object.assign({ openapi: "3.0.0" }, restOptions),
105
126
  });
106
127
  const rPrefix = routePrefix ? routePrefix : "/docs";
107
- //import fastifyApiReference from "@scalar/fastify-api-reference";
108
- //const fastifyApiReference = await require("@scalar/fastify-api-reference");
109
128
  await this.app.register(require("@fastify/swagger-ui"), {
110
129
  logo: logo ? logo : null,
111
130
  theme: theme ? theme : {},
@@ -120,10 +139,33 @@ class AvleonApplication {
120
139
  },
121
140
  });
122
141
  }
142
+ useCors(corsOptions = {}) {
143
+ this.app.register(cors_1.default, corsOptions);
144
+ }
145
+ useOpenApi(ConfigClass, modifyConfig) {
146
+ const openApiConfig = this.appConfig.get(ConfigClass);
147
+ if (modifyConfig) {
148
+ const modifiedConfig = modifyConfig(openApiConfig);
149
+ this.globalSwaggerOptions = modifiedConfig;
150
+ }
151
+ else {
152
+ this.globalSwaggerOptions = openApiConfig;
153
+ }
154
+ this.hasSwagger = true;
155
+ }
156
+ /**
157
+ * @deprecated
158
+ * Will remove in next major version
159
+ */
123
160
  async useSwagger(options) {
124
161
  this.hasSwagger = true;
125
162
  this.globalSwaggerOptions = options;
126
163
  }
164
+ useMultipart(options) {
165
+ this.multipartOptions = options;
166
+ this.app.register(multipart_1.default, options);
167
+ return this;
168
+ }
127
169
  handleMiddlewares(mclasses) {
128
170
  for (const mclass of mclasses) {
129
171
  const cls = typedi_1.default.get(mclass.constructor);
@@ -138,6 +180,11 @@ class AvleonApplication {
138
180
  : [];
139
181
  return [...classMiddlewares, ...methodMiddlewares];
140
182
  }
183
+ /**
184
+ * build controller
185
+ * @param controller
186
+ * @returns void
187
+ */
141
188
  async buildController(controller) {
142
189
  var _a, e_1, _b, _c;
143
190
  const ctrl = typedi_1.default.get(controller);
@@ -155,7 +202,6 @@ class AvleonApplication {
155
202
  return this.authorizeMiddleware.authorize(req);
156
203
  });
157
204
  }
158
- console.log("ClassMiddlware:", tag + ":", authClsMeata);
159
205
  try {
160
206
  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) {
161
207
  _c = methods_1_1.value;
@@ -226,7 +272,14 @@ class AvleonApplication {
226
272
  finally { if (e_1) throw e_1.error; }
227
273
  }
228
274
  }
275
+ /**
276
+ * map all request parameters
277
+ * @param req
278
+ * @param meta
279
+ * @returns
280
+ */
229
281
  async _mapArgs(req, meta) {
282
+ var _a, e_2, _b, _c;
230
283
  if (!req.hasOwnProperty("_argsCache")) {
231
284
  Object.defineProperty(req, "_argsCache", {
232
285
  value: new Map(),
@@ -244,9 +297,32 @@ class AvleonApplication {
244
297
  meta.currentUser.forEach((user) => (args[user.index] = req.user));
245
298
  meta.headers.forEach((header) => (args[header.index] =
246
299
  header.key === "all" ? req.headers : req.headers[header.key]));
300
+ if (meta.file) {
301
+ try {
302
+ for (var _d = true, _e = __asyncValues(meta.file), _f; _f = await _e.next(), _a = _f.done, !_a; _d = true) {
303
+ _c = _f.value;
304
+ _d = false;
305
+ let f = _c;
306
+ args[f.index] = await req.file();
307
+ }
308
+ }
309
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
310
+ finally {
311
+ try {
312
+ if (!_d && !_a && (_b = _e.return)) await _b.call(_e);
313
+ }
314
+ finally { if (e_2) throw e_2.error; }
315
+ }
316
+ }
247
317
  cache.set(cacheKey, args);
248
318
  return args;
249
319
  }
320
+ /**
321
+ * Process Meta for controlelr class methods
322
+ * @param prototype
323
+ * @param method
324
+ * @returns
325
+ */
250
326
  _processMeta(prototype, method) {
251
327
  const cacheKey = `${prototype.constructor.name}_${method}`;
252
328
  if (this.metaCache.has(cacheKey)) {
@@ -256,6 +332,8 @@ class AvleonApplication {
256
332
  params: Reflect.getMetadata(container_1.PARAM_META_KEY, prototype, method) || [],
257
333
  query: Reflect.getMetadata(container_1.QUERY_META_KEY, prototype, method) || [],
258
334
  body: Reflect.getMetadata(container_1.REQUEST_BODY_META_KEY, prototype, method) || [],
335
+ file: Reflect.getMetadata(container_1.REQUEST_BODY_FILE_KEY, prototype, method) || [],
336
+ files: Reflect.getMetadata(container_1.REQUEST_BODY_FILES_KEY, prototype, method) || [],
259
337
  headers: Reflect.getMetadata(container_1.REQUEST_HEADER_META_KEY, prototype, method) || [],
260
338
  currentUser: Reflect.getMetadata(container_1.REQUEST_USER_META_KEY, prototype, method) || [],
261
339
  // swagger: Reflect.getMetadata("route:openapi", prototype, method) || {}
@@ -297,14 +375,10 @@ class AvleonApplication {
297
375
  this.autoControllers();
298
376
  }
299
377
  }
300
- async handleRoute(args) {
301
- console.log(args);
302
- }
378
+ async handleRoute(args) { }
303
379
  async mapFn(fn) {
304
380
  const original = fn;
305
- fn = function () {
306
- console.log(arguments);
307
- };
381
+ fn = function () { };
308
382
  return fn;
309
383
  }
310
384
  useMiddlewares(mclasses) {
@@ -329,7 +403,7 @@ class AvleonApplication {
329
403
  }
330
404
  return {
331
405
  code: 500,
332
- error: "INTERNALERROR",
406
+ error: "INTERNAL_ERROR",
333
407
  message: error.message ? error.message : "Something going wrong.",
334
408
  };
335
409
  }
@@ -367,20 +441,20 @@ class AvleonApplication {
367
441
  const ms = midds.map((mclass) => {
368
442
  const cls = typedi_1.default.get(mclass);
369
443
  this.middlewares.set(mclass.name, cls);
370
- return cls.invoke; // Ensure `invoke` runs in the correct context
444
+ return cls.invoke;
371
445
  });
372
446
  const r = this.rMap.get(routeKey);
373
447
  if (r) {
374
- r.middlewares = ms; // Update middlewares array
448
+ r.middlewares = ms;
375
449
  }
376
- return route; // Ensure chaining by returning the same route object
450
+ return route;
377
451
  },
378
452
  useSwagger: (options) => {
379
453
  const r = this.rMap.get(routeKey);
380
454
  if (r) {
381
- r.schema = options; // Update schema
455
+ r.schema = options;
382
456
  }
383
- return route; // Ensure chaining
457
+ return route;
384
458
  },
385
459
  };
386
460
  return route;
@@ -403,20 +477,19 @@ class AvleonApplication {
403
477
  prefix: options.prefix ? options.prefix : "/static/",
404
478
  });
405
479
  }
480
+ async initializeDatabase() {
481
+ if (this.dataSourceOptions && this.dataSource) {
482
+ await this.dataSource.initialize();
483
+ }
484
+ }
406
485
  async run(port = 4000) {
407
486
  if (this.alreadyRun)
408
487
  throw new system_exception_1.SystemUseError("App already running");
409
488
  this.alreadyRun = true;
410
- if (AvleonApplication.buildOptions.database) {
411
- }
412
- //this.app.swagger();
413
489
  if (this.hasSwagger) {
414
490
  await this.initSwagger(this.globalSwaggerOptions);
415
491
  }
416
492
  await this._mapControllers();
417
- // this.controllers.forEach(controller => {
418
- // this.buildController(controller)
419
- // })
420
493
  this.rMap.forEach((value, key) => {
421
494
  const [m, r] = key.split(":");
422
495
  this.app.route({
@@ -443,18 +516,91 @@ class AvleonApplication {
443
516
  });
444
517
  await this.app.ready();
445
518
  await this.app.listen({ port });
446
- console.log(`Application running on port: 0.0.0.0:${port}`);
519
+ console.log(`Application running on http://127.0.0.1:${port}`);
447
520
  }
448
- getTestApp(app) {
449
- return this.app;
521
+ async getTestApp(buildOptions) {
522
+ try {
523
+ if (buildOptions && buildOptions.addDataSource) {
524
+ const typeorm = await Promise.resolve().then(() => __importStar(require("typeorm")));
525
+ if (!typeorm) {
526
+ throw new system_exception_1.SystemUseError("TypeOrm not installed");
527
+ }
528
+ const datasource = new typeorm.DataSource(buildOptions.addDataSource);
529
+ typedi_1.default.set("idatasource", datasource);
530
+ await datasource.initialize();
531
+ }
532
+ this._mapControllers();
533
+ this.rMap.forEach((value, key) => {
534
+ const [m, r] = key.split(":");
535
+ this.app.route({
536
+ method: m,
537
+ url: r,
538
+ schema: value.schema || {},
539
+ preHandler: value.middlewares ? value.middlewares : [],
540
+ handler: async (req, res) => {
541
+ const result = await value.handler.apply(this, [req, res]);
542
+ return result;
543
+ },
544
+ });
545
+ });
546
+ this.app.setErrorHandler(async (error, req, res) => {
547
+ const handledErr = this._handleError(error);
548
+ if (error instanceof exceptions_1.ValidationErrorException) {
549
+ return res.status(handledErr.code).send({
550
+ code: handledErr.code,
551
+ error: handledErr.error,
552
+ errors: handledErr.message,
553
+ });
554
+ }
555
+ return res.status(handledErr.code).send(handledErr);
556
+ });
557
+ return this.app;
558
+ }
559
+ catch (error) {
560
+ throw new system_exception_1.SystemUseError("Can't get test appliction");
561
+ }
450
562
  }
451
563
  }
452
564
  AvleonApplication.buildOptions = {};
453
- // Applciation Builder
565
+ class TestBuilder {
566
+ constructor() { }
567
+ static createBuilder() {
568
+ if (!TestBuilder.instance) {
569
+ TestBuilder.instance = new TestBuilder();
570
+ }
571
+ return TestBuilder.instance;
572
+ }
573
+ getController(controller) {
574
+ return typedi_1.default.get(controller);
575
+ }
576
+ getService(service) {
577
+ return typedi_1.default.get(service);
578
+ }
579
+ async getTestApplication(options) {
580
+ const app = AvleonApplication.getInternalApp({
581
+ dataSourceOptions: this.dataSourceOptions
582
+ });
583
+ app.mapControllers([...options.controllers]);
584
+ const fa = await app.getTestApp();
585
+ return fa;
586
+ }
587
+ build(app) {
588
+ return app.getTestApp();
589
+ }
590
+ fromApplication(app) {
591
+ return app.getTestApp();
592
+ }
593
+ }
594
+ exports.TestBuilder = TestBuilder;
454
595
  class Builder {
455
596
  constructor() {
456
597
  this.alreadyBuilt = false;
457
598
  this.database = false;
599
+ this.testBuilder = false;
600
+ this.appConfig = new config_1.AppConfig();
601
+ }
602
+ getTestApplication() {
603
+ throw new Error("Method not implemented.");
458
604
  }
459
605
  static createAppBuilder() {
460
606
  if (!Builder.instance) {
@@ -462,41 +608,57 @@ class Builder {
462
608
  }
463
609
  return Builder.instance;
464
610
  }
465
- static creatTestAppBilder() {
611
+ static creatTestAppBuilder() {
466
612
  if (!Builder.instance) {
467
613
  Builder.instance = new Builder();
614
+ Builder.instance.testBuilder = true;
468
615
  }
469
616
  return Builder.instance;
470
617
  }
471
618
  async registerPlugin(plugin, options) {
472
619
  container_1.default.set(plugin, plugin.prototype);
473
620
  }
474
- async addDataSource(config) {
475
- if (this.database) {
476
- throw new system_exception_1.SystemUseError("Datasource already added.");
621
+ addDataSource(ConfigClass, modifyConfig) {
622
+ const openApiConfig = this.appConfig.get(ConfigClass);
623
+ if (modifyConfig) {
624
+ const modifiedConfig = modifyConfig(openApiConfig);
625
+ this.dataSourceOptions = modifiedConfig;
477
626
  }
478
- this.database = true;
479
- try {
480
- const typeorm = await Promise.resolve().then(() => __importStar(require("typeorm")));
481
- if (!typeorm) {
482
- throw new system_exception_1.SystemUseError("TypeOrm not installed");
483
- }
484
- const datasource = new typeorm.DataSource(config);
485
- typedi_1.default.set("idatasource", datasource);
486
- this.dataSource = datasource;
487
- await datasource.initialize();
488
- }
489
- catch (error) {
490
- console.log(error);
491
- console.error("Database Initialize Error:", error.message);
627
+ else {
628
+ this.dataSourceOptions = openApiConfig;
492
629
  }
493
630
  }
631
+ createTestApplication(buildOptions) {
632
+ return {
633
+ addDataSource: (dataSourceOptions) => (this.dataSourceOptions = dataSourceOptions),
634
+ getApp: async (options) => {
635
+ const app = AvleonApplication.getInternalApp({
636
+ database: this.database,
637
+ dataSourceOptions: buildOptions.datSource,
638
+ });
639
+ app.mapControllers([...options.controllers]);
640
+ const _tapp = await app.getTestApp();
641
+ return {
642
+ async get(url, options) {
643
+ const res = await _tapp.inject(Object.assign({ url, method: "GET" }, options));
644
+ return res;
645
+ },
646
+ };
647
+ },
648
+ getController(controller) {
649
+ return typedi_1.default.get(controller);
650
+ },
651
+ };
652
+ }
494
653
  build() {
495
- if (this.alreadyBuilt)
654
+ if (this.alreadyBuilt) {
496
655
  throw new Error("Already built");
656
+ }
497
657
  this.alreadyBuilt = true;
498
658
  const app = AvleonApplication.getInternalApp({
499
659
  database: this.database,
660
+ multipartOptions: this.multipartOptions,
661
+ dataSourceOptions: this.dataSourceOptions,
500
662
  });
501
663
  return app;
502
664
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1,9 @@
1
+ /**
2
+ * @copyright 2024
3
+ * @author Tareq Hossain
4
+ * @email xtrinsic96@gmail.com
5
+ * @url https://github.com/xtareq
6
+ */
1
7
  export * from "./icore";
2
8
  export { inject, validateRequestBody } from "./helpers";
3
9
  export * from "./decorators";
@@ -12,4 +18,7 @@ export * from "./validation";
12
18
  export * from "./environment-variables";
13
19
  export * from "./collection";
14
20
  export * from "./queue";
21
+ export * from "./security";
22
+ export * from "./multipart";
23
+ export * from "./file-storage";
15
24
  export { default as Container } from "./container";
package/dist/index.js CHANGED
@@ -1,4 +1,10 @@
1
1
  "use strict";
2
+ /**
3
+ * @copyright 2024
4
+ * @author Tareq Hossain
5
+ * @email xtrinsic96@gmail.com
6
+ * @url https://github.com/xtareq
7
+ */
2
8
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
9
  if (k2 === undefined) k2 = k;
4
10
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -18,7 +24,6 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
18
24
  };
19
25
  Object.defineProperty(exports, "__esModule", { value: true });
20
26
  exports.Container = exports.validateRequestBody = exports.inject = void 0;
21
- //export * from "./iqra-core";
22
27
  __exportStar(require("./icore"), exports);
23
28
  var helpers_1 = require("./helpers");
24
29
  Object.defineProperty(exports, "inject", { enumerable: true, get: function () { return helpers_1.inject; } });
@@ -35,5 +40,8 @@ __exportStar(require("./validation"), exports);
35
40
  __exportStar(require("./environment-variables"), exports);
36
41
  __exportStar(require("./collection"), exports);
37
42
  __exportStar(require("./queue"), exports);
43
+ __exportStar(require("./security"), exports);
44
+ __exportStar(require("./multipart"), exports);
45
+ __exportStar(require("./file-storage"), exports);
38
46
  var container_1 = require("./container");
39
47
  Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return __importDefault(container_1).default; } });
@@ -1,4 +1,9 @@
1
- import "reflect-metadata";
1
+ /**
2
+ * @copyright 2024
3
+ * @author Tareq Hossain
4
+ * @email xtrinsic96@gmail.com
5
+ * @url https://github.com/xtareq
6
+ */
2
7
  type Constructor<T = any> = new (...args: any[]) => T;
3
8
  export declare function PartialType<T>(BaseClass: Constructor<T>): Constructor<Partial<T>>;
4
9
  /**
package/dist/map-types.js CHANGED
@@ -1,9 +1,14 @@
1
1
  "use strict";
2
+ /**
3
+ * @copyright 2024
4
+ * @author Tareq Hossain
5
+ * @email xtrinsic96@gmail.com
6
+ * @url https://github.com/xtareq
7
+ */
2
8
  Object.defineProperty(exports, "__esModule", { value: true });
3
9
  exports.PartialType = PartialType;
4
10
  exports.PickType = PickType;
5
11
  exports.OmitType = OmitType;
6
- require("reflect-metadata");
7
12
  function PartialType(BaseClass) {
8
13
  const baseProperties = [];
9
14
  let currentPrototype = BaseClass.prototype;