@avleon/core 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/authentication.d.ts +7 -0
- package/dist/authentication.js +11 -0
- package/dist/collection.d.ts +52 -0
- package/dist/collection.js +282 -0
- package/dist/config.d.ts +7 -8
- package/dist/config.js +10 -8
- package/dist/container.d.ts +5 -5
- package/dist/container.js +10 -13
- package/dist/controller.d.ts +2 -1
- package/dist/controller.js +17 -3
- package/dist/decorators.d.ts +2 -1
- package/dist/decorators.js +12 -2
- package/dist/environment-variables.d.ts +3 -0
- package/dist/environment-variables.js +33 -0
- package/dist/exceptions/http-exceptions.d.ts +24 -1
- package/dist/exceptions/http-exceptions.js +33 -2
- package/dist/helpers.d.ts +9 -1
- package/dist/helpers.js +78 -27
- package/dist/icore.d.ts +70 -16
- package/dist/icore.js +408 -135
- package/dist/index.d.ts +11 -6
- package/dist/index.js +7 -1
- package/dist/map-types.js +1 -2
- package/dist/middleware.d.ts +24 -0
- package/dist/middleware.js +59 -0
- package/dist/params.d.ts +1 -0
- package/dist/params.js +13 -9
- package/dist/queue.d.ts +30 -0
- package/dist/queue.js +96 -0
- package/dist/render.d.ts +1 -0
- package/dist/render.js +8 -0
- package/dist/response.d.ts +3 -2
- package/dist/response.js +9 -15
- package/dist/types/app-builder.interface.d.ts +9 -0
- package/dist/types/app-builder.interface.js +2 -0
- package/dist/types/application.interface.d.ts +2 -0
- package/dist/types/application.interface.js +2 -0
- package/dist/validation.d.ts +23 -0
- package/dist/validation.js +98 -0
- package/dist/validator-extend.js +2 -2
- package/package.json +45 -39
- package/dist/repository.d.ts +0 -0
- package/dist/repository.js +0 -1
package/dist/index.js
CHANGED
|
@@ -17,17 +17,23 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
17
17
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
18
18
|
};
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.Container = exports.inject = void 0;
|
|
20
|
+
exports.Container = exports.validateRequestBody = exports.inject = void 0;
|
|
21
21
|
//export * from "./iqra-core";
|
|
22
22
|
__exportStar(require("./icore"), exports);
|
|
23
23
|
var helpers_1 = require("./helpers");
|
|
24
24
|
Object.defineProperty(exports, "inject", { enumerable: true, get: function () { return helpers_1.inject; } });
|
|
25
|
+
Object.defineProperty(exports, "validateRequestBody", { enumerable: true, get: function () { return helpers_1.validateRequestBody; } });
|
|
25
26
|
__exportStar(require("./decorators"), exports);
|
|
27
|
+
__exportStar(require("./middleware"), exports);
|
|
26
28
|
__exportStar(require("./config"), exports);
|
|
27
29
|
__exportStar(require("./openapi"), exports);
|
|
28
30
|
__exportStar(require("./map-types"), exports);
|
|
29
31
|
__exportStar(require("./response"), exports);
|
|
30
32
|
__exportStar(require("./exceptions"), exports);
|
|
31
33
|
__exportStar(require("./validator-extend"), exports);
|
|
34
|
+
__exportStar(require("./validation"), exports);
|
|
35
|
+
__exportStar(require("./environment-variables"), exports);
|
|
36
|
+
__exportStar(require("./collection"), exports);
|
|
37
|
+
__exportStar(require("./queue"), exports);
|
|
32
38
|
var container_1 = require("./container");
|
|
33
39
|
Object.defineProperty(exports, "Container", { enumerable: true, get: function () { return __importDefault(container_1).default; } });
|
package/dist/map-types.js
CHANGED
|
@@ -19,8 +19,7 @@ function PartialType(BaseClass) {
|
|
|
19
19
|
}
|
|
20
20
|
// Retrieve validation metadata (class-validator)
|
|
21
21
|
const validationMetadata = Reflect.getMetadataKeys(currentPrototype, key);
|
|
22
|
-
validationMetadata.forEach((metadataKey) => {
|
|
23
|
-
});
|
|
22
|
+
validationMetadata.forEach((metadataKey) => { });
|
|
24
23
|
});
|
|
25
24
|
currentPrototype = Object.getPrototypeOf(currentPrototype); // Move up the prototype chain
|
|
26
25
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { IRequest, IResponse } from "./icore";
|
|
2
|
+
import { HttpException } from "./exceptions";
|
|
3
|
+
export declare abstract class AppMiddleware {
|
|
4
|
+
abstract invoke(req: IRequest, res?: IResponse): Promise<IRequest | HttpException>;
|
|
5
|
+
}
|
|
6
|
+
export type AuthHandler = (req: IRequest, roles?: string[]) => Promise<IRequest | HttpException>;
|
|
7
|
+
export type Constructor<T> = {
|
|
8
|
+
new (...args: any[]): T;
|
|
9
|
+
};
|
|
10
|
+
export declare abstract class AuthorizeMiddleware {
|
|
11
|
+
abstract authorize(roles: string[]): (req: IRequest, res?: IResponse) => IRequest | Promise<IRequest>;
|
|
12
|
+
}
|
|
13
|
+
export type AuthReturnTypes = IRequest | Promise<IRequest>;
|
|
14
|
+
interface AuthorizeClass {
|
|
15
|
+
authorize(req: IRequest, options?: any): AuthReturnTypes;
|
|
16
|
+
}
|
|
17
|
+
export declare function Authorize(target: {
|
|
18
|
+
new (...args: any[]): AuthorizeClass;
|
|
19
|
+
}): void;
|
|
20
|
+
export declare function Authorized(): ClassDecorator & MethodDecorator;
|
|
21
|
+
export declare function Authorized(options?: any): ClassDecorator & MethodDecorator;
|
|
22
|
+
export declare function Middleware(target: Constructor<AppMiddleware>): void;
|
|
23
|
+
export declare function UseMiddleware<T extends AppMiddleware | (new (...args: any[]) => AppMiddleware)>(options: T | T[]): MethodDecorator & ClassDecorator;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AuthorizeMiddleware = exports.AppMiddleware = void 0;
|
|
4
|
+
exports.Authorize = Authorize;
|
|
5
|
+
exports.Authorized = Authorized;
|
|
6
|
+
exports.Middleware = Middleware;
|
|
7
|
+
exports.UseMiddleware = UseMiddleware;
|
|
8
|
+
const typedi_1 = require("typedi");
|
|
9
|
+
const container_1 = require("./container");
|
|
10
|
+
class AppMiddleware {
|
|
11
|
+
}
|
|
12
|
+
exports.AppMiddleware = AppMiddleware;
|
|
13
|
+
class AuthorizeMiddleware {
|
|
14
|
+
}
|
|
15
|
+
exports.AuthorizeMiddleware = AuthorizeMiddleware;
|
|
16
|
+
function Authorize(target) {
|
|
17
|
+
if (typeof target.prototype.authorize !== "function") {
|
|
18
|
+
throw new Error(`Class "${target.name}" must implement an "authorize" method.`);
|
|
19
|
+
}
|
|
20
|
+
(0, typedi_1.Service)()(target);
|
|
21
|
+
}
|
|
22
|
+
function Authorized(options = {}) {
|
|
23
|
+
return function (target, propertyKey, descriptor) {
|
|
24
|
+
if (propertyKey && descriptor) {
|
|
25
|
+
Reflect.defineMetadata(container_1.AUTHORIZATION_META_KEY, { authorize: true, options }, target.constructor, propertyKey);
|
|
26
|
+
}
|
|
27
|
+
else {
|
|
28
|
+
Reflect.defineMetadata(container_1.AUTHORIZATION_META_KEY, { authorize: true, options }, target);
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function Middleware(target) {
|
|
33
|
+
if (typeof target.prototype.invoke !== "function") {
|
|
34
|
+
throw new Error(`Class "${target.name}" must implement an "invoke" method.`);
|
|
35
|
+
}
|
|
36
|
+
(0, typedi_1.Service)()(target);
|
|
37
|
+
}
|
|
38
|
+
// export function CurrentUser(): ParameterDecorator {
|
|
39
|
+
// return (target, propertyKey, parameterIndex) => {
|
|
40
|
+
// const existingMetadata =
|
|
41
|
+
// Reflect.getMetadata("currentUser:params", target, propertyKey!) || [];
|
|
42
|
+
// existingMetadata.push(parameterIndex);
|
|
43
|
+
// Reflect.defineMetadata("currentUser:params", existingMetadata, target, propertyKey!);
|
|
44
|
+
// };
|
|
45
|
+
// }
|
|
46
|
+
function UseMiddleware(options) {
|
|
47
|
+
return function (target, propertyKey, descriptor) {
|
|
48
|
+
const normalizeMiddleware = (middleware) => typeof middleware === "function" ? new middleware() : middleware;
|
|
49
|
+
const middlewareList = (Array.isArray(options) ? options : [options]).map(normalizeMiddleware);
|
|
50
|
+
if (typeof target === "function" && !propertyKey) {
|
|
51
|
+
const existingMiddlewares = Reflect.getMetadata("controller:middleware", target) || [];
|
|
52
|
+
Reflect.defineMetadata("controller:middleware", [...existingMiddlewares, ...middlewareList], target);
|
|
53
|
+
}
|
|
54
|
+
else if (descriptor) {
|
|
55
|
+
const existingMiddlewares = Reflect.getMetadata("route:middleware", target, propertyKey) || [];
|
|
56
|
+
Reflect.defineMetadata("route:middleware", [...existingMiddlewares, ...middlewareList], target, propertyKey);
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
package/dist/params.d.ts
CHANGED
|
@@ -13,4 +13,5 @@ export declare const Param: (key?: string | ParameterOptions, options?: Paramete
|
|
|
13
13
|
export declare const Query: (key?: string | ParameterOptions, options?: ParameterOptions) => ParameterDecorator;
|
|
14
14
|
export declare const Body: (key?: string | ParameterOptions, options?: ParameterOptions) => ParameterDecorator;
|
|
15
15
|
export declare const Header: (key?: string | ParameterOptions, options?: ParameterOptions) => ParameterDecorator;
|
|
16
|
+
export declare const AuthUser: (key?: string | ParameterOptions, options?: ParameterOptions) => ParameterDecorator;
|
|
16
17
|
export {};
|
package/dist/params.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Header = exports.Body = exports.Query = exports.Param = void 0;
|
|
3
|
+
exports.AuthUser = exports.Header = exports.Body = exports.Query = exports.Param = void 0;
|
|
4
4
|
const container_1 = require("./container");
|
|
5
5
|
const helpers_1 = require("./helpers");
|
|
6
6
|
function createParamDecorator(type) {
|
|
@@ -10,29 +10,33 @@ function createParamDecorator(type) {
|
|
|
10
10
|
const existingParams = Reflect.getMetadata(type, target, propertyKey) || [];
|
|
11
11
|
const parameterTypes = Reflect.getMetadata("design:paramtypes", target, propertyKey) || [];
|
|
12
12
|
const functionSource = target[propertyKey].toString();
|
|
13
|
-
const paramNames = (_a = functionSource
|
|
13
|
+
const paramNames = (_a = functionSource
|
|
14
|
+
.match(/\(([^)]*)\)/)) === null || _a === void 0 ? void 0 : _a[1].split(",").map((name) => name.trim());
|
|
14
15
|
const paramDataType = parameterTypes[parameterIndex];
|
|
15
16
|
existingParams.push({
|
|
16
17
|
index: parameterIndex,
|
|
17
|
-
key: key ? key :
|
|
18
|
+
key: key ? key : "all",
|
|
18
19
|
name: paramNames[parameterIndex],
|
|
19
20
|
required: options.required || false,
|
|
20
21
|
validate: options.validate || true,
|
|
21
22
|
dataType: (0, helpers_1.getDataType)(paramDataType),
|
|
22
23
|
validatorClass: (0, helpers_1.isClassValidatorClass)(paramDataType),
|
|
23
|
-
type
|
|
24
|
+
type,
|
|
24
25
|
});
|
|
25
26
|
switch (type) {
|
|
26
|
-
case
|
|
27
|
+
case "route:param":
|
|
27
28
|
Reflect.defineMetadata(container_1.PARAM_META_KEY, existingParams, target, propertyKey);
|
|
28
29
|
break;
|
|
29
|
-
case
|
|
30
|
+
case "route:query":
|
|
30
31
|
Reflect.defineMetadata(container_1.QUERY_META_KEY, existingParams, target, propertyKey);
|
|
31
32
|
break;
|
|
32
|
-
case
|
|
33
|
+
case "route:body":
|
|
33
34
|
Reflect.defineMetadata(container_1.REQUEST_BODY_META_KEY, existingParams, target, propertyKey);
|
|
34
35
|
break;
|
|
35
|
-
case
|
|
36
|
+
case "route:user":
|
|
37
|
+
Reflect.defineMetadata(container_1.REQUEST_USER_META_KEY, existingParams, target, propertyKey);
|
|
38
|
+
break;
|
|
39
|
+
case "route:header":
|
|
36
40
|
Reflect.defineMetadata(container_1.REQUEST_HEADER_META_KEY, existingParams, target, propertyKey);
|
|
37
41
|
break;
|
|
38
42
|
default:
|
|
@@ -45,4 +49,4 @@ exports.Param = createParamDecorator("route:param");
|
|
|
45
49
|
exports.Query = createParamDecorator("route:query");
|
|
46
50
|
exports.Body = createParamDecorator("route:body");
|
|
47
51
|
exports.Header = createParamDecorator("route:header");
|
|
48
|
-
|
|
52
|
+
exports.AuthUser = createParamDecorator("route:user");
|
package/dist/queue.d.ts
CHANGED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
interface Job {
|
|
2
|
+
id: string;
|
|
3
|
+
data: any;
|
|
4
|
+
}
|
|
5
|
+
interface QueueAdapter {
|
|
6
|
+
loadJobs(): Promise<Job[]>;
|
|
7
|
+
saveJobs(jobs: Job[]): Promise<void>;
|
|
8
|
+
}
|
|
9
|
+
export declare class FileQueueAdapter implements QueueAdapter {
|
|
10
|
+
private queueFile;
|
|
11
|
+
constructor(queueName: string);
|
|
12
|
+
loadJobs(): Promise<Job[]>;
|
|
13
|
+
saveJobs(jobs: Job[]): Promise<void>;
|
|
14
|
+
}
|
|
15
|
+
declare class SimpleQueue {
|
|
16
|
+
private processing;
|
|
17
|
+
private jobHandler;
|
|
18
|
+
private adapter;
|
|
19
|
+
constructor(adapter: QueueAdapter, jobHandler: (job: Job) => Promise<void>);
|
|
20
|
+
addJob(data: any): Promise<void>;
|
|
21
|
+
private processNext;
|
|
22
|
+
}
|
|
23
|
+
export declare class QueueManager {
|
|
24
|
+
private static instance;
|
|
25
|
+
private adapter;
|
|
26
|
+
private constructor();
|
|
27
|
+
static getInstance(adapter: QueueAdapter): QueueManager;
|
|
28
|
+
createQueue(jobHandler: (job: Job) => Promise<void>): SimpleQueue;
|
|
29
|
+
}
|
|
30
|
+
export {};
|
package/dist/queue.js
CHANGED
|
@@ -1 +1,97 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QueueManager = exports.FileQueueAdapter = void 0;
|
|
4
|
+
const fs_1 = require("fs");
|
|
5
|
+
const path_1 = require("path");
|
|
6
|
+
const helpers_1 = require("./helpers");
|
|
7
|
+
class FileQueueAdapter {
|
|
8
|
+
constructor(queueName) {
|
|
9
|
+
this.queueFile = (0, path_1.join)(__dirname, `${queueName}.json`);
|
|
10
|
+
}
|
|
11
|
+
async loadJobs() {
|
|
12
|
+
try {
|
|
13
|
+
const data = await fs_1.promises.readFile(this.queueFile, "utf-8");
|
|
14
|
+
return JSON.parse(data);
|
|
15
|
+
}
|
|
16
|
+
catch (error) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
async saveJobs(jobs) {
|
|
21
|
+
await fs_1.promises.writeFile(this.queueFile, JSON.stringify(jobs, null, 2), "utf-8");
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.FileQueueAdapter = FileQueueAdapter;
|
|
25
|
+
// class RedisQueueAdapter implements QueueAdapter {
|
|
26
|
+
// private client = createClient();
|
|
27
|
+
// private queueKey: string;
|
|
28
|
+
//
|
|
29
|
+
// constructor(queueName: string) {
|
|
30
|
+
// this.queueKey = `queue:${queueName}`;
|
|
31
|
+
// this.client.connect();
|
|
32
|
+
// }
|
|
33
|
+
//
|
|
34
|
+
// async loadJobs(): Promise<Job[]> {
|
|
35
|
+
// const jobs = await this.client.lRange(this.queueKey, 0, -1);
|
|
36
|
+
// return jobs.map((job) => JSON.parse(job));
|
|
37
|
+
// }
|
|
38
|
+
//
|
|
39
|
+
// async saveJobs(jobs: Job[]) {
|
|
40
|
+
// await this.client.del(this.queueKey);
|
|
41
|
+
// if (jobs.length > 0) {
|
|
42
|
+
// await this.client.rPush(this.queueKey, ...jobs.map(job => JSON.stringify(job)));
|
|
43
|
+
// }
|
|
44
|
+
// }
|
|
45
|
+
// }
|
|
46
|
+
class SimpleQueue {
|
|
47
|
+
constructor(adapter, jobHandler) {
|
|
48
|
+
this.processing = false;
|
|
49
|
+
this.adapter = adapter;
|
|
50
|
+
this.jobHandler = jobHandler;
|
|
51
|
+
}
|
|
52
|
+
async addJob(data) {
|
|
53
|
+
const job = { id: helpers_1.uuid, data };
|
|
54
|
+
const jobs = await this.adapter.loadJobs();
|
|
55
|
+
jobs.push(job);
|
|
56
|
+
await this.adapter.saveJobs(jobs);
|
|
57
|
+
this.processNext();
|
|
58
|
+
}
|
|
59
|
+
async processNext() {
|
|
60
|
+
if (this.processing)
|
|
61
|
+
return;
|
|
62
|
+
this.processing = true;
|
|
63
|
+
const jobs = await this.adapter.loadJobs();
|
|
64
|
+
if (jobs.length === 0) {
|
|
65
|
+
this.processing = false;
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
const job = jobs.shift();
|
|
69
|
+
if (job) {
|
|
70
|
+
try {
|
|
71
|
+
await this.jobHandler(job);
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
console.error(`Error processing job ${job.id}:`, error);
|
|
75
|
+
jobs.unshift(job);
|
|
76
|
+
}
|
|
77
|
+
await this.adapter.saveJobs(jobs);
|
|
78
|
+
this.processing = false;
|
|
79
|
+
this.processNext();
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
class QueueManager {
|
|
84
|
+
constructor(adapter) {
|
|
85
|
+
this.adapter = adapter;
|
|
86
|
+
}
|
|
87
|
+
static getInstance(adapter) {
|
|
88
|
+
if (!QueueManager.instance) {
|
|
89
|
+
QueueManager.instance = new QueueManager(adapter);
|
|
90
|
+
}
|
|
91
|
+
return QueueManager.instance;
|
|
92
|
+
}
|
|
93
|
+
createQueue(jobHandler) {
|
|
94
|
+
return new SimpleQueue(this.adapter, jobHandler);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
exports.QueueManager = QueueManager;
|
package/dist/render.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function render(viewPath: string, data: any): void;
|
package/dist/render.js
ADDED
package/dist/response.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import
|
|
1
|
+
import "reflect-metadata";
|
|
2
|
+
import { ClassConstructor } from "class-transformer";
|
|
2
3
|
export interface IHttpResponse<T extends any> {
|
|
3
4
|
message: string;
|
|
4
5
|
data: T | null;
|
|
5
6
|
}
|
|
6
7
|
export declare class HttpResponse {
|
|
7
|
-
static Ok<T
|
|
8
|
+
static Ok<T>(obj: any, s?: ClassConstructor<T>): any;
|
|
8
9
|
static NoContent(): void;
|
|
9
10
|
}
|
package/dist/response.js
CHANGED
|
@@ -7,7 +7,7 @@ function isClassTransformerClass(target) {
|
|
|
7
7
|
const prototype = target.prototype;
|
|
8
8
|
const keys = Reflect.getMetadataKeys(prototype);
|
|
9
9
|
// Check for class-transformer metadata
|
|
10
|
-
return keys.some(key => key.startsWith(
|
|
10
|
+
return keys.some((key) => key.startsWith("class_transformer:"));
|
|
11
11
|
}
|
|
12
12
|
function isClassTransformerType(target) {
|
|
13
13
|
return isClassTransformerClass(target);
|
|
@@ -15,21 +15,15 @@ function isClassTransformerType(target) {
|
|
|
15
15
|
class HttpResponse {
|
|
16
16
|
static Ok(obj, s) {
|
|
17
17
|
if (s) {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
else {
|
|
27
|
-
return { message: "success", data };
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
else {
|
|
31
|
-
return { message: "success", data: obj };
|
|
18
|
+
const isPaginated = obj === null || obj === void 0 ? void 0 : obj.hasOwnProperty("total");
|
|
19
|
+
// Ensure transformation applies only allowed properties
|
|
20
|
+
const transformedData = (0, class_transformer_1.plainToInstance)(s, isPaginated ? obj.data : obj, {
|
|
21
|
+
enableImplicitConversion: true,
|
|
22
|
+
excludeExtraneousValues: true, // Ensures only @Expose() properties are included
|
|
23
|
+
});
|
|
24
|
+
return Object.assign({ message: "success" }, (isPaginated ? Object.assign(Object.assign({}, obj), { data: (0, class_transformer_1.instanceToPlain)(transformedData) }) : { data: (0, class_transformer_1.instanceToPlain)(transformedData) }));
|
|
32
25
|
}
|
|
26
|
+
return { message: "success", data: obj };
|
|
33
27
|
}
|
|
34
28
|
static NoContent() { }
|
|
35
29
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
type BaseRule = {
|
|
2
|
+
required?: boolean;
|
|
3
|
+
optional?: boolean;
|
|
4
|
+
message?: string;
|
|
5
|
+
};
|
|
6
|
+
type StringRule = BaseRule & {
|
|
7
|
+
type: "string";
|
|
8
|
+
};
|
|
9
|
+
type NumberRule = BaseRule & {
|
|
10
|
+
type: "number";
|
|
11
|
+
min?: number;
|
|
12
|
+
max?: number;
|
|
13
|
+
exact?: number;
|
|
14
|
+
};
|
|
15
|
+
type BooleanRule = BaseRule & {
|
|
16
|
+
type: "boolean";
|
|
17
|
+
};
|
|
18
|
+
export type ValidationRule = StringRule | NumberRule | BooleanRule;
|
|
19
|
+
export type ValidationProps = {
|
|
20
|
+
[key: string]: ValidationRule;
|
|
21
|
+
};
|
|
22
|
+
export declare function validateOrThrow<T extends {}>(obj: T, rules: ValidationProps): any;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateOrThrow = validateOrThrow;
|
|
4
|
+
const exceptions_1 = require("./exceptions");
|
|
5
|
+
class PValidationRule {
|
|
6
|
+
constructor(name, type, message) {
|
|
7
|
+
this.name = name;
|
|
8
|
+
this.type = type;
|
|
9
|
+
this.message = message;
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
class Validator {
|
|
13
|
+
constructor(obj) {
|
|
14
|
+
this.rules = [];
|
|
15
|
+
this.init(obj);
|
|
16
|
+
}
|
|
17
|
+
init(obj) {
|
|
18
|
+
Object.keys(obj).forEach((key) => {
|
|
19
|
+
const rule = obj[key];
|
|
20
|
+
this.rules.push(new PValidationRule(key, rule.type, rule.message));
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
validate(obj) {
|
|
24
|
+
const erors = [];
|
|
25
|
+
this.rules.forEach((k) => {
|
|
26
|
+
const r = Object.keys(obj).find((key) => key == k.name);
|
|
27
|
+
let messages = [];
|
|
28
|
+
if (!r || obj[r] == undefined || obj[r] == "") {
|
|
29
|
+
messages.push({
|
|
30
|
+
constraint: "required",
|
|
31
|
+
message: k.name + " is required",
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
if (k.type == "string" && typeof obj[k.name] != "string") {
|
|
35
|
+
messages.push({
|
|
36
|
+
constraint: "type",
|
|
37
|
+
message: `${k.name} must be type ${k.type}`,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (k.type == "number" && !parseInt(obj[k.name])) {
|
|
41
|
+
messages.push({
|
|
42
|
+
constraint: "type",
|
|
43
|
+
message: `${k.name} must be type ${k.type}`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
if (k.type == "number") {
|
|
47
|
+
obj[k.name] = parseInt(obj[k.name]);
|
|
48
|
+
}
|
|
49
|
+
if (k.type == "boolean" && !isBool(obj[k.name])) {
|
|
50
|
+
messages.push({
|
|
51
|
+
constraint: "type",
|
|
52
|
+
message: `${k.name} must be type ${k.type}`,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
if (k.type == "boolean") {
|
|
56
|
+
obj[k.name] = parseBoolean(obj[k.name]);
|
|
57
|
+
}
|
|
58
|
+
if (messages.length > 0) {
|
|
59
|
+
erors.push({
|
|
60
|
+
path: k.name,
|
|
61
|
+
messages: messages,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
return [erors, obj];
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
const isBool = (val) => {
|
|
69
|
+
if (typeof val == "boolean")
|
|
70
|
+
return true;
|
|
71
|
+
if (parseInt(val) == 0 || parseInt(val) == 1)
|
|
72
|
+
return true;
|
|
73
|
+
if (val == "true" || val == "false")
|
|
74
|
+
return true;
|
|
75
|
+
return false;
|
|
76
|
+
};
|
|
77
|
+
const parseBoolean = (val) => {
|
|
78
|
+
if (typeof val === "boolean")
|
|
79
|
+
return val;
|
|
80
|
+
// if (typeof val === "number") {
|
|
81
|
+
// return val !== 0; // Common convention: 0 → false, any other number → true
|
|
82
|
+
// }
|
|
83
|
+
if (parseInt(val) == 1)
|
|
84
|
+
return true;
|
|
85
|
+
if (typeof val === "string") {
|
|
86
|
+
const normalized = val.trim().toLowerCase();
|
|
87
|
+
return normalized === "true";
|
|
88
|
+
}
|
|
89
|
+
return false; // Default for unsupported types (null, undefined, objects, etc.)
|
|
90
|
+
};
|
|
91
|
+
function validateOrThrow(obj, rules) {
|
|
92
|
+
const valid = new Validator(rules);
|
|
93
|
+
const errors = valid.validate(obj);
|
|
94
|
+
if (errors[0].length > 0) {
|
|
95
|
+
throw new exceptions_1.BadRequestException(errors[0]);
|
|
96
|
+
}
|
|
97
|
+
return errors[1];
|
|
98
|
+
}
|
package/dist/validator-extend.js
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.IsArrayNotEmpty = IsArrayNotEmpty;
|
|
4
4
|
function IsArrayNotEmpty(validationOptions) {
|
|
5
|
-
const { registerDecorator, ValidationArguments } = require(
|
|
5
|
+
const { registerDecorator, ValidationArguments } = require("class-validator");
|
|
6
6
|
return function (object, propertyName) {
|
|
7
7
|
registerDecorator({
|
|
8
|
-
name:
|
|
8
|
+
name: "isArrayWithAtLeastOneElement",
|
|
9
9
|
target: object.constructor,
|
|
10
10
|
propertyName: propertyName,
|
|
11
11
|
options: validationOptions,
|
package/package.json
CHANGED
|
@@ -1,39 +1,45 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@avleon/core",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"main": "./dist/index.js",
|
|
5
|
-
"types": "./dist/index.d.ts",
|
|
6
|
-
"scripts": {
|
|
7
|
-
"build": "rimraf dist && tsc",
|
|
8
|
-
"watch": "tsc-watch",
|
|
9
|
-
"test": "jest",
|
|
10
|
-
"test:watch": "jest --watch"
|
|
11
|
-
},
|
|
12
|
-
"keywords": [],
|
|
13
|
-
"author": "Tareq Hossain",
|
|
14
|
-
"license": "ISC",
|
|
15
|
-
"devDependencies": {
|
|
16
|
-
"@types/jest": "^29.5.14",
|
|
17
|
-
"jest": "^29.7.0",
|
|
18
|
-
"nodemon": "^3.1.7",
|
|
19
|
-
"ts-jest": "^29.2.5",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"@fastify/
|
|
26
|
-
"
|
|
27
|
-
"fastify": "^5.1.0",
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
"
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "@avleon/core",
|
|
3
|
+
"version": "0.0.6",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"types": "./dist/index.d.ts",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "rimraf dist && tsc",
|
|
8
|
+
"watch": "tsc-watch",
|
|
9
|
+
"test": "jest",
|
|
10
|
+
"test:watch": "jest --watch"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [],
|
|
13
|
+
"author": "Tareq Hossain",
|
|
14
|
+
"license": "ISC",
|
|
15
|
+
"devDependencies": {
|
|
16
|
+
"@types/jest": "^29.5.14",
|
|
17
|
+
"jest": "^29.7.0",
|
|
18
|
+
"nodemon": "^3.1.7",
|
|
19
|
+
"ts-jest": "^29.2.5",
|
|
20
|
+
"ts-node": "^10.9.2",
|
|
21
|
+
"tsc-watch": "^6.2.1",
|
|
22
|
+
"typescript": "^5.7.2"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@fastify/static": "^8.1.1",
|
|
26
|
+
"@fastify/swagger": "^9.4.0",
|
|
27
|
+
"@fastify/swagger-ui": "^5.1.0",
|
|
28
|
+
"@scalar/fastify-api-reference": "^1.25.122",
|
|
29
|
+
"class-transformer": "^0.5.1",
|
|
30
|
+
"class-validator": "^0.14.1",
|
|
31
|
+
"dotenv": "^16.4.7",
|
|
32
|
+
"fastify": "^5.1.0",
|
|
33
|
+
"reflect-metadata": "^0.2.2",
|
|
34
|
+
"typedi": "^0.10.0",
|
|
35
|
+
"typeorm": "^0.3.20"
|
|
36
|
+
},
|
|
37
|
+
"directories": {
|
|
38
|
+
"test": "tests"
|
|
39
|
+
},
|
|
40
|
+
"description": "avleon core",
|
|
41
|
+
"repository": {
|
|
42
|
+
"type": "git",
|
|
43
|
+
"url": "git+https://github.com/xtareq/avleon-core"
|
|
44
|
+
}
|
|
45
|
+
}
|
package/dist/repository.d.ts
DELETED
|
File without changes
|
package/dist/repository.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";
|