@avleon/core 0.0.13 → 0.0.16

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.
File without changes
@@ -0,0 +1 @@
1
+ "use strict";
@@ -39,12 +39,3 @@ export declare class ForbiddenException extends BaseHttpException {
39
39
  constructor(message: any);
40
40
  }
41
41
  export type HttpException = NotFoundException | BadRequestException | UnauthorizedException | InternalErrorException | ForbiddenException;
42
- export type HttpExceptions = {
43
- NotFound: (message: any) => NotFoundException;
44
- ValidationError: (message: any) => ValidationErrorException;
45
- BadRequest: (message: any) => BadRequestException;
46
- Unauthorized: (message: any) => UnauthorizedException;
47
- Forbidden: (message: any) => ForbiddenException;
48
- InternalError: (message: any) => InternalErrorException;
49
- };
50
- export declare const httpExcepitoins: HttpExceptions;
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.httpExcepitoins = exports.ForbiddenException = exports.UnauthorizedException = exports.NotFoundException = exports.InternalErrorException = exports.ValidationErrorException = exports.BadRequestException = exports.BaseHttpException = void 0;
3
+ exports.ForbiddenException = exports.UnauthorizedException = exports.NotFoundException = exports.InternalErrorException = exports.ValidationErrorException = exports.BadRequestException = exports.BaseHttpException = void 0;
4
4
  /**
5
5
  * @copyright 2024
6
6
  * @author Tareq Hossain
@@ -65,11 +65,19 @@ class ForbiddenException extends BaseHttpException {
65
65
  }
66
66
  }
67
67
  exports.ForbiddenException = ForbiddenException;
68
- exports.httpExcepitoins = {
69
- NotFound: (message) => new NotFoundException(message),
70
- ValidationError: (message) => new ValidationErrorException(message),
71
- BadRequest: (message) => new BadRequestException(message),
72
- Unauthorized: (message) => new UnauthorizedException(message),
73
- Forbidden: (message) => new ForbiddenException(message),
74
- InternalError: (message) => new InternalErrorException(message)
75
- };
68
+ // export type HttpExceptions = {
69
+ // NotFound: (message: any) => NotFoundException,
70
+ // ValidationError: (message: any) =>ValidationErrorException,
71
+ // BadRequest: (message: any) => BadRequestException,
72
+ // Unauthorized: (message: any) => UnauthorizedException,
73
+ // Forbidden: (message: any) => ForbiddenException,
74
+ // InternalError: (message: any) => InternalErrorException
75
+ // }
76
+ // export const httpExcepitoins: HttpExceptions = {
77
+ // NotFound:(message:any)=>new NotFoundException(message),
78
+ // ValidationError:(message:any)=>new ValidationErrorException(message),
79
+ // BadRequest:(message:any)=>new BadRequestException(message),
80
+ // Unauthorized:(message:any)=>new UnauthorizedException(message),
81
+ // Forbidden:(message:any)=>new ForbiddenException(message),
82
+ // InternalError: (message:any)=> new InternalErrorException(message)
83
+ // }
package/dist/helpers.d.ts CHANGED
@@ -23,10 +23,10 @@ export declare function jsonToJs(value: string): any;
23
23
  export declare function jsonToInstance(value: string, instance: Constructor): any;
24
24
  export declare function transformObjectByInstanceToObject(instance: Constructor, value: object): Record<string, any>;
25
25
  export declare const isClassValidatorClass: (target: Constructor) => boolean;
26
- export declare function validateObjectByInstance(target: Constructor, value?: object, options?: 'object' | 'array'): Promise<any>;
26
+ export declare function validateObjectByInstance(target: Constructor, value?: object, options?: "object" | "array"): Promise<any>;
27
27
  type ValidationError = {
28
28
  count: number;
29
29
  errors: any;
30
30
  };
31
- export declare function validateRequestBody(target: Constructor, value: object, options?: 'object' | 'array'): ValidationError;
31
+ export declare function validateRequestBody(target: Constructor, value: object, options?: "object" | "array"): ValidationError;
32
32
  export {};
package/dist/helpers.js CHANGED
@@ -43,7 +43,7 @@ function inject(cls) {
43
43
  }
44
44
  function isConstructor(func) {
45
45
  // Check if the func is a function
46
- if (typeof func !== 'function') {
46
+ if (typeof func !== "function") {
47
47
  return false;
48
48
  }
49
49
  // Check if it's an arrow function or a built-in JavaScript function
@@ -51,13 +51,13 @@ function isConstructor(func) {
51
51
  return false;
52
52
  }
53
53
  // Check if it has a `prototype` property
54
- if (func.prototype && typeof func.prototype === 'object') {
54
+ if (func.prototype && typeof func.prototype === "object") {
55
55
  return true;
56
56
  }
57
57
  // If it's not a constructor, check if it can be called with the new keyword
58
58
  try {
59
59
  const instance = new func();
60
- return typeof instance === 'object';
60
+ return typeof instance === "object";
61
61
  }
62
62
  catch (e) {
63
63
  return false;
@@ -83,8 +83,7 @@ function parsedPath(ipath) {
83
83
  const isClassValidator = (target) => {
84
84
  try {
85
85
  const clsval = require("class-validator");
86
- const result = (0, class_validator_1.getMetadataStorage)()
87
- .getTargetValidationMetadatas(target, '', false, false);
86
+ const result = (0, class_validator_1.getMetadataStorage)().getTargetValidationMetadatas(target, "", false, false);
88
87
  return result.length > 0;
89
88
  }
90
89
  catch (err) {
@@ -216,7 +215,7 @@ const isClassValidatorClass = (target) => {
216
215
  }
217
216
  };
218
217
  exports.isClassValidatorClass = isClassValidatorClass;
219
- async function validateObjectByInstance(target, value = {}, options = 'array') {
218
+ async function validateObjectByInstance(target, value = {}, options = "array") {
220
219
  try {
221
220
  const { validateOrReject } = require("class-validator");
222
221
  const { plainToInstance } = require("class-transformer");
@@ -224,11 +223,16 @@ async function validateObjectByInstance(target, value = {}, options = 'array') {
224
223
  }
225
224
  catch (error) {
226
225
  if (typeof error == "object" && Array.isArray(error)) {
227
- const errors = options == 'object' ? error.reduce((acc, x) => {
228
- //acc[x.property] = Object.values(x.constraints);
229
- acc[x.property] = x.constraints;
230
- return acc;
231
- }, {}) : error.map(x => ({ path: x.property, constraints: x.constraints }));
226
+ const errors = options == "object"
227
+ ? error.reduce((acc, x) => {
228
+ //acc[x.property] = Object.values(x.constraints);
229
+ acc[x.property] = x.constraints;
230
+ return acc;
231
+ }, {})
232
+ : error.map((x) => ({
233
+ path: x.property,
234
+ constraints: x.constraints,
235
+ }));
232
236
  return errors;
233
237
  }
234
238
  else {
@@ -236,14 +240,16 @@ async function validateObjectByInstance(target, value = {}, options = 'array') {
236
240
  }
237
241
  }
238
242
  }
239
- function validateRequestBody(target, value, options = 'array') {
243
+ function validateRequestBody(target, value, options = "array") {
240
244
  if (!(0, exports.isClassValidatorClass)(target))
241
245
  return { count: 0, errors: {} };
242
246
  const error = (0, class_validator_1.validateSync)((0, class_transformer_1.plainToInstance)(target, value ? value : {}));
243
- const errors = options == 'object' ? error.reduce((acc, x) => {
244
- //acc[x.property] = Object.values(x.constraints);
245
- acc[x.property] = x.constraints;
246
- return acc;
247
- }, {}) : error.map(x => ({ path: x.property, constraints: x.constraints }));
247
+ const errors = options == "object"
248
+ ? error.reduce((acc, x) => {
249
+ //acc[x.property] = Object.values(x.constraints);
250
+ acc[x.property] = x.constraints;
251
+ return acc;
252
+ }, {})
253
+ : error.map((x) => ({ path: x.property, constraints: x.constraints }));
248
254
  return { count: error.length, errors };
249
255
  }
package/dist/icore.d.ts CHANGED
@@ -4,7 +4,7 @@
4
4
  * @email xtrinsic96@gmail.com
5
5
  * @url https://github.com/xtareq
6
6
  */
