@dwtechs/antity 0.6.0 → 0.8.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 +24 -44
- package/dist/antity.d.ts +8 -31
- package/dist/antity.js +39 -25
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
[](https://opensource.org/licenses/MIT)
|
|
3
3
|
[](https://www.npmjs.com/package/@dwtechs/antity)
|
|
4
4
|
[](https://www.npmjs.com/package/@dwtechs/antity)
|
|
5
|
+

|
|
5
6
|
[](https://www.npmjs.com/package/@dwtechs/antity)
|
|
6
7
|
|
|
7
8
|
- [Synopsis](#synopsis)
|
|
@@ -57,15 +58,15 @@ const entity = new Entity("consumers", [
|
|
|
57
58
|
min: 0,
|
|
58
59
|
max: 120,
|
|
59
60
|
typeCheck: true,
|
|
60
|
-
|
|
61
|
+
methods: ["GET", "PUT", "DELETE"],
|
|
61
62
|
required: true,
|
|
62
63
|
safe: true,
|
|
63
64
|
sanitize: true,
|
|
64
65
|
normalize: true,
|
|
65
|
-
|
|
66
|
+
validate: true,
|
|
66
67
|
sanitizer: null,
|
|
67
68
|
normalizer: null,
|
|
68
|
-
|
|
69
|
+
validator: null,
|
|
69
70
|
},
|
|
70
71
|
{
|
|
71
72
|
key: "firstName",
|
|
@@ -73,15 +74,15 @@ const entity = new Entity("consumers", [
|
|
|
73
74
|
min: 0,
|
|
74
75
|
max: 255,
|
|
75
76
|
typeCheck: true,
|
|
76
|
-
|
|
77
|
+
methods: ["GET", "POST", "PUT", "DELETE"],
|
|
77
78
|
required: true,
|
|
78
79
|
safe: true,
|
|
79
80
|
sanitize: true,
|
|
80
81
|
normalize: true,
|
|
81
|
-
|
|
82
|
+
validate: true,
|
|
82
83
|
sanitizer: null,
|
|
83
84
|
normalizer: normalizeName,
|
|
84
|
-
|
|
85
|
+
validator: null,
|
|
85
86
|
},
|
|
86
87
|
{
|
|
87
88
|
key: "lastName",
|
|
@@ -89,15 +90,15 @@ const entity = new Entity("consumers", [
|
|
|
89
90
|
min: 0,
|
|
90
91
|
max: 255,
|
|
91
92
|
typeCheck: true,
|
|
92
|
-
|
|
93
|
+
methods: ["GET", "POST", "PUT", "DELETE"],
|
|
93
94
|
required: true,
|
|
94
95
|
safe: true,
|
|
95
96
|
sanitize: true,
|
|
96
97
|
normalize: true,
|
|
97
|
-
|
|
98
|
+
validate: true,
|
|
98
99
|
sanitizer: null,
|
|
99
100
|
normalizer: normalizeName,
|
|
100
|
-
|
|
101
|
+
validator: null,
|
|
101
102
|
},
|
|
102
103
|
{
|
|
103
104
|
key: "nickname",
|
|
@@ -105,25 +106,23 @@ const entity = new Entity("consumers", [
|
|
|
105
106
|
min: 0,
|
|
106
107
|
max: 255,
|
|
107
108
|
typeCheck: true,
|
|
108
|
-
|
|
109
|
+
methods: ["GET", "POST", "PUT", "DELETE"],
|
|
109
110
|
required: true,
|
|
110
111
|
safe: true,
|
|
111
112
|
sanitize: true,
|
|
112
113
|
normalize: true,
|
|
113
|
-
|
|
114
|
+
validate: true,
|
|
114
115
|
sanitizer: null,
|
|
115
116
|
normalizer: normalizeNickname,
|
|
116
|
-
|
|
117
|
+
validator: null,
|
|
117
118
|
},
|
|
118
119
|
]);
|
|
119
120
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const unsafeProps = entity.getUnsafeProps();
|
|
121
|
+
// add a consumer. Used when loggin in from user service
|
|
122
|
+
router.post("/", entity.normalize, entity.validate, ...);
|
|
123
123
|
|
|
124
124
|
```
|
|
125
125
|
|
|
126
|
-
|
|
127
126
|
## API Reference
|
|
128
127
|
|
|
129
128
|
|
|
@@ -171,10 +170,10 @@ class Property {
|
|
|
171
170
|
methods: Method[];
|
|
172
171
|
sanitize: boolean;
|
|
173
172
|
normalize: boolean;
|
|
174
|
-
|
|
173
|
+
validate: boolean;
|
|
175
174
|
sanitizer: Function | null;
|
|
176
175
|
normalizer: Function | null;
|
|
177
|
-
|
|
176
|
+
validator: Function | null;
|
|
178
177
|
};
|
|
179
178
|
|
|
180
179
|
class Entity {
|
|
@@ -195,40 +194,21 @@ class Entity {
|
|
|
195
194
|
/**
|
|
196
195
|
* Normalizes an array of records by applying sanitization and normalization
|
|
197
196
|
* rules defined in the `properties` of the class.
|
|
198
|
-
*
|
|
199
|
-
* @param rows - An array of records where each record is a key-value pair.
|
|
200
|
-
* The keys represent property names, and the values are the data
|
|
201
|
-
* to be sanitized and normalized.
|
|
202
|
-
* @returns An array of records with sanitized and normalized values.
|
|
203
197
|
*/
|
|
204
|
-
normalize(
|
|
198
|
+
normalize(req: Request, _res: Response, next: NextFunction): void;
|
|
205
199
|
|
|
206
200
|
/**
|
|
207
201
|
* Validates a set of rows against the defined properties and operation/method.
|
|
208
202
|
*
|
|
209
|
-
* @param rows - An array of objects where each object represents a row to validate.
|
|
210
|
-
* Each row is a record with string keys and unknown values.
|
|
211
|
-
* @param operation - The operation or method to validate against. It can be of type `Operation` or `Method`.
|
|
212
|
-
*
|
|
213
|
-
* @returns A string containing the validation error message if validation fails, or `null` if validation passes.
|
|
214
|
-
*
|
|
215
203
|
* If a property is required and missing, or if it fails the control checks, the function returns an error message.
|
|
216
204
|
* Otherwise, it returns `null` indicating successful validation.
|
|
217
205
|
*/
|
|
218
|
-
validate(
|
|
206
|
+
validate(req: Request, _res: Response, next: NextFunction): void;
|
|
219
207
|
}
|
|
220
208
|
|
|
221
209
|
```
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
```javascript
|
|
226
|
-
|
|
227
|
-
entity.validate(req.body, "GET"); // will validate properties for GET requests
|
|
228
|
-
entity.validate(req.body, "PUT"); // will validate properties for PUT requests
|
|
229
|
-
entity.validate(req.body, "DELETE"); // will validate properties for DELETE requests
|
|
230
|
-
|
|
231
|
-
```
|
|
210
|
+
normalize() and validate() methods are made to be used as Express.js middlewares.
|
|
211
|
+
Each method will look for data to work on in the **req.body.rows** parmeter.
|
|
232
212
|
|
|
233
213
|
|
|
234
214
|
### Available options for a property
|
|
@@ -244,13 +224,13 @@ Any of these can be passed into the options object for each function.
|
|
|
244
224
|
| required | boolean | Is this property required on insert | false
|
|
245
225
|
| safe | boolean | Is this property safe to send to the client | true
|
|
246
226
|
| typeCheck | boolean | Type is checked if true | false
|
|
247
|
-
|
|
|
227
|
+
| methods | Method[] | SQL DML operations concerned by the property | [ "select", "insert", "update", "merge", "delete" ]
|
|
248
228
|
| sanitize | boolean | Sanitize the property if true | true
|
|
249
229
|
| normalize | boolean | Normalize the property if true | false
|
|
250
|
-
|
|
|
230
|
+
| validate | boolean | validate the property if true | true
|
|
251
231
|
| sanitizer | ((v:any) => any) \| null | Sanitizer function if sanitize is true | null
|
|
252
232
|
| normalizer | ((v:any) => any) \| null | Normalizer function if normalize is true | null
|
|
253
|
-
|
|
|
233
|
+
| validator | ((v:any, min:number, max:number, typeCheck:boolean) => any) \| null | validator function if validate is true | null
|
|
254
234
|
|
|
255
235
|
* *Min and max parameters are not used for boolean type*
|
|
256
236
|
* *TypeCheck Parameter is not used for boolean, string and array types*
|
package/dist/antity.d.ts
CHANGED
|
@@ -24,7 +24,8 @@ SOFTWARE.
|
|
|
24
24
|
https://github.com/DWTechs/Antity.js
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
import type { Request, Response, NextFunction } from 'express';
|
|
28
|
+
declare const Methods: readonly [ "GET", "PATCH", "PUT", "POST", "DELETE" ];
|
|
28
29
|
type Method = typeof Methods[number];
|
|
29
30
|
type Type =
|
|
30
31
|
"boolean" |
|
|
@@ -55,21 +56,6 @@ type Type =
|
|
|
55
56
|
"node" |
|
|
56
57
|
"object";
|
|
57
58
|
|
|
58
|
-
declare const Methods: readonly [ "GET", "PATCH", "PUT", "POST", "DELETE" ];
|
|
59
|
-
|
|
60
|
-
declare const Types: Record<Type, {
|
|
61
|
-
validate: (
|
|
62
|
-
v: any,
|
|
63
|
-
min: number | Date,
|
|
64
|
-
max: number | Date,
|
|
65
|
-
typeCheck: boolean
|
|
66
|
-
) => boolean;
|
|
67
|
-
}>;
|
|
68
|
-
|
|
69
|
-
declare const Required: {
|
|
70
|
-
validate: (v: any) => boolean;
|
|
71
|
-
};
|
|
72
|
-
|
|
73
59
|
declare class Entity {
|
|
74
60
|
private _name;
|
|
75
61
|
private _unsafeProps;
|
|
@@ -80,15 +66,10 @@ declare class Entity {
|
|
|
80
66
|
get properties(): Property[];
|
|
81
67
|
set name(name: string);
|
|
82
68
|
getProp(key: string): Property | undefined;
|
|
83
|
-
normalize(
|
|
84
|
-
validate(
|
|
69
|
+
normalize(req: Request, _res: Response, next: NextFunction): void;
|
|
70
|
+
validate(req: Request, _res: Response, next: NextFunction): void;
|
|
85
71
|
}
|
|
86
72
|
|
|
87
|
-
declare const Messages: {
|
|
88
|
-
missing: (key: string) => string;
|
|
89
|
-
invalid: (key: string, type: Type) => string;
|
|
90
|
-
};
|
|
91
|
-
|
|
92
73
|
declare class Property {
|
|
93
74
|
key: string;
|
|
94
75
|
type: Type;
|
|
@@ -100,10 +81,10 @@ declare class Property {
|
|
|
100
81
|
methods: Method[];
|
|
101
82
|
sanitize: boolean;
|
|
102
83
|
normalize: boolean;
|
|
103
|
-
|
|
84
|
+
validate: boolean;
|
|
104
85
|
sanitizer: ((v: any) => any) | null;
|
|
105
86
|
normalizer: ((v: any) => any) | null;
|
|
106
|
-
|
|
87
|
+
validator: ((v: any) => any) | null;
|
|
107
88
|
constructor(
|
|
108
89
|
key: string,
|
|
109
90
|
type: Type,
|
|
@@ -115,10 +96,10 @@ declare class Property {
|
|
|
115
96
|
methods: Method[],
|
|
116
97
|
sanitize: boolean,
|
|
117
98
|
normalize: boolean,
|
|
118
|
-
|
|
99
|
+
validate: boolean,
|
|
119
100
|
sanitizer: ((v: any) => any) | null,
|
|
120
101
|
normalizer: ((v: any) => any) | null,
|
|
121
|
-
|
|
102
|
+
validator: ((v: any) => any) | null
|
|
122
103
|
);
|
|
123
104
|
}
|
|
124
105
|
|
|
@@ -126,9 +107,5 @@ export type { Type, Method };
|
|
|
126
107
|
export {
|
|
127
108
|
Entity,
|
|
128
109
|
Property,
|
|
129
|
-
Messages,
|
|
130
|
-
Types,
|
|
131
|
-
Required,
|
|
132
|
-
Methods,
|
|
133
110
|
};
|
|
134
111
|
|
package/dist/antity.js
CHANGED
|
@@ -40,7 +40,7 @@ const Types = {
|
|
|
40
40
|
validate: (v, min, max, typeCheck) => isValidNumber(v, min || undefined, max || undefined, typeCheck || undefined)
|
|
41
41
|
},
|
|
42
42
|
integer: {
|
|
43
|
-
validate: (v, min, max, typeCheck) => isValidInteger(v, min
|
|
43
|
+
validate: (v, min, max, typeCheck) => isValidInteger(v, min !== null && min !== void 0 ? min : undefined, max !== null && max !== void 0 ? max : undefined, typeCheck || undefined)
|
|
44
44
|
},
|
|
45
45
|
float: {
|
|
46
46
|
validate: (v, min, max, typeCheck) => isValidFloat(v, min || undefined, max || undefined, typeCheck || undefined)
|
|
@@ -114,7 +114,7 @@ const Types = {
|
|
|
114
114
|
};
|
|
115
115
|
|
|
116
116
|
class Property {
|
|
117
|
-
constructor(key, type, min, max, required, safe, typeCheck, methods, sanitize, normalize,
|
|
117
|
+
constructor(key, type, min, max, required, safe, typeCheck, methods, sanitize, normalize, validate, sanitizer, normalizer, validator) {
|
|
118
118
|
if (!isString(key, "!0"))
|
|
119
119
|
throw new Error(`Property "key" must be a string. Received ${key}`);
|
|
120
120
|
if (!isProperty(Types, type))
|
|
@@ -135,10 +135,10 @@ class Property {
|
|
|
135
135
|
this.methods = methods || Methods;
|
|
136
136
|
this.sanitize = isBoolean(sanitize) ? sanitize : true;
|
|
137
137
|
this.normalize = isBoolean(normalize) ? normalize : false;
|
|
138
|
-
this.
|
|
138
|
+
this.validate = isBoolean(validate) ? validate : true;
|
|
139
139
|
this.sanitizer = isFunction(sanitizer) ? sanitizer : null;
|
|
140
140
|
this.normalizer = isFunction(normalizer) ? normalizer : null;
|
|
141
|
-
this.
|
|
141
|
+
this.validator = isFunction(validator) ? validator : null;
|
|
142
142
|
}
|
|
143
143
|
interval(val, type, integerDefault, dateDefault) {
|
|
144
144
|
if (type === "date")
|
|
@@ -147,18 +147,13 @@ class Property {
|
|
|
147
147
|
}
|
|
148
148
|
}
|
|
149
149
|
|
|
150
|
-
const Messages = {
|
|
151
|
-
missing: (key) => `Missing ${key}`,
|
|
152
|
-
invalid: (key, type) => `Invalid ${key}, must be of type ${type}`,
|
|
153
|
-
};
|
|
154
|
-
|
|
155
150
|
class Entity {
|
|
156
151
|
constructor(name, properties) {
|
|
157
152
|
this._name = name;
|
|
158
153
|
this._properties = [];
|
|
159
154
|
this._unsafeProps = [];
|
|
160
155
|
for (const p of properties) {
|
|
161
|
-
const prop = new Property(p.key, p.type, p.min, p.max, p.required, p.safe, p.typeCheck, p.methods, p.sanitize, p.normalize, p.
|
|
156
|
+
const prop = new Property(p.key, p.type, p.min, p.max, p.required, p.safe, p.typeCheck, p.methods, p.sanitize, p.normalize, p.validate, p.sanitizer, p.normalizer, p.validator);
|
|
162
157
|
this._properties.push(prop);
|
|
163
158
|
if (!prop.safe)
|
|
164
159
|
this._unsafeProps.push(prop.key);
|
|
@@ -181,7 +176,11 @@ class Entity {
|
|
|
181
176
|
getProp(key) {
|
|
182
177
|
return this.properties.find(p => p.key === key);
|
|
183
178
|
}
|
|
184
|
-
normalize(
|
|
179
|
+
normalize(req, _res, next) {
|
|
180
|
+
var _a;
|
|
181
|
+
const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
|
|
182
|
+
if (!isArray(rows, "!0"))
|
|
183
|
+
return next({ status: 400, msg: "Normalize: no rows found in request body" });
|
|
185
184
|
for (const r of rows) {
|
|
186
185
|
for (const { key, type, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
187
186
|
let v = r[key];
|
|
@@ -190,7 +189,7 @@ class Entity {
|
|
|
190
189
|
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
191
190
|
v = this.sanitize(v, sanitizer);
|
|
192
191
|
}
|
|
193
|
-
if (normalize && normalizer) {
|
|
192
|
+
if (normalize && isFunction(normalizer)) {
|
|
194
193
|
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
195
194
|
v = normalizer(v);
|
|
196
195
|
}
|
|
@@ -198,40 +197,55 @@ class Entity {
|
|
|
198
197
|
}
|
|
199
198
|
}
|
|
200
199
|
}
|
|
201
|
-
|
|
200
|
+
next();
|
|
202
201
|
}
|
|
203
|
-
validate(
|
|
202
|
+
validate(req, _res, next) {
|
|
203
|
+
var _a;
|
|
204
|
+
const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
|
|
205
|
+
const method = req.method;
|
|
206
|
+
if (!isArray(rows, "!0"))
|
|
207
|
+
return next({ status: 400, msg: "Sanitize: no rows found in request body" });
|
|
204
208
|
if (!isIn(Methods, method))
|
|
205
|
-
return
|
|
209
|
+
return next({
|
|
210
|
+
status: 400,
|
|
211
|
+
msg: `Invalid REST method. Received: ${method}. Must be one of: ${Methods.toString()}`
|
|
212
|
+
});
|
|
206
213
|
for (const r of rows) {
|
|
207
|
-
for (const { key, type, min, max, required, typeCheck, methods,
|
|
214
|
+
for (const { key, type, min, max, required, typeCheck, methods, validate, validator } of this.properties) {
|
|
208
215
|
const v = r[key];
|
|
209
216
|
if (isIn(methods, method)) {
|
|
210
217
|
if (required) {
|
|
211
218
|
const rq = this.require(v, key, type);
|
|
212
219
|
if (rq)
|
|
213
|
-
return rq;
|
|
220
|
+
return next(rq);
|
|
214
221
|
}
|
|
215
|
-
if (v &&
|
|
216
|
-
const ct = this.control(v, key, type, min, max, typeCheck,
|
|
222
|
+
if (v && validate) {
|
|
223
|
+
const ct = this.control(v, key, type, min, max, typeCheck, validator);
|
|
217
224
|
if (ct)
|
|
218
|
-
return ct;
|
|
225
|
+
return next(ct);
|
|
219
226
|
}
|
|
220
227
|
}
|
|
221
228
|
}
|
|
222
229
|
}
|
|
223
|
-
|
|
230
|
+
next();
|
|
224
231
|
}
|
|
225
232
|
require(v, key, type) {
|
|
226
233
|
log.debug(`require ${key}: ${type} = ${v}`);
|
|
227
|
-
return isNil(v) ?
|
|
234
|
+
return isNil(v) ? { status: 400, msg: `Missing ${key} of type ${type}` } : null;
|
|
228
235
|
}
|
|
229
236
|
control(v, key, type, min, max, typeCheck, cb) {
|
|
230
237
|
log.debug(`control ${key}: ${type} = ${v}`);
|
|
238
|
+
let val;
|
|
231
239
|
if (cb)
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
240
|
+
val = cb(v);
|
|
241
|
+
else
|
|
242
|
+
val = Types[type].validate(v, min, max, typeCheck);
|
|
243
|
+
let c = "";
|
|
244
|
+
if (!isNil(min))
|
|
245
|
+
c += ` and >= ${min}`;
|
|
246
|
+
if (!isNil(max))
|
|
247
|
+
c += ` and <= ${max}`;
|
|
248
|
+
return val ? null : { status: 400, msg: `Invalid ${key}, must be of type ${type}${c}` };
|
|
235
249
|
}
|
|
236
250
|
sanitize(v, cb) {
|
|
237
251
|
if (cb)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwtechs/antity",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Open source library for easy entity management",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"entities"
|
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
"rollup:mjs": "rollup --config rollup.config.mjs",
|
|
31
31
|
"rollup:cjs": "rollup --config rollup.config.cjs.mjs",
|
|
32
32
|
"rollup": "npm run rollup:mjs",
|
|
33
|
-
"test": "jest --coverage"
|
|
33
|
+
"test": "jest --coverage --config jest.config.js"
|
|
34
34
|
},
|
|
35
35
|
"files": [
|
|
36
36
|
"dist/"
|
|
@@ -48,6 +48,7 @@
|
|
|
48
48
|
"@rollup/plugin-node-resolve": "15.3.0",
|
|
49
49
|
"@types/jest": "29.5.14",
|
|
50
50
|
"@types/node": "22.10.1",
|
|
51
|
+
"@types/express": "5.0.0",
|
|
51
52
|
"babel-jest": "29.7.0",
|
|
52
53
|
"core-js": "3.33.0",
|
|
53
54
|
"jest": "29.7.0",
|