badmfck-api-server 2.9.8 → 2.9.9

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.
@@ -89,7 +89,7 @@ async function Initializer(services) {
89
89
  exports.Initializer = Initializer;
90
90
  class APIService extends BaseService_1.BaseService {
91
91
  static nextLogID = 0;
92
- version = "2.9.8";
92
+ version = "2.9.9";
93
93
  options;
94
94
  monitor = null;
95
95
  monitorIndexFile;
@@ -12,6 +12,7 @@ type IHandler = Record<HTTPMethod, ((req: HTTPRequestVO) => Promise<TransferPack
12
12
  controller: (req: HTTPRequestVO) => Promise<TransferPacketVO<any>>;
13
13
  ignoreInterceptor?: boolean;
14
14
  allowInterceptorError?: boolean;
15
+ validationModel?: any;
15
16
  asStream?: boolean;
16
17
  }>;
17
18
  export interface IEndpointHandler {
@@ -21,6 +22,7 @@ export interface IEndpointHandler {
21
22
  independed?: boolean;
22
23
  allowInterceptorError?: boolean;
23
24
  asStream?: boolean;
25
+ validationModel?: any;
24
26
  }
25
27
  export declare class BaseEndpoint implements IBaseEndpoint {
26
28
  private inializedEndpointNames;
@@ -36,6 +38,7 @@ export declare class BaseEndpoint implements IBaseEndpoint {
36
38
  getInitalizedEndpointNames(): String[];
37
39
  precheck(req: HTTPRequestVO): Promise<TransferPacketVO<any> | null>;
38
40
  execute(req: HTTPRequestVO): Promise<TransferPacketVO<any>>;
41
+ protected validateStructure(structure: any, req: HTTPRequestVO): Promise<void>;
39
42
  protected createStream(req: HTTPRequestVO): HTTPRequestVO;
40
43
  }
41
44
  export {};
@@ -4,6 +4,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.BaseEndpoint = void 0;
7
+ const Validator_1 = require("./helper/Validator");
7
8
  const LogService_1 = require("./LogService");
8
9
  const DefaultErrors_1 = __importDefault(require("./structures/DefaultErrors"));
9
10
  const stream_1 = require("stream");
@@ -71,10 +72,15 @@ class BaseEndpoint {
71
72
  let targetEP = BaseEndpoint.entrypoint + i.endpoint;
72
73
  targetEP = targetEP.replaceAll("//", "/");
73
74
  if (targetEP === req.endpoint) {
74
- if (i.handler && typeof i.handler === "function")
75
+ if (i.handler && typeof i.handler === "function") {
76
+ if (i.validationModel)
77
+ await this.validateStructure(i.validationModel, req);
75
78
  return i.handler.call(this, req);
79
+ }
76
80
  const httpMethod = req.method.toUpperCase();
77
81
  if (i.handler && i.handler[httpMethod] && typeof i.handler[httpMethod] === "function") {
82
+ if (i.validationModel)
83
+ await this.validateStructure(i.validationModel, req);
78
84
  if (i.asStream)
79
85
  req = this.createStream(req);
80
86
  return i.handler[httpMethod].call(this, req);
@@ -84,6 +90,9 @@ class BaseEndpoint {
84
90
  && typeof i.handler[httpMethod] === "object"
85
91
  && "controller" in i.handler[httpMethod]
86
92
  && typeof i.handler[httpMethod].controller === "function") {
93
+ const vmodel = i.handler[httpMethod].validationModel;
94
+ if (vmodel)
95
+ await this.validateStructure(vmodel, req);
87
96
  if (i.asStream)
88
97
  req = this.createStream(req);
89
98
  return i.handler[httpMethod].controller.call(this, req);
@@ -101,6 +110,15 @@ class BaseEndpoint {
101
110
  data: null
102
111
  };
103
112
  }
113
+ async validateStructure(structure, req) {
114
+ if (!structure)
115
+ return;
116
+ if (typeof structure === "object" && (!req.data || typeof req.data !== "object"))
117
+ throw { ...DefaultErrors_1.default.BAD_REQUEST, details: "empty or invalid request" };
118
+ const report = await Validator_1.Validator.validateStructure(structure, req.data);
119
+ if (report)
120
+ throw { ...DefaultErrors_1.default.BAD_REQUEST, details: report };
121
+ }
104
122
  createStream(req) {
105
123
  const res = req.response;
106
124
  res.setHeader('Content-Type', 'text/plain');
@@ -21,6 +21,7 @@ export declare enum ValidationReport {
21
21
  }
22
22
  export declare class Validator {
23
23
  static validateObject(fields: string[], object: any): boolean;
24
+ static validateStructure(structure: any, object: any): Promise<string[] | undefined>;
24
25
  static convertToType<T>(value: any, type: "string" | "number" | "boolean" | "date"): T | null;
25
26
  static validateValue(value: string | number | boolean, opt?: IValidatorOptions): ValidationReport;
26
27
  }
@@ -20,6 +20,70 @@ class Validator {
20
20
  }
21
21
  return true;
22
22
  }
23
+ static async validateStructure(structure, object) {
24
+ if (!structure)
25
+ return;
26
+ if (!object)
27
+ return ["no data"];
28
+ if (typeof structure !== "object") {
29
+ if (typeof object === "object")
30
+ return ["wrong datatype"];
31
+ if (typeof object !== typeof structure)
32
+ return ["datatype missmatch"];
33
+ return;
34
+ }
35
+ if (typeof structure === "function") {
36
+ let result = ['can`t validate data'];
37
+ try {
38
+ result = await structure(object);
39
+ }
40
+ catch (e) { }
41
+ return result;
42
+ }
43
+ let errors = [];
44
+ for (let i in structure) {
45
+ if (!(i in object))
46
+ errors.push("no field '" + i + "'");
47
+ if (typeof object[i] !== typeof structure[i])
48
+ errors.push("wrong datatype for field '" + i + "' expected " + typeof structure[i] + " got " + typeof object[i]);
49
+ if (typeof structure[i] === "object" || typeof structure[i] === "function") {
50
+ const result = await this.validateStructure(structure[i], object[i]);
51
+ if (result) {
52
+ for (let j of result)
53
+ errors.push(j);
54
+ }
55
+ }
56
+ if (typeof structure[i] === "string" && structure[i].includes(",")) {
57
+ const expected = structure[i].split(",").map((v) => v.trim().toLowerCase());
58
+ if (expected.length) {
59
+ const value = object[i].toString().toLowerCase().trim();
60
+ if (value.length === 0)
61
+ errors.push("empty value for field '" + i + "'");
62
+ else if (expected.indexOf(value) === -1)
63
+ errors.push("wrong value for field '" + i + "', expected " + expected.join(", ") + " got: " + value);
64
+ }
65
+ }
66
+ if (typeof structure[i] === "number") {
67
+ if (isNaN(object[i]))
68
+ errors.push("wrong value for field '" + i + "', expected number got " + object[i]);
69
+ if (structure[i] != 0) {
70
+ if (structure[i] > 0) {
71
+ const max = structure[i];
72
+ if (object[i] > max)
73
+ errors.push("value for field '" + i + "' is too big, expected less than " + max + " got: " + object[i]);
74
+ }
75
+ else {
76
+ const min = structure[i] * -1;
77
+ if (object[i] < min)
78
+ errors.push("value for field '" + i + "' is too small, expected more than " + min + " got: " + object[i]);
79
+ }
80
+ }
81
+ }
82
+ }
83
+ if (errors.length > 0)
84
+ return errors;
85
+ return;
86
+ }
23
87
  static convertToType(value, type) {
24
88
  if (value === null || value === undefined)
25
89
  return null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "badmfck-api-server",
3
- "version": "2.9.8",
3
+ "version": "2.9.9",
4
4
  "description": "Simple API http server based on express",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",