@vortenixinnovations/flagra-common-module 1.0.54 → 1.0.58
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/build/util/index.d.ts +0 -3
- package/build/util/index.js +0 -3
- package/package.json +4 -3
- package/build/util/error/errors.d.ts +0 -19
- package/build/util/error/errors.js +0 -38
- package/build/util/error/handler.d.ts +0 -3
- package/build/util/error/handler.js +0 -33
- package/build/util/error/index.d.ts +0 -3
- package/build/util/error/index.js +0 -3
- package/build/util/error/status-codes.d.ts +0 -7
- package/build/util/error/status-codes.js +0 -7
- package/build/util/error/validator.d.ts +0 -1
- package/build/util/error/validator.js +0 -14
- package/build/util/logger/index.d.ts +0 -3
- package/build/util/logger/index.js +0 -39
- package/build/util/validator.d.ts +0 -9
- package/build/util/validator.js +0 -43
package/build/util/index.d.ts
CHANGED
package/build/util/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vortenixinnovations/flagra-common-module",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.58",
|
|
4
4
|
"description": "common module of flagra",
|
|
5
5
|
"main": "./build/index.js",
|
|
6
6
|
"types": "./build/index.d.ts",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"clean": "del-cli ./build/*",
|
|
24
24
|
"build": "npm run clean && tsc",
|
|
25
|
-
"
|
|
25
|
+
"release": "npm version patch && npm run build && npm publish"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@sinclair/typebox": "^0.34.41",
|
|
@@ -33,7 +33,8 @@
|
|
|
33
33
|
"dotenv": "^17.2.3",
|
|
34
34
|
"express": "^5.1.0",
|
|
35
35
|
"pino": "^10.0.0",
|
|
36
|
-
"pino-http": "^11.0.0"
|
|
36
|
+
"pino-http": "^11.0.0",
|
|
37
|
+
"pino-pretty": "^13.0.0"
|
|
37
38
|
},
|
|
38
39
|
"devDependencies": {
|
|
39
40
|
"@types/express": "^5.0.3",
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
declare class BaseError extends Error {
|
|
2
|
-
readonly name: string;
|
|
3
|
-
readonly status: number;
|
|
4
|
-
readonly message: string;
|
|
5
|
-
constructor(name: string, status: number, description: string);
|
|
6
|
-
}
|
|
7
|
-
export declare class APIError extends BaseError {
|
|
8
|
-
constructor(description?: string);
|
|
9
|
-
}
|
|
10
|
-
export declare class ValidationError extends BaseError {
|
|
11
|
-
constructor(description?: string);
|
|
12
|
-
}
|
|
13
|
-
export declare class AuthorizeError extends BaseError {
|
|
14
|
-
constructor(description?: string);
|
|
15
|
-
}
|
|
16
|
-
export declare class NotFoundError extends BaseError {
|
|
17
|
-
constructor(description?: string);
|
|
18
|
-
}
|
|
19
|
-
export {};
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import { STATUS_CODES } from "./status-codes.js";
|
|
2
|
-
class BaseError extends Error {
|
|
3
|
-
name;
|
|
4
|
-
status;
|
|
5
|
-
message;
|
|
6
|
-
constructor(name, status, description) {
|
|
7
|
-
super(description);
|
|
8
|
-
this.name = name;
|
|
9
|
-
this.status = status;
|
|
10
|
-
this.message = description;
|
|
11
|
-
Object.setPrototypeOf(this, new.target.prototype);
|
|
12
|
-
Error.captureStackTrace(this);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
// 500 Internal Error
|
|
16
|
-
export class APIError extends BaseError {
|
|
17
|
-
constructor(description = "api error") {
|
|
18
|
-
super("api internal server error", STATUS_CODES.INTERNAL_ERROR, description);
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
// 400 Validation Error
|
|
22
|
-
export class ValidationError extends BaseError {
|
|
23
|
-
constructor(description = "bad request") {
|
|
24
|
-
super("bad request", STATUS_CODES.BAD_REQUEST, description);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
// 403 Authorize error
|
|
28
|
-
export class AuthorizeError extends BaseError {
|
|
29
|
-
constructor(description = "access denied") {
|
|
30
|
-
super("access denied", STATUS_CODES.UN_AUTHORISED, description);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
// 404 Not Found
|
|
34
|
-
export class NotFoundError extends BaseError {
|
|
35
|
-
constructor(description = "not found") {
|
|
36
|
-
super(description, STATUS_CODES.NOT_FOUND, description);
|
|
37
|
-
}
|
|
38
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { AuthorizeError, NotFoundError, ValidationError } from "./errors.js";
|
|
2
|
-
import { logger } from "../logger/index.js";
|
|
3
|
-
export const HandleErrorWithLogger = (error, req, res, next) => {
|
|
4
|
-
let reportError = true;
|
|
5
|
-
let status = 500;
|
|
6
|
-
let data = error.message;
|
|
7
|
-
// convert express-jwt UnauthorizedError to your AuthorizeError
|
|
8
|
-
if (error.name === "UnauthorizedError") {
|
|
9
|
-
error = new AuthorizeError(error.message);
|
|
10
|
-
}
|
|
11
|
-
// skip known errors
|
|
12
|
-
[NotFoundError, ValidationError, AuthorizeError].forEach((typeOfError) => {
|
|
13
|
-
if (error instanceof typeOfError) {
|
|
14
|
-
reportError = false;
|
|
15
|
-
status = error.status || 400;
|
|
16
|
-
data = error.message;
|
|
17
|
-
}
|
|
18
|
-
});
|
|
19
|
-
if (reportError) {
|
|
20
|
-
logger.error(error);
|
|
21
|
-
}
|
|
22
|
-
else {
|
|
23
|
-
// future use third party error reporting tools
|
|
24
|
-
logger.warn(error);
|
|
25
|
-
}
|
|
26
|
-
res.status(status).json({ error: data });
|
|
27
|
-
};
|
|
28
|
-
export const HandleUnCaughtException = async (error) => {
|
|
29
|
-
// error report / monitoring tools
|
|
30
|
-
logger.error(error);
|
|
31
|
-
// recover
|
|
32
|
-
process.exit(1);
|
|
33
|
-
};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare const ValidateError: (input: any) => Promise<Record<string, any> | false>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { validate } from "class-validator";
|
|
2
|
-
export const ValidateError = async (input) => {
|
|
3
|
-
const error = await validate(input, {
|
|
4
|
-
ValidationError: { target: true, property: true },
|
|
5
|
-
});
|
|
6
|
-
if (error.length) {
|
|
7
|
-
return error.map((err) => ({
|
|
8
|
-
field: err.property,
|
|
9
|
-
message: (err.constraints && Object.values(err.constraints)[0]) ||
|
|
10
|
-
"please provide input for this field",
|
|
11
|
-
}));
|
|
12
|
-
}
|
|
13
|
-
return false;
|
|
14
|
-
};
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import pino from "pino";
|
|
2
|
-
import { pinoHttp } from "pino-http";
|
|
3
|
-
import fs from "fs";
|
|
4
|
-
import path from "path";
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import dotenv from "dotenv";
|
|
7
|
-
dotenv.config();
|
|
8
|
-
const isProd = process.env.APP_ENV == "production";
|
|
9
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
10
|
-
const __dirname = path.dirname(__filename);
|
|
11
|
-
// Ensure logs directory exists
|
|
12
|
-
const logDir = path.resolve(__dirname, "../logs");
|
|
13
|
-
if (isProd && !fs.existsSync(logDir)) {
|
|
14
|
-
fs.mkdirSync(logDir, { recursive: true });
|
|
15
|
-
}
|
|
16
|
-
const destination = isProd
|
|
17
|
-
? pino.destination({ dest: path.join(logDir, "app.log"), sync: false }) // non-blocking file write
|
|
18
|
-
: undefined;
|
|
19
|
-
export const logger = pino({
|
|
20
|
-
level: "info",
|
|
21
|
-
timestamp: () => `,"time":"${new Date().toISOString()}"`,
|
|
22
|
-
...(isProd
|
|
23
|
-
? {} // No transport for production — raw JSON
|
|
24
|
-
: {
|
|
25
|
-
transport: {
|
|
26
|
-
target: "pino-pretty",
|
|
27
|
-
options: {
|
|
28
|
-
colorize: true,
|
|
29
|
-
translateTime: "SYS:standard",
|
|
30
|
-
ignore: "pid,hostname",
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
}),
|
|
34
|
-
}, destination // Only used in production
|
|
35
|
-
);
|
|
36
|
-
// HTTP request logger for Express
|
|
37
|
-
export const httpLogger = pinoHttp({
|
|
38
|
-
logger,
|
|
39
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { Static, TSchema } from "@sinclair/typebox";
|
|
2
|
-
export declare function sanitizeStrings<T>(input: T): T;
|
|
3
|
-
export declare function ValidateRequest<T extends TSchema>(data: unknown, schema: T): {
|
|
4
|
-
valid: true;
|
|
5
|
-
data: Static<T>;
|
|
6
|
-
} | {
|
|
7
|
-
valid: false;
|
|
8
|
-
error: string;
|
|
9
|
-
};
|
package/build/util/validator.js
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import Ajv from "ajv";
|
|
2
|
-
import ajvErrors from "ajv-errors";
|
|
3
|
-
import addFormats from "ajv-formats";
|
|
4
|
-
const ajv = new Ajv({ allErrors: true, strict: false, coerceTypes: true });
|
|
5
|
-
ajvErrors(ajv);
|
|
6
|
-
addFormats(ajv);
|
|
7
|
-
export function sanitizeStrings(input) {
|
|
8
|
-
if (input === null || input === undefined) {
|
|
9
|
-
return input;
|
|
10
|
-
}
|
|
11
|
-
if (typeof input === "string") {
|
|
12
|
-
return input.trim();
|
|
13
|
-
}
|
|
14
|
-
// Handle arrays recursively
|
|
15
|
-
if (Array.isArray(input)) {
|
|
16
|
-
return input.map((item) => sanitizeStrings(item));
|
|
17
|
-
}
|
|
18
|
-
// Handle objects recursively
|
|
19
|
-
if (typeof input === "object") {
|
|
20
|
-
const result = {};
|
|
21
|
-
for (const key in input) {
|
|
22
|
-
if (Object.prototype.hasOwnProperty.call(input, key)) {
|
|
23
|
-
result[key] = sanitizeStrings(input[key]);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return result;
|
|
27
|
-
}
|
|
28
|
-
// Return non-string primitive values as-is
|
|
29
|
-
return input;
|
|
30
|
-
}
|
|
31
|
-
// Generic validator function using TypeBox schemas
|
|
32
|
-
export function ValidateRequest(data, schema) {
|
|
33
|
-
const sanitizedData = sanitizeStrings(data);
|
|
34
|
-
const validate = ajv.compile(schema);
|
|
35
|
-
const isValid = validate(sanitizedData);
|
|
36
|
-
if (isValid)
|
|
37
|
-
return { valid: true, data: sanitizedData };
|
|
38
|
-
const errorMessages = validate.errors?.map((e) => e.message).filter(Boolean);
|
|
39
|
-
return {
|
|
40
|
-
valid: false,
|
|
41
|
-
error: errorMessages?.[0] || "Validation failed",
|
|
42
|
-
};
|
|
43
|
-
}
|