@dwtechs/antity 0.14.0 → 0.15.0
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 +19 -76
- package/dist/antity.d.ts +5 -14
- package/dist/antity.js +41 -102
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -52,12 +52,8 @@ const entity = new Entity("consumers", [
|
|
|
52
52
|
min: 0,
|
|
53
53
|
max: 120,
|
|
54
54
|
typeCheck: true,
|
|
55
|
-
|
|
56
|
-
required: true,
|
|
55
|
+
need: ["PUT"],
|
|
57
56
|
safe: true,
|
|
58
|
-
sanitize: true,
|
|
59
|
-
normalize: true,
|
|
60
|
-
validate: true,
|
|
61
57
|
sanitizer: null,
|
|
62
58
|
normalizer: null,
|
|
63
59
|
validator: null,
|
|
@@ -68,12 +64,8 @@ const entity = new Entity("consumers", [
|
|
|
68
64
|
min: 0,
|
|
69
65
|
max: 255,
|
|
70
66
|
typeCheck: true,
|
|
71
|
-
|
|
72
|
-
required: true,
|
|
67
|
+
need: ["PUT"],
|
|
73
68
|
safe: true,
|
|
74
|
-
sanitize: true,
|
|
75
|
-
normalize: true,
|
|
76
|
-
validate: true,
|
|
77
69
|
sanitizer: null,
|
|
78
70
|
normalizer: normalizeName,
|
|
79
71
|
validator: null,
|
|
@@ -84,12 +76,8 @@ const entity = new Entity("consumers", [
|
|
|
84
76
|
min: 0,
|
|
85
77
|
max: 255,
|
|
86
78
|
typeCheck: true,
|
|
87
|
-
|
|
88
|
-
required: true,
|
|
79
|
+
need: ["PUT"],
|
|
89
80
|
safe: true,
|
|
90
|
-
sanitize: true,
|
|
91
|
-
normalize: true,
|
|
92
|
-
validate: true,
|
|
93
81
|
sanitizer: null,
|
|
94
82
|
normalizer: normalizeName,
|
|
95
83
|
validator: null,
|
|
@@ -100,12 +88,8 @@ const entity = new Entity("consumers", [
|
|
|
100
88
|
min: 0,
|
|
101
89
|
max: 255,
|
|
102
90
|
typeCheck: true,
|
|
103
|
-
|
|
104
|
-
required: true,
|
|
91
|
+
need: ["PUT"],
|
|
105
92
|
safe: true,
|
|
106
|
-
sanitize: true,
|
|
107
|
-
normalize: true,
|
|
108
|
-
validate: true,
|
|
109
93
|
sanitizer: null,
|
|
110
94
|
normalizer: normalizeNickname,
|
|
111
95
|
validator: null,
|
|
@@ -154,20 +138,16 @@ type Type =
|
|
|
154
138
|
"node" |
|
|
155
139
|
"object";
|
|
156
140
|
|
|
157
|
-
type Method = "
|
|
141
|
+
type Method = "PATCH" | "PUT" | "POST";
|
|
158
142
|
|
|
159
143
|
class Property {
|
|
160
144
|
key: string;
|
|
161
145
|
type: Type;
|
|
162
146
|
min: number | Date | null;
|
|
163
147
|
max: number | Date | null;
|
|
164
|
-
|
|
165
|
-
|
|
148
|
+
need: Method[];
|
|
149
|
+
send: boolean;
|
|
166
150
|
typeCheck: boolean;
|
|
167
|
-
methods: Method[];
|
|
168
|
-
sanitize: boolean;
|
|
169
|
-
normalize: boolean;
|
|
170
|
-
validate: boolean;
|
|
171
151
|
sanitizer: Function | null;
|
|
172
152
|
normalizer: Function | null;
|
|
173
153
|
validator: Function | null;
|
|
@@ -350,39 +330,6 @@ class Entity {
|
|
|
350
330
|
*/
|
|
351
331
|
validateOne: (req: Request, _res: Response, next: NextFunction) => void;
|
|
352
332
|
|
|
353
|
-
/**
|
|
354
|
-
* Checks, sanitizes, normalizes, and validates each row in req.body.rows according to property config and HTTP method.
|
|
355
|
-
*
|
|
356
|
-
* - Applies sanitization if `sanitize: true` and method matches
|
|
357
|
-
* - Applies normalization if `normalize: true` and method matches
|
|
358
|
-
* - Checks required properties and validates values
|
|
359
|
-
* - Calls next(error) on failure, next() on success
|
|
360
|
-
*
|
|
361
|
-
* @param {Request} req - Express request object containing rows
|
|
362
|
-
* @param {Response} _res - Express response object (not used)
|
|
363
|
-
* @param {NextFunction} next - Express next function
|
|
364
|
-
*
|
|
365
|
-
* @returns {void}
|
|
366
|
-
*
|
|
367
|
-
* **Input Properties Required:**
|
|
368
|
-
* - `req.body.rows` (array) - Array of objects to check
|
|
369
|
-
* - Each property config can specify sanitize, normalize, validate, required, etc.
|
|
370
|
-
*
|
|
371
|
-
* **Output Properties:**
|
|
372
|
-
* - Mutates `req.body.rows` with sanitized/normalized values
|
|
373
|
-
* - Calls next(error) if any row fails checks, next() if all pass
|
|
374
|
-
*
|
|
375
|
-
* @example
|
|
376
|
-
* ```typescript
|
|
377
|
-
* router.post('/entity', entity.check, (req, res) => {
|
|
378
|
-
* // req.body.rows are now sanitized, normalized, and validated
|
|
379
|
-
* res.json({ success: true });
|
|
380
|
-
* });
|
|
381
|
-
* ```
|
|
382
|
-
*/
|
|
383
|
-
check: (req: Request, _res: Response, next: NextFunction) => void;
|
|
384
|
-
}
|
|
385
|
-
|
|
386
333
|
```
|
|
387
334
|
**normalizeArray()**, **normalizeOne()**, **validateArray()**, and **validateOne()** methods are made to be used as Express.js middlewares.
|
|
388
335
|
|
|
@@ -423,22 +370,18 @@ Properties **min** and **max** of the password properties will override default
|
|
|
423
370
|
|
|
424
371
|
Any of these can be passed into the options object for each function.
|
|
425
372
|
|
|
426
|
-
| Name | Type
|
|
427
|
-
| :-------------- |
|
|
428
|
-
| key |
|
|
429
|
-
| type |
|
|
430
|
-
| min |
|
|
431
|
-
| max |
|
|
432
|
-
|
|
|
433
|
-
|
|
|
434
|
-
| typeCheck |
|
|
435
|
-
|
|
|
436
|
-
|
|
|
437
|
-
|
|
|
438
|
-
| validate | boolean | validate the property if true | true
|
|
439
|
-
| sanitizer | ((v:any) => any) \| null | Custom sanitizer function if sanitize is true | null
|
|
440
|
-
| normalizer | ((v:any) => any) \| null | Custop Normalizer function if normalize is true | null
|
|
441
|
-
| validator | ((v:any, min:number, max:number, typeCheck:boolean) => any) \| null | validator function if validate is true | null
|
|
373
|
+
| Name | Type | Description | Default value |
|
|
374
|
+
| :-------------- | :----------------------- | :----------------------------------------------- | :-------------- |
|
|
375
|
+
| key | string | Name of the property |
|
|
376
|
+
| type | Type | Type of the property |
|
|
377
|
+
| min | number \| Date | Minimum value if applicable | 0 \| 1900-01-01
|
|
378
|
+
| max | number \| Date | Maximum value if applicable | 999999999 \| 2200-12-31
|
|
379
|
+
| need | Methods[] | Property is required for the listed methods only | [ "POST", "PUT", "PATCH" ]
|
|
380
|
+
| send | boolean | Property is sent in the response | true
|
|
381
|
+
| typeCheck | boolean | Strict type check at validation | false
|
|
382
|
+
| sanitizer | ((v:any) => any) \| null | Custom sanitizer function | null
|
|
383
|
+
| normalizer | ((v:any) => any) \| null | Custom Normalizer function | null
|
|
384
|
+
| validator | ((v:any, min:number, max:number, typeCheck:boolean) => any) \| null | Custom validator | null
|
|
442
385
|
|
|
443
386
|
* *Min and max parameters are not used for boolean type*
|
|
444
387
|
* *TypeCheck Parameter is not used for boolean, string and array types*
|
package/dist/antity.d.ts
CHANGED
|
@@ -25,7 +25,7 @@ https://github.com/DWTechs/Antity.js
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
import type { Request, Response, NextFunction } from 'express';
|
|
28
|
-
declare const Methods: readonly [
|
|
28
|
+
declare const Methods: readonly ["PATCH", "PUT", "POST"];
|
|
29
29
|
type Method = typeof Methods[number];
|
|
30
30
|
type Type =
|
|
31
31
|
"boolean" |
|
|
@@ -72,7 +72,6 @@ declare class Entity {
|
|
|
72
72
|
normalizeOne: (req: Request, _res: Response, next: NextFunction) => void;
|
|
73
73
|
validateArray: (req: Request, _res: Response, next: NextFunction) => void;
|
|
74
74
|
validateOne: (req: Request, _res: Response, next: NextFunction) => void;
|
|
75
|
-
check: (req: Request, _res: Response, next: NextFunction) => void;
|
|
76
75
|
}
|
|
77
76
|
|
|
78
77
|
declare class Property {
|
|
@@ -81,13 +80,9 @@ declare class Property {
|
|
|
81
80
|
type: Type;
|
|
82
81
|
min: number | Date | null;
|
|
83
82
|
max: number | Date | null;
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
send: boolean;
|
|
84
|
+
need: Method[];
|
|
86
85
|
typeCheck: boolean;
|
|
87
|
-
methods: Method[];
|
|
88
|
-
sanitize: boolean;
|
|
89
|
-
normalize: boolean;
|
|
90
|
-
validate: boolean;
|
|
91
86
|
sanitizer: ((v: any) => any) | null;
|
|
92
87
|
normalizer: ((v: any) => any) | null;
|
|
93
88
|
validator: ((v: any) => any) | null;
|
|
@@ -96,13 +91,9 @@ declare class Property {
|
|
|
96
91
|
type: Type,
|
|
97
92
|
min: number | Date | null,
|
|
98
93
|
max: number | Date | null,
|
|
99
|
-
|
|
100
|
-
|
|
94
|
+
send: boolean,
|
|
95
|
+
need: Method[],
|
|
101
96
|
typeCheck: boolean,
|
|
102
|
-
methods: Method[],
|
|
103
|
-
sanitize: boolean,
|
|
104
|
-
normalize: boolean,
|
|
105
|
-
validate: boolean,
|
|
106
97
|
sanitizer: ((v: any) => any) | null,
|
|
107
98
|
normalizer: ((v: any) => any) | null,
|
|
108
99
|
validator: ((v: any) => any) | null
|
package/dist/antity.js
CHANGED
|
@@ -28,7 +28,7 @@ import { isBoolean, isStringOfLength, isValidNumber, isValidInteger, isValidFloa
|
|
|
28
28
|
import { log } from '@dwtechs/winstan';
|
|
29
29
|
|
|
30
30
|
const LOGS_PREFIX = "Antity: ";
|
|
31
|
-
const METHODS = ["
|
|
31
|
+
const METHODS = ["PATCH", "PUT", "POST"];
|
|
32
32
|
const { PWD_MIN_LENGTH_POLICY, PWD_MAX_LENGTH_POLICY, PWD_NUMBERS_POLICY, PWD_UPPERCASE_POLICY, PWD_LOWERCASE_POLICY, PWD_SYMBOLS_POLICY } = process.env;
|
|
33
33
|
const PWD_MIN_LENGTH = PWD_MIN_LENGTH_POLICY ? +PWD_MIN_LENGTH_POLICY : 9;
|
|
34
34
|
const PWD_MAX_LENGTH = PWD_MAX_LENGTH_POLICY ? +PWD_MAX_LENGTH_POLICY : 20;
|
|
@@ -135,7 +135,7 @@ const Types = {
|
|
|
135
135
|
};
|
|
136
136
|
|
|
137
137
|
class Property {
|
|
138
|
-
constructor(key, type, min, max,
|
|
138
|
+
constructor(key, type, min, max, send, need, typeCheck, sanitizer, normalizer, validator) {
|
|
139
139
|
try {
|
|
140
140
|
isString(key, "!0", null, true);
|
|
141
141
|
}
|
|
@@ -148,13 +148,13 @@ class Property {
|
|
|
148
148
|
catch (err) {
|
|
149
149
|
throw new Error(`${LOGS_PREFIX}Property "type" must be a valid type - caused by: ${err.message}`);
|
|
150
150
|
}
|
|
151
|
-
if (isArray(
|
|
152
|
-
for (const m of
|
|
151
|
+
if (isArray(need)) {
|
|
152
|
+
for (const m of need) {
|
|
153
153
|
try {
|
|
154
154
|
isIn(METHODS, m, 0, true);
|
|
155
155
|
}
|
|
156
156
|
catch (err) {
|
|
157
|
-
throw new Error(`${LOGS_PREFIX}Property "
|
|
157
|
+
throw new Error(`${LOGS_PREFIX}Property "need" must be an array of REST methods - caused by: ${err.message}`);
|
|
158
158
|
}
|
|
159
159
|
}
|
|
160
160
|
}
|
|
@@ -162,13 +162,9 @@ class Property {
|
|
|
162
162
|
this.type = type;
|
|
163
163
|
this.min = this.interval(min, type, 0, "1900-01-01T00:00:00Z");
|
|
164
164
|
this.max = this.interval(max, type, 999999999, "2200-12-31T00:00:00Z");
|
|
165
|
-
this.
|
|
166
|
-
this.
|
|
165
|
+
this.need = isArray(need) ? need : [];
|
|
166
|
+
this.send = isBoolean(send) ? send : true;
|
|
167
167
|
this.typeCheck = isBoolean(typeCheck) ? typeCheck : false;
|
|
168
|
-
this.methods = methods || METHODS;
|
|
169
|
-
this.sanitize = isBoolean(sanitize) ? sanitize : true;
|
|
170
|
-
this.normalize = isBoolean(normalize) ? normalize : false;
|
|
171
|
-
this.validate = isBoolean(validate) ? validate : true;
|
|
172
168
|
this.sanitizer = isFunction(sanitizer) ? sanitizer : null;
|
|
173
169
|
this.normalizer = isFunction(normalizer) ? normalizer : null;
|
|
174
170
|
this.validator = isFunction(validator) ? validator : null;
|
|
@@ -206,6 +202,21 @@ function trim(v) {
|
|
|
206
202
|
return v;
|
|
207
203
|
}
|
|
208
204
|
|
|
205
|
+
function normalize(record, properties) {
|
|
206
|
+
for (const { key, type, sanitizer, normalizer, } of properties) {
|
|
207
|
+
let v = record[key];
|
|
208
|
+
if (v) {
|
|
209
|
+
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
210
|
+
v = sanitize(v, sanitizer);
|
|
211
|
+
if (isFunction(normalizer)) {
|
|
212
|
+
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
213
|
+
v = normalizer(v);
|
|
214
|
+
}
|
|
215
|
+
record[key] = v;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
209
220
|
function control(v, key, type, min, max, typeCheck, cb) {
|
|
210
221
|
log.debug(`control ${key}: ${type} = ${v}`);
|
|
211
222
|
let errorMessage = "";
|
|
@@ -233,37 +244,18 @@ function require(v, key, type) {
|
|
|
233
244
|
return isNil(v) ? { statusCode: 400, message: `${LOGS_PREFIX}Missing ${key} of type ${type}` } : null;
|
|
234
245
|
}
|
|
235
246
|
|
|
236
|
-
function
|
|
237
|
-
for (const { key, type,
|
|
238
|
-
let v = record[key];
|
|
239
|
-
if (v) {
|
|
240
|
-
if (sanitize$1) {
|
|
241
|
-
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
242
|
-
v = sanitize(v, sanitizer);
|
|
243
|
-
}
|
|
244
|
-
if (normalize && isFunction(normalizer)) {
|
|
245
|
-
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
246
|
-
v = normalizer(v);
|
|
247
|
-
}
|
|
248
|
-
record[key] = v;
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function applyValidation(record, properties, method) {
|
|
254
|
-
for (const { key, type, min, max, required, typeCheck, methods, validate, validator } of properties) {
|
|
247
|
+
function validate(record, properties, method) {
|
|
248
|
+
for (const { key, type, min, max, need, typeCheck, validator } of properties) {
|
|
255
249
|
const v = record[key];
|
|
256
|
-
if (isIn(
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
return ct;
|
|
266
|
-
}
|
|
250
|
+
if (isIn(need, method)) {
|
|
251
|
+
const rq = require(v, key, type);
|
|
252
|
+
if (rq)
|
|
253
|
+
return rq;
|
|
254
|
+
}
|
|
255
|
+
if (v) {
|
|
256
|
+
const ct = control(v, key, type, min, max, typeCheck, validator);
|
|
257
|
+
if (ct)
|
|
258
|
+
return ct;
|
|
267
259
|
}
|
|
268
260
|
}
|
|
269
261
|
return null;
|
|
@@ -278,16 +270,16 @@ class Entity {
|
|
|
278
270
|
if (!isArray(rows, ">", 0))
|
|
279
271
|
return next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no rows found in request body` });
|
|
280
272
|
for (const r of rows) {
|
|
281
|
-
|
|
273
|
+
normalize(r, this._properties);
|
|
282
274
|
}
|
|
283
275
|
next();
|
|
284
276
|
};
|
|
285
277
|
this.normalizeOne = (req, _res, next) => {
|
|
286
278
|
log.debug(`normalizeOne ${this.name}`);
|
|
287
|
-
const
|
|
288
|
-
if (!isObject(
|
|
279
|
+
const r = req.body;
|
|
280
|
+
if (!isObject(r, true))
|
|
289
281
|
return next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no data found in request body` });
|
|
290
|
-
|
|
282
|
+
normalize(r, this._properties);
|
|
291
283
|
next();
|
|
292
284
|
};
|
|
293
285
|
this.validateArray = (req, _res, next) => {
|
|
@@ -303,7 +295,7 @@ class Entity {
|
|
|
303
295
|
message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}`
|
|
304
296
|
});
|
|
305
297
|
for (const r of rows) {
|
|
306
|
-
const error =
|
|
298
|
+
const error = validate(r, this._properties, method);
|
|
307
299
|
if (error)
|
|
308
300
|
return next(error);
|
|
309
301
|
}
|
|
@@ -320,69 +312,16 @@ class Entity {
|
|
|
320
312
|
statusCode: 400,
|
|
321
313
|
message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}`
|
|
322
314
|
});
|
|
323
|
-
const error =
|
|
315
|
+
const error = validate(record, this._properties, method);
|
|
324
316
|
if (error)
|
|
325
317
|
return next(error);
|
|
326
318
|
next();
|
|
327
319
|
};
|
|
328
|
-
this.check = (req, _res, next) => {
|
|
329
|
-
var _a;
|
|
330
|
-
const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
|
|
331
|
-
const method = req.method;
|
|
332
|
-
log.debug(`check ${this.name}`);
|
|
333
|
-
try {
|
|
334
|
-
isArray(rows, "!0", null, true);
|
|
335
|
-
}
|
|
336
|
-
catch (err) {
|
|
337
|
-
return next({
|
|
338
|
-
statusCode: 400,
|
|
339
|
-
message: `${LOGS_PREFIX}no rows found in request body - caused by: ${err.message}`
|
|
340
|
-
});
|
|
341
|
-
}
|
|
342
|
-
try {
|
|
343
|
-
isIn(METHODS, method, 0, true);
|
|
344
|
-
}
|
|
345
|
-
catch (err) {
|
|
346
|
-
return next({
|
|
347
|
-
statusCode: 400,
|
|
348
|
-
message: `${LOGS_PREFIX}Invalid REST method. Must be one of: ${METHODS.toString()} - caused by: ${err.message}`
|
|
349
|
-
});
|
|
350
|
-
}
|
|
351
|
-
for (const r of rows) {
|
|
352
|
-
for (const { key, type, min, max, required, typeCheck, methods, validate, sanitize: sanitize$1, normalize, sanitizer, normalizer, validator } of this._properties) {
|
|
353
|
-
let v = r[key];
|
|
354
|
-
if (isIn(methods, method)) {
|
|
355
|
-
if (v) {
|
|
356
|
-
if (sanitize$1) {
|
|
357
|
-
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
358
|
-
v = sanitize(v, sanitizer);
|
|
359
|
-
}
|
|
360
|
-
if (normalize && isFunction(normalizer)) {
|
|
361
|
-
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
362
|
-
v = normalizer(v);
|
|
363
|
-
}
|
|
364
|
-
r[key] = v;
|
|
365
|
-
if (validate) {
|
|
366
|
-
const ct = control(v, key, type, min, max, typeCheck, validator);
|
|
367
|
-
if (ct)
|
|
368
|
-
return next(ct);
|
|
369
|
-
}
|
|
370
|
-
}
|
|
371
|
-
if (required) {
|
|
372
|
-
const rq = require(v, key, type);
|
|
373
|
-
if (rq)
|
|
374
|
-
return next(rq);
|
|
375
|
-
}
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
next();
|
|
380
|
-
};
|
|
381
320
|
this._name = name;
|
|
382
321
|
this._properties = [];
|
|
383
322
|
this._unsafeProps = [];
|
|
384
323
|
for (const p of properties) {
|
|
385
|
-
const prop = new Property(p.key, p.type, p.min, p.max, p.
|
|
324
|
+
const prop = new Property(p.key, p.type, p.min, p.max, p.send, p.need, p.typeCheck, p.sanitizer, p.normalizer, p.validator);
|
|
386
325
|
Object.assign(prop, p);
|
|
387
326
|
this._properties.push(prop);
|
|
388
327
|
if (!prop.safe)
|
|
@@ -409,7 +348,7 @@ class Entity {
|
|
|
409
348
|
getPropsByMethod(method) {
|
|
410
349
|
const props = [];
|
|
411
350
|
for (const p of this.properties) {
|
|
412
|
-
if (isIn(p.
|
|
351
|
+
if (isIn(p.need, method, 0))
|
|
413
352
|
props.push(p);
|
|
414
353
|
}
|
|
415
354
|
return props;
|