7
- import { FastifyInstance, FastifyReply, FastifyRequest, HookHandlerDoneFunction } from "fastify";
7
+ import { FastifyReply, FastifyRequest, HookHandlerDoneFunction, InjectOptions, LightMyRequestResponse } from "fastify";
8
8
  import { Constructable } from "typedi";
9
9
  import { Constructor } from "./helpers";
10
10
  import { PathLike } from "fs";
@@ -27,9 +27,19 @@ export interface IRequest extends FastifyRequest {
27
27
  headers: any;
28
28
  user?: any;
29
29
  }
30
+ export interface DoneFunction extends HookHandlerDoneFunction {
31
+ }
30
32
  export interface IResponse extends FastifyReply {
31
33
  }
32
- export interface DoneFunction extends HookHandlerDoneFunction {
34
+ export type TestResponseType = LightMyRequestResponse;
35
+ export type TestResponse = TestResponseType | Promise<TestResponseType>;
36
+ export interface TestApplication {
37
+ get: (url: string, options?: InjectOptions) => TestResponse;
38
+ post: (url: string, options?: InjectOptions) => TestResponse;
39
+ put: (url: string, options?: InjectOptions) => TestResponse;
40
+ patch: (url: string, options?: InjectOptions) => TestResponse;
41
+ delete: (url: string, options?: InjectOptions) => TestResponse;
42
+ options: (url: string, options?: InjectOptions) => TestResponse;
33
43
  }
34
44
  export interface ParamMetaOptions {
35
45
  index: number;
@@ -39,6 +49,7 @@ export interface ParamMetaOptions {
39
49
  validate: boolean;
40
50
  dataType: any;
41
51
  validatorClass: boolean;
52
+ schema?: any;
42
53
  type: "route:param" | "route:query" | "route:body" | "route:header" | "route:user" | "route:file" | "route:files";
43
54
  }
44
55
  export interface ParamMetaFilesOptions {
@@ -64,7 +75,6 @@ type StaticFileOptions = {
64
75
  type MultipartOptions = {
65
76
  destination: PathLike;
66
77
  } & FastifyMultipartOptions;
67
- type AvleonApp = FastifyInstance;
68
78
  export type TestAppOptions = {
69
79
  controllers: Constructor[];
70
80
  };
@@ -78,7 +88,7 @@ export interface IAvleonApplication {
78
88
  useCors(corsOptions?: FastifyCorsOptions): void;
79
89
  useOpenApi<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
80
90
  useSwagger(options: OpenApiUiOptions): Promise<void>;
81
- useMultipart(options: MultipartOptions): IAvleonApplication;
91
+ useMultipart(options: MultipartOptions): void;
82
92
  useMiddlewares<T extends AppMiddleware>(mclasses: Constructor<T>[]): void;
83
93
  useAuthoriztion<T extends any>(middleware: Constructor<T>): void;
84
94
  mapRoute<T extends (...args: any[]) => any>(method: "get" | "post" | "put" | "delete", path: string, fn: T): Promise<void>;
@@ -89,7 +99,7 @@ export interface IAvleonApplication {
89
99
  mapControllers(controllers: any[]): any;
90
100
  useStaticFiles(options?: StaticFileOptions): void;
91
101
  run(port?: number): Promise<void>;
92
- getTestApp(): any;
102
+ getTestApp(): TestApplication;
93
103
  }
94
104
  declare class AvleonApplication implements IAvleonApplication {
95
105
  private static instance;
@@ -120,7 +130,7 @@ declare class AvleonApplication implements IAvleonApplication {
120
130
  * Will remove in next major version
121
131
  */
122
132
  useSwagger(options: OpenApiUiOptions): Promise<void>;
123
- useMultipart(options: MultipartOptions): this;
133
+ useMultipart(options: MultipartOptions): void;
124
134
  private handleMiddlewares;
125
135
  private executeMiddlewares;
126
136
  /**
@@ -173,7 +183,7 @@ declare class AvleonApplication implements IAvleonApplication {
173
183
  useStaticFiles(options?: StaticFileOptions): void;
174
184
  initializeDatabase(): Promise<void>;
175
185
  run(port?: number): Promise<void>;
176
- getTestApp(buildOptions?: any): Promise<any>;
186
+ getTestApp(buildOptions?: any): TestApplication;
177
187
  }
178
188
  export type Application = typeof AvleonApplication;
179
189
  export interface ITestBuilder {
@@ -193,11 +203,11 @@ export declare class TestBuilder {
193
203
  static createBuilder(): TestBuilder;
194
204
  getController<T>(controller: Constructor<T>): T;
195
205
  getService<T>(service: Constructor<T>): T;
196
- getTestApplication(options: TestAppOptions): Promise<AvleonApp>;
197
- build(app: IAvleonApplication): any;
198
- fromApplication(app: IAvleonApplication): any;
206
+ getTestApplication(options: TestAppOptions): TestApplication;
207
+ build(app: IAvleonApplication): TestApplication;
208
+ fromApplication(app: IAvleonApplication): TestApplication;
199
209
  }
200
- export declare class Builder implements ITestBuilder, IAppBuilder {
210
+ export declare class Builder implements IAppBuilder {
201
211
  private static instance;
202
212
  private alreadyBuilt;
203
213
  private database;
@@ -207,12 +217,9 @@ export declare class Builder implements ITestBuilder, IAppBuilder {
207
217
  private testBuilder;
208
218
  private appConfig;
209
219
  private constructor();
210
- getTestApplication(): AvleonTestAppliction;
211
220
  static createAppBuilder(): Builder;
212
- static creatTestAppBuilder(): ITestBuilder;
213
221
  registerPlugin<T extends Function, S extends {}>(plugin: T, options: S): Promise<void>;
214
222
  addDataSource<T extends IConfig<R>, R = ReturnType<InstanceType<Constructable<T>>["config"]>>(ConfigClass: Constructable<T>, modifyConfig?: (config: R) => R): void;
215
- createTestApplication<T extends AvleonTestAppliction>(buildOptions?: any): any;
216
223
  build<T extends IAvleonApplication>(): T;
217
224
  }
218
225
  export {};
package/dist/icore.js CHANGED
@@ -94,7 +94,9 @@ class AvleonApplication {
94
94
  this.authorizeMiddleware = undefined;
95
95
  this.dataSource = undefined;
96
96
  this.metaCache = new Map();
97
- this.app = (0, fastify_1.default)();
97
+ this.app = (0, fastify_1.default)({
98
+ frameworkErrors: (error, req, res) => { },
99
+ });
98
100
  this.appConfig = new config_1.AppConfig();
99
101
  // this.app.setValidatorCompiler(() => () => true);
100
102
  }
@@ -120,24 +122,41 @@ class AvleonApplication {
120
122
  return env.get("NODE_ENV") == "development";
121
123
  }
122
124
  async initSwagger(options) {
123
- const { routePrefix, logo, theme } = options, restOptions = __rest(options, ["routePrefix", "logo", "theme"]);
125
+ const { routePrefix, logo, ui, theme, configuration } = options, restOptions = __rest(options, ["routePrefix", "logo", "ui", "theme", "configuration"]);
124
126
  this.app.register(swagger_1.default, {
125
127
  openapi: Object.assign({ openapi: "3.0.0" }, restOptions),
126
128
  });
127
129
  const rPrefix = routePrefix ? routePrefix : "/docs";
128
- await this.app.register(require("@fastify/swagger-ui"), {
129
- logo: logo ? logo : null,
130
- theme: theme ? theme : {},
131
- routePrefix: rPrefix,
132
- configuration: {
133
- metaData: {
134
- title: "Avleon Api",
135
- ogTitle: "Avleon",
130
+ if (options.ui && options.ui == "scalar") {
131
+ await this.app.register(require("@scalar/fastify-api-reference"), {
132
+ routePrefix: rPrefix,
133
+ configuration: configuration
134
+ ? configuration
135
+ : {
136
+ metaData: {
137
+ title: "Avleon Api",
138
+ ogTitle: "Avleon",
139
+ },
140
+ theme: options.theme ? options.theme : "kepler",
141
+ favicon: "/static/favicon.png",
142
+ },
143
+ });
144
+ }
145
+ else {
146
+ await this.app.register(require("@fastify/swagger-ui"), {
147
+ logo: logo ? logo : null,
148
+ theme: theme ? theme : {},
149
+ routePrefix: rPrefix,
150
+ configuration: {
151
+ metaData: {
152
+ title: "Avleon Api",
153
+ ogTitle: "Avleon",
154
+ },
155
+ theme: "kepler",
156
+ favicon: "/static/favicon.png",
136
157
  },
137
- theme: "kepler",
138
- favicon: "/static/favicon.png",
139
- },
140
- });
158
+ });
159
+ }
141
160
  }
142
161
  useCors(corsOptions = {}) {
143
162
  this.app.register(cors_1.default, corsOptions);
@@ -163,8 +182,7 @@ class AvleonApplication {
163
182
  }
164
183
  useMultipart(options) {
165
184
  this.multipartOptions = options;
166
- this.app.register(multipart_1.default, options);
167
- return this;
185
+ this.app.register(multipart_1.default, Object.assign(Object.assign({}, this.multipartOptions), { attachFieldsToBody: true }));
168
186
  }
169
187
  handleMiddlewares(mclasses) {
170
188
  for (const mclass of mclasses) {
@@ -222,11 +240,21 @@ class AvleonApplication {
222
240
  const swaggerMeta = Reflect.getMetadata("route:openapi", prototype, method) || {};
223
241
  const authClsMethodMeata = Reflect.getMetadata(container_1.AUTHORIZATION_META_KEY, ctrl.constructor, method) || { authorize: false, options: undefined };
224
242
  const allMeta = this._processMeta(prototype, method);
243
+ let bodySchema = null;
244
+ allMeta.body.forEach((r) => {
245
+ if (r.schema) {
246
+ bodySchema = Object.assign({}, r.schema);
247
+ }
248
+ });
225
249
  const routePath = methodmetaOptions.path == "" ? "/" : methodmetaOptions.path;
250
+ let schema = Object.assign(Object.assign(Object.assign({}, swaggerControllerMeta), swaggerMeta), { tags: [tag] });
251
+ if (!swaggerMeta.body && bodySchema) {
252
+ schema = Object.assign(Object.assign({}, schema), { body: bodySchema });
253
+ }
226
254
  this.app.route({
227
255
  url: routePath,
228
256
  method: methodmetaOptions.method.toUpperCase(),
229
- schema: Object.assign(Object.assign(Object.assign({}, swaggerControllerMeta), swaggerMeta), { tags: [tag] }),
257
+ schema: Object.assign({}, schema),
230
258
  handler: async (req, res) => {
231
259
  let reqClone = req;
232
260
  if (authClsMethodMeata.authorize && this.authorizeMiddleware) {
@@ -279,6 +307,7 @@ class AvleonApplication {
279
307
  */
280
308
  async _mapArgs(req, meta) {
281
309
  var _a, e_2, _b, _c, _d, e_3, _e, _f;
310
+ var _g;
282
311
  if (!req.hasOwnProperty("_argsCache")) {
283
312
  Object.defineProperty(req, "_argsCache", {
284
313
  value: new Map(),
@@ -298,9 +327,9 @@ class AvleonApplication {
298
327
  header.key === "all" ? req.headers : req.headers[header.key]));
299
328
  if (meta.file) {
300
329
  try {
301
- for (var _g = true, _h = __asyncValues(meta.file), _j; _j = await _h.next(), _a = _j.done, !_a; _g = true) {
302
- _c = _j.value;
303
- _g = false;
330
+ for (var _h = true, _j = __asyncValues(meta.file), _k; _k = await _j.next(), _a = _k.done, !_a; _h = true) {
331
+ _c = _k.value;
332
+ _h = false;
304
333
  let f = _c;
305
334
  args[f.index] = await req.file();
306
335
  }
@@ -308,12 +337,13 @@ class AvleonApplication {
308
337
  catch (e_2_1) { e_2 = { error: e_2_1 }; }
309
338
  finally {
310
339
  try {
311
- if (!_g && !_a && (_b = _h.return)) await _b.call(_h);
340
+ if (!_h && !_a && (_b = _j.return)) await _b.call(_j);
312
341
  }
313
342
  finally { if (e_2) throw e_2.error; }
314
343
  }
315
344
  }
316
- if (meta.files) {
345
+ if (meta.files &&
346
+ ((_g = req.headers["content-type"]) === null || _g === void 0 ? void 0 : _g.startsWith("multipart/form-data")) === true) {
317
347
  const files = await req.saveRequestFiles();
318
348
  if (!files || files.length === 0) {
319
349
  throw new exceptions_1.BadRequestException({ error: "No files uploaded" });
@@ -328,9 +358,9 @@ class AvleonApplication {
328
358
  fields: file.fields,
329
359
  }));
330
360
  try {
331
- for (var _k = true, _l = __asyncValues(meta.files), _m; _m = await _l.next(), _d = _m.done, !_d; _k = true) {
332
- _f = _m.value;
333
- _k = false;
361
+ for (var _l = true, _m = __asyncValues(meta.files), _o; _o = await _m.next(), _d = _o.done, !_d; _l = true) {
362
+ _f = _o.value;
363
+ _l = false;
334
364
  let f = _f;
335
365
  const findex = fileInfo.findIndex((x) => x.fieldname == f.fieldName);
336
366
  if (f.fieldName != "all" && findex == -1) {
@@ -345,7 +375,7 @@ class AvleonApplication {
345
375
  catch (e_3_1) { e_3 = { error: e_3_1 }; }
346
376
  finally {
347
377
  try {
348
- if (!_k && !_d && (_e = _l.return)) await _e.call(_l);
378
+ if (!_l && !_d && (_e = _m.return)) await _e.call(_m);
349
379
  }
350
380
  finally { if (e_3) throw e_3.error; }
351
381
  }
@@ -402,6 +432,9 @@ class AvleonApplication {
402
432
  if ((0, container_1.isApiController)(controller)) {
403
433
  this.buildController(controller);
404
434
  }
435
+ else {
436
+ throw new system_exception_1.SystemUseError("Not a api controller.");
437
+ }
405
438
  }
406
439
  }
407
440
  }
@@ -555,16 +588,23 @@ class AvleonApplication {
555
588
  await this.app.listen({ port });
556
589
  console.log(`Application running on http://127.0.0.1:${port}`);
557
590
  }
558
- async getTestApp(buildOptions) {
591
+ getTestApp(buildOptions) {
559
592
  try {
560
593
  if (buildOptions && buildOptions.addDataSource) {
561
- const typeorm = await Promise.resolve().then(() => __importStar(require("typeorm")));
594
+ const typeorm = Promise.resolve().then(() => __importStar(require("typeorm")));
562
595
  if (!typeorm) {
563
596
  throw new system_exception_1.SystemUseError("TypeOrm not installed");
564
597
  }
565
- const datasource = new typeorm.DataSource(buildOptions.addDataSource);
566
- typedi_1.default.set("idatasource", datasource);
567
- await datasource.initialize();
598
+ typeorm.then(async (t) => {
599
+ try {
600
+ const datasource = new t.DataSource(buildOptions.addDataSource);
601
+ typedi_1.default.set("idatasource", datasource);
602
+ await datasource.initialize();
603
+ }
604
+ catch (error) {
605
+ console.error("Database can't initialized.", error);
606
+ }
607
+ });
568
608
  }
569
609
  this._mapControllers();
570
610
  this.rMap.forEach((value, key) => {
@@ -591,7 +631,15 @@ class AvleonApplication {
591
631
  }
592
632
  return res.status(handledErr.code).send(handledErr);
593
633
  });
594
- return this.app;
634
+ // return this.app as any;
635
+ return {
636
+ get: (url, options) => this.app.inject(Object.assign({ method: "GET", url }, options)),
637
+ post: (url, options) => this.app.inject(Object.assign({ method: "POST", url }, options)),
638
+ put: (url, options) => this.app.inject(Object.assign({ method: "PUT", url }, options)),
639
+ patch: (url, options) => this.app.inject(Object.assign({ method: "PATCH", url }, options)),
640
+ delete: (url, options) => this.app.inject(Object.assign({ method: "DELETE", url }, options)),
641
+ options: (url, options) => this.app.inject(Object.assign({ method: "OPTIONS", url }, options)),
642
+ };
595
643
  }
596
644
  catch (error) {
597
645
  throw new system_exception_1.SystemUseError("Can't get test appliction");
@@ -613,12 +661,12 @@ class TestBuilder {
613
661
  getService(service) {
614
662
  return typedi_1.default.get(service);
615
663
  }
616
- async getTestApplication(options) {
664
+ getTestApplication(options) {
617
665
  const app = AvleonApplication.getInternalApp({
618
666
  dataSourceOptions: this.dataSourceOptions,
619
667
  });
620
668
  app.mapControllers([...options.controllers]);
621
- const fa = await app.getTestApp();
669
+ const fa = app.getTestApp();
622
670
  return fa;
623
671
  }
624
672
  build(app) {
@@ -636,22 +684,12 @@ class Builder {
636
684
  this.testBuilder = false;
637
685
  this.appConfig = new config_1.AppConfig();
638
686
  }
639
- getTestApplication() {
640
- throw new Error("Method not implemented.");
641
- }
642
687
  static createAppBuilder() {
643
688
  if (!Builder.instance) {
644
689
  Builder.instance = new Builder();
645
690
  }
646
691
  return Builder.instance;
647
692
  }
648
- static creatTestAppBuilder() {
649
- if (!Builder.instance) {
650
- Builder.instance = new Builder();
651
- Builder.instance.testBuilder = true;
652
- }
653
- return Builder.instance;
654
- }
655
693
  async registerPlugin(plugin, options) {
656
694
  container_1.default.set(plugin, plugin.prototype);
657
695
  }
@@ -665,28 +703,6 @@ class Builder {
665
703
  this.dataSourceOptions = openApiConfig;
666
704
  }
667
705
  }
668
- createTestApplication(buildOptions) {
669
- return {
670
- addDataSource: (dataSourceOptions) => (this.dataSourceOptions = dataSourceOptions),
671
- getApp: async (options) => {
672
- const app = AvleonApplication.getInternalApp({
673
- database: this.database,
674
- dataSourceOptions: buildOptions.datSource,
675
- });
676
- app.mapControllers([...options.controllers]);
677
- const _tapp = await app.getTestApp();
678
- return {
679
- async get(url, options) {
680
- const res = await _tapp.inject(Object.assign({ url, method: "GET" }, options));
681
- return res;
682
- },
683
- };
684
- },
685
- getController(controller) {
686
- return typedi_1.default.get(controller);
687
- },
688
- };
689
- }
690
706
  build() {
691
707
  if (this.alreadyBuilt) {
692
708
  throw new Error("Already built");
package/dist/index.d.ts CHANGED
@@ -4,6 +4,7 @@
4
4
  * @email xtrinsic96@gmail.com
5
5
  * @url https://github.com/xtareq
6
6
  */
7
+ import * as sw from "./swagger-schema";
7
8
  export * from "./icore";
8
9
  export { inject, validateRequestBody } from "./helpers";
9
10
  export * from "./decorators";
@@ -21,4 +22,6 @@ export * from "./queue";
21
22
  export * from "./security";
22
23
  export * from "./multipart";
23
24
  export * from "./file-storage";
25
+ export * from "./logger";
26
+ export declare const GetSchema: typeof sw.generateSwaggerSchema;
24
27
  export { default as Container } from "./container";
package/dist/index.js CHANGED
@@ -1,10 +1,4 @@
1
1
  "use strict";
2
- /**
3
- * @copyright 2024
4
- * @author Tareq Hossain
5
- * @email xtrinsic96@gmail.com
6
- * @url https://github.com/xtareq
7
- */
8
2
  var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
3
  if (k2 === undefined) k2 = k;
10
4
  var desc = Object.getOwnPropertyDescriptor(m, k);
@@ -16,6 +10,28 @@ var __createBinding = (this && this.__createBinding) || (Object.create ? (functi
16
10
  if (k2 === undefined) k2 = k;
17
11
  o[k2] = m[k];
18
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 () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
19
35
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
20
36
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
37
  };
@@ -23,7 +39,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
23
39
  return (mod && mod.__esModule) ? mod : { "default": mod };
24
40
  };
25
41
  Object.defineProperty(exports, "__esModule", { value: true });
26
- exports.Container = exports.validateRequestBody = exports.inject = void 0;
42
+ exports.Container = exports.GetSchema = exports.validateRequestBody = exports.inject = void 0;
43
+ /**
44
+ * @copyright 2024
45
+ * @author Tareq Hossain
46
+ * @email xtrinsic96@gmail.com
47
+ * @url https://github.com/xtareq
48
+ */
49
+ const sw = __importStar(require("./swagger-schema"));
27
50
  __exportStar(require("./icore"), exports);
28
51
  var helpers_1 = require("./helpers");
29
52
  Object.defineProperty(exports, "inject", { enumerable: true, get: function () { return helpers_1.inject; } });
@@ -43,5 +66,7 @@ __exportStar(require("./queue"), exports);
43
66
  __exportStar(require("./security"), exports);
44
67
  __exportStar(require("./multipart"), exports);
45
68
  __exportStar(require("./file-storage"), exports);
69
+ __exportStar(require("./logger"), exports);
70
+ exports.GetSchema = sw.generateSwaggerSchema;
46
71
  var container_1 = require("./container");
47
72
  Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return __importDefault(container_1).default; } });
@@ -0,0 +1,12 @@
1
+ import pino from "pino";
2
+ export declare class LoggerService {
3
+ private logger;
4
+ constructor();
5
+ getLogger(): pino.Logger;
6
+ info(message: string, obj?: any): void;
7
+ error(message: string, obj?: any): void;
8
+ warn(message: string, obj?: any): void;
9
+ debug(message: string, obj?: any): void;
10
+ fatal(message: string, obj?: any): void;
11
+ trace(message: string, obj?: any): void;
12
+ }
package/dist/logger.js ADDED
@@ -0,0 +1,87 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.LoggerService = void 0;
16
+ const pino_1 = __importDefault(require("pino"));
17
+ const decorators_1 = require("./decorators");
18
+ let LoggerService = class LoggerService {
19
+ constructor() {
20
+ this.logger = (0, pino_1.default)({
21
+ level: process.env.LOG_LEVEL || "info",
22
+ transport: {
23
+ target: "pino-pretty",
24
+ options: {
25
+ translateTime: "SYS:standard",
26
+ ignore: "pid,hostname",
27
+ },
28
+ },
29
+ });
30
+ }
31
+ getLogger() {
32
+ return this.logger;
33
+ }
34
+ info(message, obj) {
35
+ if (obj) {
36
+ this.logger.info(obj, message);
37
+ }
38
+ else {
39
+ this.logger.info(message);
40
+ }
41
+ }
42
+ error(message, obj) {
43
+ if (obj) {
44
+ this.logger.error(obj, message);
45
+ }
46
+ else {
47
+ this.logger.error(message);
48
+ }
49
+ }
50
+ warn(message, obj) {
51
+ if (obj) {
52
+ this.logger.warn(obj, message);
53
+ }
54
+ else {
55
+ this.logger.warn(message);
56
+ }
57
+ }
58
+ debug(message, obj) {
59
+ if (obj) {
60
+ this.logger.debug(obj, message);
61
+ }
62
+ else {
63
+ this.logger.debug(message);
64
+ }
65
+ }
66
+ fatal(message, obj) {
67
+ if (obj) {
68
+ this.logger.fatal(obj, message);
69
+ }
70
+ else {
71
+ this.logger.fatal(message);
72
+ }
73
+ }
74
+ trace(message, obj) {
75
+ if (obj) {
76
+ this.logger.trace(obj, message);
77
+ }
78
+ else {
79
+ this.logger.trace(message);
80
+ }
81
+ }
82
+ };
83
+ exports.LoggerService = LoggerService;
84
+ exports.LoggerService = LoggerService = __decorate([
85
+ decorators_1.AppService,
86
+ __metadata("design:paramtypes", [])
87
+ ], LoggerService);
package/dist/openapi.d.ts CHANGED
@@ -36,7 +36,9 @@ interface ServerVariableObject {
36
36
  export type OpenApiUiOptions = {
37
37
  logo?: any;
38
38
  theme?: any;
39
+ ui?: "default" | "scalar";
39
40
  openapi?: string;
41
+ configuration?: any;
40
42
  routePrefix?: string;
41
43
  info?: InfoObject;
42
44
  servers?: ServerObject[];
package/dist/params.js CHANGED
@@ -9,6 +9,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.AuthUser = exports.Header = exports.Body = exports.Query = exports.Param = void 0;
10
10
  const container_1 = require("./container");
11
11
  const helpers_1 = require("./helpers");
12
+ const swagger_schema_1 = require("./swagger-schema");
12
13
  function createParamDecorator(type) {
13
14
  return function (key, options = {}) {
14
15
  return function (target, propertyKey, parameterIndex) {
@@ -27,6 +28,9 @@ function createParamDecorator(type) {
27
28
  validate: options.validate || true,
28
29
  dataType: (0, helpers_1.getDataType)(paramDataType),
29
30
  validatorClass: (0, helpers_1.isClassValidatorClass)(paramDataType),
31
+ schema: (0, helpers_1.isClassValidatorClass)(paramDataType)
32
+ ? (0, swagger_schema_1.generateSwaggerSchema)(paramDataType)
33
+ : null,
30
34
  type,
31
35
  });
32
36
  switch (type) {
@@ -4,7 +4,6 @@
4
4
  * @email xtrinsic96@gmail.com
5
5
  * @url https://github.com/xtareq
6
6
  */
7
- import "reflect-metadata";
8
7
  import { ClassConstructor } from "class-transformer";
9
8
  export interface IHttpResponse<T extends any> {
10
9
  message: string;
@@ -14,6 +13,8 @@ export declare class HttpResponse {
14
13
  static Ok<T>(obj: any, s?: ClassConstructor<T>): IHttpResponse<T>;
15
14
  static Created<T>(obj: any, s?: ClassConstructor<T>): IHttpResponse<T>;
16
15
  static NoContent(): IHttpResponse<null>;
16
+ }
17
+ export declare class HttpExceptions {
17
18
  static BadRequest(message: string, data?: any): IHttpResponse<any>;
18
19
  static Unauthorized(message: string, data?: any): IHttpResponse<any>;
19
20
  static Forbidden(message: string, data?: any): IHttpResponse<any>;
package/dist/response.js CHANGED
@@ -1,13 +1,12 @@
1
1
  "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpExceptions = exports.HttpResponse = void 0;
2
4
  /**
3
5
  * @copyright 2024
4
6
  * @author Tareq Hossain
5
7
  * @email xtrinsic96@gmail.com
6
8
  * @url https://github.com/xtareq
7
9
  */
8
- Object.defineProperty(exports, "__esModule", { value: true });
9
- exports.HttpResponse = void 0;
10
- require("reflect-metadata");
11
10
  const class_transformer_1 = require("class-transformer");
12
11
  function isClassTransformerClass(target) {
13
12
  const prototype = target.prototype;
@@ -49,6 +48,9 @@ class HttpResponse {
49
48
  static NoContent() {
50
49
  return { message: "no content", data: null };
51
50
  }
51
+ }
52
+ exports.HttpResponse = HttpResponse;
53
+ class HttpExceptions {
52
54
  static BadRequest(message, data = null) {
53
55
  return { message: message, data: data };
54
56
  }
@@ -74,4 +76,4 @@ class HttpResponse {
74
76
  return { message: message, data: data };
75
77
  }
76
78
  }
77
- exports.HttpResponse = HttpResponse;
79
+ exports.HttpExceptions = HttpExceptions;
@@ -1,7 +1 @@
1
- /**
2
- * @copyright 2024
3
- * @author Tareq Hossain
4
- * @email xtrinsic96@gmail.com
5
- * @url https://github.com/xtareq
6
- */
7
1
  export declare function generateSwaggerSchema(classType: any): any;
@@ -7,22 +7,28 @@ exports.generateSwaggerSchema = generateSwaggerSchema;
7
7
  * @email xtrinsic96@gmail.com
8
8
  * @url https://github.com/xtareq
9
9
  */
10
+ const class_validator_1 = require("class-validator");
10
11
  function generateSwaggerSchema(classType) {
11
- const { getMetadataStorage } = require("class-validator");
12
- const { plainToInstance } = require("class-transformer");
13
- //const { isArray } = require("lodash"); // Add lodash for array check
14
- const metadataStorage = getMetadataStorage();
15
- const validationMetadata = metadataStorage.getTargetValidationMetadatas(classType, "", true);
12
+ const metadataStorage = (0, class_validator_1.getMetadataStorage)();
13
+ const validationMetadata = metadataStorage.getTargetValidationMetadatas(classType, "", true, false);
16
14
  const schema = {
17
15
  type: "object",
18
16
  properties: {},
19
17
  required: [],
20
18
  };
21
- validationMetadata.forEach((meta) => {
22
- var _a, _b;
23
- const propertyName = meta.propertyName;
24
- // Infer the type dynamically using Reflect metadata
25
- const propertyType = Reflect.getMetadata("design:type", classType.prototype, propertyName);
19
+ const prototype = classType.prototype;
20
+ const propertyKeys = new Set([
21
+ ...Object.getOwnPropertyNames(prototype),
22
+ ...validationMetadata.map((m) => m.propertyName),
23
+ ]);
24
+ propertyKeys.forEach((propertyName) => {
25
+ var _a;
26
+ if (!propertyName || propertyName === "constructor")
27
+ return;
28
+ const openApiMeta = Reflect.getMetadata("property:openapi", prototype, propertyName);
29
+ if (openApiMeta === null || openApiMeta === void 0 ? void 0 : openApiMeta.exclude)
30
+ return;
31
+ const propertyType = Reflect.getMetadata("design:type", prototype, propertyName);
26
32
  let swaggerProperty = {};
27
33
  switch (propertyType) {
28
34
  case String:
@@ -39,85 +45,101 @@ function generateSwaggerSchema(classType) {
39
45
  swaggerProperty.format = "date-time";
40
46
  break;
41
47
  case Array:
42
- // Attempt to infer array item type
43
- const arrayItemType = Reflect.getMetadata("design:type", classType.prototype, propertyName + "[0]" // Attempt to get array item type. Very fragile.
44
- );
45
- if (arrayItemType) {
46
- swaggerProperty.type = "array";
47
- swaggerProperty.items = {
48
- type: arrayItemType.name.toLowerCase(), // basic type inference
49
- };
50
- if (arrayItemType === Object) {
51
- //try to infer the Object type within array
52
- const nestedSchema = generateSwaggerSchema(Reflect.getMetadata("design:type", classType.prototype, propertyName + "[0]"));
53
- swaggerProperty.items = nestedSchema;
54
- }
55
- }
56
- else {
57
- swaggerProperty.type = "array";
58
- swaggerProperty.items = {}; // Array of unknown type
59
- }
48
+ swaggerProperty.type = "array";
49
+ swaggerProperty.items = { type: "string" }; // fallback
60
50
  break;
61
51
  case Object:
62
- //Nested object
63
- const nestedSchema = generateSwaggerSchema(Reflect.getMetadata("design:type", classType.prototype, propertyName));
64
- swaggerProperty = nestedSchema;
52
+ swaggerProperty = generateSwaggerSchema(propertyType);
65
53
  break;
66
54
  default:
67
- swaggerProperty.type = ((_a = propertyType === null || propertyType === void 0 ? void 0 : propertyType.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "string"; // Default to string if type cannot be inferred
55
+ swaggerProperty.type = ((_a = propertyType === null || propertyType === void 0 ? void 0 : propertyType.name) === null || _a === void 0 ? void 0 : _a.toLowerCase()) || "string";
56
+ }
57
+ // Apply OpenApi metadata if present
58
+ if (openApiMeta) {
59
+ swaggerProperty = Object.assign(Object.assign({}, swaggerProperty), extractOpenApiFields(openApiMeta));
68
60
  }
69
61
  schema.properties[propertyName] = swaggerProperty;
70
- (_b = meta.constraints) === null || _b === void 0 ? void 0 : _b.forEach((constraint) => {
71
- switch (constraint.name) {
72
- case "isNotEmpty":
73
- if (!schema.required.includes(propertyName)) {
74
- schema.required.push(propertyName);
75
- }
76
- break;
77
- case "minLength":
78
- schema.properties[propertyName].minLength = constraint.constraints[0];
79
- break;
80
- case "maxLength":
81
- schema.properties[propertyName].maxLength = constraint.constraints[0];
82
- break;
83
- case "min":
84
- schema.properties[propertyName].minimum = constraint.constraints[0];
85
- break;
86
- case "max":
87
- schema.properties[propertyName].maximum = constraint.constraints[0];
88
- break;
89
- case "isEmail":
90
- schema.properties[propertyName].format = "email";
91
- break;
92
- case "isDate":
93
- schema.properties[propertyName].format = "date-time";
94
- break;
95
- case "isIn":
96
- schema.properties[propertyName].enum = constraint.constraints[0];
97
- break;
98
- case "isNumber":
99
- schema.properties[propertyName].type = "number";
100
- break;
101
- case "isInt":
102
- schema.properties[propertyName].type = "integer";
103
- break;
104
- case "isBoolean":
105
- schema.properties[propertyName].type = "boolean";
106
- break;
107
- case "isString":
108
- schema.properties[propertyName].type = "string";
109
- break;
110
- case "isOptional":
111
- if (schema.required.includes(propertyName)) {
112
- schema.required = schema.required.filter((item) => item !== propertyName);
113
- }
114
- break;
115
- // Add more cases for other validators as needed
116
- }
117
- });
62
+ });
63
+ // Handle validation rules
64
+ validationMetadata.forEach((meta) => {
65
+ const propertyName = meta.propertyName;
66
+ switch (meta.name) {
67
+ case "isNotEmpty":
68
+ if (!schema.required.includes(propertyName)) {
69
+ schema.required.push(propertyName);
70
+ }
71
+ break;
72
+ case "isDefined":
73
+ if (!schema.required.includes(propertyName)) {
74
+ schema.required.push(propertyName);
75
+ }
76
+ break;
77
+ case "isOptional":
78
+ schema.required = schema.required.filter((item) => item !== propertyName);
79
+ break;
80
+ case "minLength":
81
+ schema.properties[propertyName].minLength = meta.constraints[0];
82
+ break;
83
+ case "maxLength":
84
+ schema.properties[propertyName].maxLength = meta.constraints[0];
85
+ break;
86
+ case "min":
87
+ schema.properties[propertyName].minimum = meta.constraints[0];
88
+ break;
89
+ case "max":
90
+ schema.properties[propertyName].maximum = meta.constraints[0];
91
+ break;
92
+ case "isEmail":
93
+ schema.properties[propertyName].format = "email";
94
+ break;
95
+ case "isDate":
96
+ schema.properties[propertyName].format = "date-time";
97
+ break;
98
+ case "isIn":
99
+ schema.properties[propertyName].enum = meta.constraints[0];
100
+ break;
101
+ case "isNumber":
102
+ schema.properties[propertyName].type = "number";
103
+ break;
104
+ case "isInt":
105
+ schema.properties[propertyName].type = "integer";
106
+ break;
107
+ case "isBoolean":
108
+ schema.properties[propertyName].type = "boolean";
109
+ break;
110
+ case "isString":
111
+ schema.properties[propertyName].type = "string";
112
+ break;
113
+ }
118
114
  });
119
115
  return schema;
120
116
  }
117
+ function extractOpenApiFields(meta) {
118
+ const result = {};
119
+ const fields = [
120
+ "description",
121
+ "summary",
122
+ "deprecated",
123
+ "example",
124
+ "enum",
125
+ "format",
126
+ "default",
127
+ "minimum",
128
+ "maximum",
129
+ "minLength",
130
+ "maxLength",
131
+ "pattern",
132
+ "oneOf",
133
+ "allOf",
134
+ "anyOf",
135
+ ];
136
+ fields.forEach((field) => {
137
+ if (meta[field] !== undefined) {
138
+ result[field] = meta[field];
139
+ }
140
+ });
141
+ return result;
142
+ }
121
143
  // export function generateSwaggerSchema(classType: any) {
122
144
  // const { getMetadataStorage } = require("class-validator");
123
145
  // const { plainToInstance } = require("class-transformer");
package/package.json CHANGED
@@ -1,52 +1,58 @@
1
- {
2
- "name": "@avleon/core",
3
- "version": "0.0.13",
4
- "main": "./dist/index.js",
5
- "scripts": {
6
- "build": "rimraf dist && tsc",
7
- "watch": "tsc-watch",
8
- "test": "jest",
9
- "test:watch": "jest --watch"
10
- },
11
- "keywords": [],
12
- "author": "Tareq Hossain",
13
- "license": "ISC",
14
- "devDependencies": {
15
- "@types/jest": "^29.5.14",
16
- "class-transformer": "^0.5.1",
17
- "class-validator": "^0.14.1",
18
- "jest": "^29.7.0",
19
- "nodemon": "^3.1.7",
20
- "sharp": "^0.33.5",
21
- "ts-jest": "^29.2.5",
22
- "ts-node": "^10.9.2",
23
- "tsc-watch": "^6.2.1",
24
- "typeorm": "^0.3.20",
25
- "typescript": "^5.7.2"
26
- },
27
- "dependencies": {
28
- "@fastify/cors": "^11.0.0",
29
- "@fastify/multipart": "^9.0.3",
30
- "@fastify/static": "^8.1.1",
31
- "@fastify/swagger": "^9.4.0",
32
- "@fastify/swagger-ui": "^5.1.0",
33
- "bcryptjs": "^3.0.2",
34
- "dotenv": "^16.4.7",
35
- "fastify": "^5.1.0",
36
- "reflect-metadata": "^0.2.2",
37
- "typedi": "^0.10.0"
38
- },
39
- "peerDependencies": {
40
- "typeorm": "^0.3.20",
41
- "class-transformer": "^0.5.1",
42
- "class-validator": "^0.14.1"
43
- },
44
- "directories": {
45
- "test": "tests"
46
- },
47
- "description": "avleon core",
48
- "repository": {
49
- "type": "git",
50
- "url": "git+https://github.com/avleonjs/avleon-core"
51
- }
1
+ {
2
+ "name": "@avleon/core",
3
+ "version": "0.0.16",
4
+ "main": "./dist/index.js",
5
+ "scripts": {
6
+ "build": "rimraf dist && tsc",
7
+ "watch": "tsc-watch",
8
+ "test": "jest",
9
+ "test:watch": "jest --watch"
10
+ },
11
+ "keywords": [],
12
+ "author": "Tareq Hossain",
13
+ "license": "ISC",
14
+ "devDependencies": {
15
+ "@types/jest": "^29.5.14",
16
+ "@types/node": "^20.17.25",
17
+ "class-transformer": "^0.5.1",
18
+ "class-validator": "^0.14.1",
19
+ "jest": "^29.7.0",
20
+ "nodemon": "^3.1.7",
21
+ "sharp": "^0.33.5",
22
+ "ts-jest": "^29.2.5",
23
+ "ts-node": "^10.9.2",
24
+ "tsc-watch": "^6.2.1",
25
+ "typeorm": "^0.3.20",
26
+ "typescript": "^5.7.2"
27
+ },
28
+ "dependencies": {
29
+ "@fastify/cors": "^11.0.0",
30
+ "@fastify/multipart": "^9.0.3",
31
+ "@fastify/static": "^8.1.1",
32
+ "@fastify/swagger": "^9.4.0",
33
+ "@fastify/swagger-ui": "^5.1.0",
34
+ "bcryptjs": "^3.0.2",
35
+ "dotenv": "^16.4.7",
36
+ "fastify": "^5.1.0",
37
+ "pino": "^9.6.0",
38
+ "pino-pretty": "^13.0.0",
39
+ "reflect-metadata": "^0.2.2",
40
+ "typedi": "^0.10.0"
41
+ },
42
+ "peerDependencies": {
43
+ "class-transformer": "^0.5.1",
44
+ "class-validator": "^0.14.1",
45
+ "typeorm": "^0.3.20"
46
+ },
47
+ "optionalDependencies": {
48
+ "@scalar/fastify-api-reference": "^1.25.119"
49
+ },
50
+ "directories": {
51
+ "test": "tests"
52
+ },
53
+ "description": "avleon core",
54
+ "repository": {
55
+ "type": "git",
56
+ "url": "git+https://github.com/avleonjs/avleon-core"
57
+ }
52
58
  }