@avleon/core 0.0.13 → 0.0.14
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.
- package/dist/classToOpenapi.d.ts +0 -0
- package/dist/classToOpenapi.js +1 -0
- package/dist/exceptions/http-exceptions.d.ts +0 -9
- package/dist/exceptions/http-exceptions.js +17 -9
- package/dist/helpers.d.ts +2 -2
- package/dist/helpers.js +23 -17
- package/dist/icore.d.ts +21 -14
- package/dist/icore.js +52 -53
- package/dist/index.d.ts +3 -0
- package/dist/index.js +32 -7
- package/dist/logger.d.ts +12 -0
- package/dist/logger.js +87 -0
- package/dist/params.js +4 -0
- package/dist/response.d.ts +2 -1
- package/dist/response.js +6 -4
- package/dist/swagger-schema.d.ts +0 -6
- package/dist/swagger-schema.js +102 -80
- package/package.json +53 -51
|
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.
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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?:
|
|
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?:
|
|
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 !==
|
|
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 ===
|
|
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 ===
|
|
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 =
|
|
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 ==
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
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 =
|
|
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 ==
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
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 {
|
|
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
|
|
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):
|
|
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():
|
|
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):
|
|
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):
|
|
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):
|
|
197
|
-
build(app: IAvleonApplication):
|
|
198
|
-
fromApplication(app: IAvleonApplication):
|
|
206
|
+
getTestApplication(options: TestAppOptions): TestApplication;
|
|
207
|
+
build(app: IAvleonApplication): TestApplication;
|
|
208
|
+
fromApplication(app: IAvleonApplication): TestApplication;
|
|
199
209
|
}
|
|
200
|
-
export declare class Builder implements
|
|
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
|
}
|
|
@@ -163,8 +165,7 @@ class AvleonApplication {
|
|
|
163
165
|
}
|
|
164
166
|
useMultipart(options) {
|
|
165
167
|
this.multipartOptions = options;
|
|
166
|
-
this.app.register(multipart_1.default,
|
|
167
|
-
return this;
|
|
168
|
+
this.app.register(multipart_1.default, Object.assign(Object.assign({}, this.multipartOptions), { attachFieldsToBody: true }));
|
|
168
169
|
}
|
|
169
170
|
handleMiddlewares(mclasses) {
|
|
170
171
|
for (const mclass of mclasses) {
|
|
@@ -222,11 +223,21 @@ class AvleonApplication {
|
|
|
222
223
|
const swaggerMeta = Reflect.getMetadata("route:openapi", prototype, method) || {};
|
|
223
224
|
const authClsMethodMeata = Reflect.getMetadata(container_1.AUTHORIZATION_META_KEY, ctrl.constructor, method) || { authorize: false, options: undefined };
|
|
224
225
|
const allMeta = this._processMeta(prototype, method);
|
|
226
|
+
let bodySchema = null;
|
|
227
|
+
allMeta.body.forEach((r) => {
|
|
228
|
+
if (r.schema) {
|
|
229
|
+
bodySchema = Object.assign({}, r.schema);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
225
232
|
const routePath = methodmetaOptions.path == "" ? "/" : methodmetaOptions.path;
|
|
233
|
+
let schema = Object.assign(Object.assign(Object.assign({}, swaggerControllerMeta), swaggerMeta), { tags: [tag] });
|
|
234
|
+
if (!swaggerMeta.body && bodySchema) {
|
|
235
|
+
schema = Object.assign(Object.assign({}, schema), { body: bodySchema });
|
|
236
|
+
}
|
|
226
237
|
this.app.route({
|
|
227
238
|
url: routePath,
|
|
228
239
|
method: methodmetaOptions.method.toUpperCase(),
|
|
229
|
-
schema: Object.assign(
|
|
240
|
+
schema: Object.assign({}, schema),
|
|
230
241
|
handler: async (req, res) => {
|
|
231
242
|
let reqClone = req;
|
|
232
243
|
if (authClsMethodMeata.authorize && this.authorizeMiddleware) {
|
|
@@ -279,6 +290,7 @@ class AvleonApplication {
|
|
|
279
290
|
*/
|
|
280
291
|
async _mapArgs(req, meta) {
|
|
281
292
|
var _a, e_2, _b, _c, _d, e_3, _e, _f;
|
|
293
|
+
var _g;
|
|
282
294
|
if (!req.hasOwnProperty("_argsCache")) {
|
|
283
295
|
Object.defineProperty(req, "_argsCache", {
|
|
284
296
|
value: new Map(),
|
|
@@ -298,9 +310,9 @@ class AvleonApplication {
|
|
|
298
310
|
header.key === "all" ? req.headers : req.headers[header.key]));
|
|
299
311
|
if (meta.file) {
|
|
300
312
|
try {
|
|
301
|
-
for (var
|
|
302
|
-
_c =
|
|
303
|
-
|
|
313
|
+
for (var _h = true, _j = __asyncValues(meta.file), _k; _k = await _j.next(), _a = _k.done, !_a; _h = true) {
|
|
314
|
+
_c = _k.value;
|
|
315
|
+
_h = false;
|
|
304
316
|
let f = _c;
|
|
305
317
|
args[f.index] = await req.file();
|
|
306
318
|
}
|
|
@@ -308,12 +320,13 @@ class AvleonApplication {
|
|
|
308
320
|
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
309
321
|
finally {
|
|
310
322
|
try {
|
|
311
|
-
if (!
|
|
323
|
+
if (!_h && !_a && (_b = _j.return)) await _b.call(_j);
|
|
312
324
|
}
|
|
313
325
|
finally { if (e_2) throw e_2.error; }
|
|
314
326
|
}
|
|
315
327
|
}
|
|
316
|
-
if (meta.files
|
|
328
|
+
if (meta.files &&
|
|
329
|
+
((_g = req.headers["content-type"]) === null || _g === void 0 ? void 0 : _g.startsWith("multipart/form-data")) === true) {
|
|
317
330
|
const files = await req.saveRequestFiles();
|
|
318
331
|
if (!files || files.length === 0) {
|
|
319
332
|
throw new exceptions_1.BadRequestException({ error: "No files uploaded" });
|
|
@@ -328,9 +341,9 @@ class AvleonApplication {
|
|
|
328
341
|
fields: file.fields,
|
|
329
342
|
}));
|
|
330
343
|
try {
|
|
331
|
-
for (var
|
|
332
|
-
_f =
|
|
333
|
-
|
|
344
|
+
for (var _l = true, _m = __asyncValues(meta.files), _o; _o = await _m.next(), _d = _o.done, !_d; _l = true) {
|
|
345
|
+
_f = _o.value;
|
|
346
|
+
_l = false;
|
|
334
347
|
let f = _f;
|
|
335
348
|
const findex = fileInfo.findIndex((x) => x.fieldname == f.fieldName);
|
|
336
349
|
if (f.fieldName != "all" && findex == -1) {
|
|
@@ -345,7 +358,7 @@ class AvleonApplication {
|
|
|
345
358
|
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
346
359
|
finally {
|
|
347
360
|
try {
|
|
348
|
-
if (!
|
|
361
|
+
if (!_l && !_d && (_e = _m.return)) await _e.call(_m);
|
|
349
362
|
}
|
|
350
363
|
finally { if (e_3) throw e_3.error; }
|
|
351
364
|
}
|
|
@@ -402,6 +415,9 @@ class AvleonApplication {
|
|
|
402
415
|
if ((0, container_1.isApiController)(controller)) {
|
|
403
416
|
this.buildController(controller);
|
|
404
417
|
}
|
|
418
|
+
else {
|
|
419
|
+
throw new system_exception_1.SystemUseError("Not a api controller.");
|
|
420
|
+
}
|
|
405
421
|
}
|
|
406
422
|
}
|
|
407
423
|
}
|
|
@@ -555,16 +571,23 @@ class AvleonApplication {
|
|
|
555
571
|
await this.app.listen({ port });
|
|
556
572
|
console.log(`Application running on http://127.0.0.1:${port}`);
|
|
557
573
|
}
|
|
558
|
-
|
|
574
|
+
getTestApp(buildOptions) {
|
|
559
575
|
try {
|
|
560
576
|
if (buildOptions && buildOptions.addDataSource) {
|
|
561
|
-
const typeorm =
|
|
577
|
+
const typeorm = Promise.resolve().then(() => __importStar(require("typeorm")));
|
|
562
578
|
if (!typeorm) {
|
|
563
579
|
throw new system_exception_1.SystemUseError("TypeOrm not installed");
|
|
564
580
|
}
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
581
|
+
typeorm.then(async (t) => {
|
|
582
|
+
try {
|
|
583
|
+
const datasource = new t.DataSource(buildOptions.addDataSource);
|
|
584
|
+
typedi_1.default.set("idatasource", datasource);
|
|
585
|
+
await datasource.initialize();
|
|
586
|
+
}
|
|
587
|
+
catch (error) {
|
|
588
|
+
console.error("Database can't initialized.", error);
|
|
589
|
+
}
|
|
590
|
+
});
|
|
568
591
|
}
|
|
569
592
|
this._mapControllers();
|
|
570
593
|
this.rMap.forEach((value, key) => {
|
|
@@ -591,7 +614,15 @@ class AvleonApplication {
|
|
|
591
614
|
}
|
|
592
615
|
return res.status(handledErr.code).send(handledErr);
|
|
593
616
|
});
|
|
594
|
-
return this.app;
|
|
617
|
+
// return this.app as any;
|
|
618
|
+
return {
|
|
619
|
+
get: (url, options) => this.app.inject(Object.assign({ method: "GET", url }, options)),
|
|
620
|
+
post: (url, options) => this.app.inject(Object.assign({ method: "POST", url }, options)),
|
|
621
|
+
put: (url, options) => this.app.inject(Object.assign({ method: "PUT", url }, options)),
|
|
622
|
+
patch: (url, options) => this.app.inject(Object.assign({ method: "PATCH", url }, options)),
|
|
623
|
+
delete: (url, options) => this.app.inject(Object.assign({ method: "DELETE", url }, options)),
|
|
624
|
+
options: (url, options) => this.app.inject(Object.assign({ method: "OPTIONS", url }, options)),
|
|
625
|
+
};
|
|
595
626
|
}
|
|
596
627
|
catch (error) {
|
|
597
628
|
throw new system_exception_1.SystemUseError("Can't get test appliction");
|
|
@@ -613,12 +644,12 @@ class TestBuilder {
|
|
|
613
644
|
getService(service) {
|
|
614
645
|
return typedi_1.default.get(service);
|
|
615
646
|
}
|
|
616
|
-
|
|
647
|
+
getTestApplication(options) {
|
|
617
648
|
const app = AvleonApplication.getInternalApp({
|
|
618
649
|
dataSourceOptions: this.dataSourceOptions,
|
|
619
650
|
});
|
|
620
651
|
app.mapControllers([...options.controllers]);
|
|
621
|
-
const fa =
|
|
652
|
+
const fa = app.getTestApp();
|
|
622
653
|
return fa;
|
|
623
654
|
}
|
|
624
655
|
build(app) {
|
|
@@ -636,22 +667,12 @@ class Builder {
|
|
|
636
667
|
this.testBuilder = false;
|
|
637
668
|
this.appConfig = new config_1.AppConfig();
|
|
638
669
|
}
|
|
639
|
-
getTestApplication() {
|
|
640
|
-
throw new Error("Method not implemented.");
|
|
641
|
-
}
|
|
642
670
|
static createAppBuilder() {
|
|
643
671
|
if (!Builder.instance) {
|
|
644
672
|
Builder.instance = new Builder();
|
|
645
673
|
}
|
|
646
674
|
return Builder.instance;
|
|
647
675
|
}
|
|
648
|
-
static creatTestAppBuilder() {
|
|
649
|
-
if (!Builder.instance) {
|
|
650
|
-
Builder.instance = new Builder();
|
|
651
|
-
Builder.instance.testBuilder = true;
|
|
652
|
-
}
|
|
653
|
-
return Builder.instance;
|
|
654
|
-
}
|
|
655
676
|
async registerPlugin(plugin, options) {
|
|
656
677
|
container_1.default.set(plugin, plugin.prototype);
|
|
657
678
|
}
|
|
@@ -665,28 +686,6 @@ class Builder {
|
|
|
665
686
|
this.dataSourceOptions = openApiConfig;
|
|
666
687
|
}
|
|
667
688
|
}
|
|
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
689
|
build() {
|
|
691
690
|
if (this.alreadyBuilt) {
|
|
692
691
|
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; } });
|
package/dist/logger.d.ts
ADDED
|
@@ -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/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) {
|
package/dist/response.d.ts
CHANGED
|
@@ -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.
|
|
79
|
+
exports.HttpExceptions = HttpExceptions;
|
package/dist/swagger-schema.d.ts
CHANGED
package/dist/swagger-schema.js
CHANGED
|
@@ -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
|
|
12
|
-
const
|
|
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
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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
|
-
|
|
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";
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
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,54 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@avleon/core",
|
|
3
|
-
"version": "0.0.
|
|
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
|
-
"
|
|
37
|
-
"
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"class-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@avleon/core",
|
|
3
|
+
"version": "0.0.14",
|
|
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
|
+
"pino": "^9.6.0",
|
|
37
|
+
"pino-pretty": "^13.0.0",
|
|
38
|
+
"reflect-metadata": "^0.2.2",
|
|
39
|
+
"typedi": "^0.10.0"
|
|
40
|
+
},
|
|
41
|
+
"peerDependencies": {
|
|
42
|
+
"class-transformer": "^0.5.1",
|
|
43
|
+
"class-validator": "^0.14.1",
|
|
44
|
+
"typeorm": "^0.3.20"
|
|
45
|
+
},
|
|
46
|
+
"directories": {
|
|
47
|
+
"test": "tests"
|
|
48
|
+
},
|
|
49
|
+
"description": "avleon core",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/avleonjs/avleon-core"
|
|
53
|
+
}
|
|
52
54
|
}
|