@dwtechs/antity 0.3.0 → 0.5.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 +51 -22
- package/dist/antity.d.ts +17 -13
- package/dist/antity.js +74 -37
- package/package.json +6 -3
- package/dist/antity.cjs.js +0 -556
package/README.md
CHANGED
|
@@ -50,15 +50,16 @@ $ npm i @dwtechs/antity
|
|
|
50
50
|
import { Entity } from "@dwtechs/antity";
|
|
51
51
|
import { normalizeName, normalizeNickname } from "@dwtechs/checkard";
|
|
52
52
|
|
|
53
|
-
const entity = new Entity("
|
|
53
|
+
const entity = new Entity("consumers", [
|
|
54
54
|
{
|
|
55
55
|
key: "id",
|
|
56
56
|
type: "integer",
|
|
57
57
|
min: 0,
|
|
58
58
|
max: 120,
|
|
59
59
|
typeCheck: true,
|
|
60
|
-
|
|
60
|
+
operations: ["select", "update", "delete"],
|
|
61
61
|
required: true,
|
|
62
|
+
safe: true,
|
|
62
63
|
sanitize: true,
|
|
63
64
|
normalize: true,
|
|
64
65
|
control: true,
|
|
@@ -72,8 +73,9 @@ const entity = new Entity("consumer", "consumers", [
|
|
|
72
73
|
min: 0,
|
|
73
74
|
max: 255,
|
|
74
75
|
typeCheck: true,
|
|
75
|
-
|
|
76
|
+
operations: ["select", "insert", "update", "delete"],
|
|
76
77
|
required: true,
|
|
78
|
+
safe: true,
|
|
77
79
|
sanitize: true,
|
|
78
80
|
normalize: true,
|
|
79
81
|
control: true,
|
|
@@ -87,8 +89,9 @@ const entity = new Entity("consumer", "consumers", [
|
|
|
87
89
|
min: 0,
|
|
88
90
|
max: 255,
|
|
89
91
|
typeCheck: true,
|
|
90
|
-
|
|
92
|
+
operations: ["select", "insert", "update", "delete"],
|
|
91
93
|
required: true,
|
|
94
|
+
safe: true,
|
|
92
95
|
sanitize: true,
|
|
93
96
|
normalize: true,
|
|
94
97
|
control: true,
|
|
@@ -102,8 +105,9 @@ const entity = new Entity("consumer", "consumers", [
|
|
|
102
105
|
min: 0,
|
|
103
106
|
max: 255,
|
|
104
107
|
typeCheck: true,
|
|
105
|
-
|
|
108
|
+
operations: ["select", "insert", "update", "delete"],
|
|
106
109
|
required: true,
|
|
110
|
+
safe: true,
|
|
107
111
|
sanitize: true,
|
|
108
112
|
normalize: true,
|
|
109
113
|
control: true,
|
|
@@ -113,10 +117,9 @@ const entity = new Entity("consumer", "consumers", [
|
|
|
113
117
|
},
|
|
114
118
|
]);
|
|
115
119
|
|
|
116
|
-
req.body = entity.normalize(req.body);
|
|
117
|
-
const check = entity.validate(req.body,
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
req.body = entity.normalize(req.body); // will also sanitize if true
|
|
121
|
+
const check = entity.validate(req.body, "select");
|
|
122
|
+
const unsafeProps = entity.getUnsafeProps();
|
|
120
123
|
|
|
121
124
|
```
|
|
122
125
|
|
|
@@ -154,6 +157,7 @@ type Type = "boolean" |
|
|
|
154
157
|
"node" |
|
|
155
158
|
"object";
|
|
156
159
|
|
|
160
|
+
type Operation = "select" | "insert" | "update" | "merge" | "delete";
|
|
157
161
|
type Method = "GET" | "PATCH" | "PUT" | "POST" | "DELETE";
|
|
158
162
|
|
|
159
163
|
class Property {
|
|
@@ -162,8 +166,9 @@ class Property {
|
|
|
162
166
|
min: number | Date;
|
|
163
167
|
max: number | Date;
|
|
164
168
|
required: boolean;
|
|
169
|
+
safe: boolean;
|
|
165
170
|
typeCheck: boolean;
|
|
166
|
-
|
|
171
|
+
operations: Operation[];
|
|
167
172
|
sanitize: boolean;
|
|
168
173
|
normalize: boolean;
|
|
169
174
|
control: boolean;
|
|
@@ -173,18 +178,41 @@ class Property {
|
|
|
173
178
|
};
|
|
174
179
|
|
|
175
180
|
class Entity {
|
|
176
|
-
name: string;
|
|
177
181
|
table: string;
|
|
178
|
-
cols: Record<
|
|
182
|
+
cols: Record<Operation, string[]>;
|
|
179
183
|
properties: Property[];
|
|
180
|
-
normalize(rows: Record<string, any>[]): Record<string, any>[];
|
|
181
|
-
validate(rows: Record<string, any>[],
|
|
184
|
+
normalize(rows: Record<string, any>[]): Record<string, any>[]; // will also sanitize if true
|
|
185
|
+
validate(rows: Record<string, any>[], operation: Operation | Method): string | null;
|
|
182
186
|
getTable(): string;
|
|
183
|
-
|
|
187
|
+
// if pagination is true for a select operation, it will return cols + a total column
|
|
188
|
+
getCols(operation: Operation, stringify?: boolean, pagination?: boolean): string[] | string;
|
|
189
|
+
getUnsafeProps(): string[];
|
|
184
190
|
}
|
|
185
191
|
|
|
186
192
|
```
|
|
187
193
|
|
|
194
|
+
### REST Methods mapping
|
|
195
|
+
|
|
196
|
+
When validating request inputs, you can use REST methods or SQL operations as second parameter
|
|
197
|
+
|
|
198
|
+
| REST method | SQL operation |
|
|
199
|
+
| :---------- | :------------ |
|
|
200
|
+
| GET | select |
|
|
201
|
+
| PATCH | update |
|
|
202
|
+
| PUT | update |
|
|
203
|
+
| POST | insert |
|
|
204
|
+
| DELETE | delete |
|
|
205
|
+
|
|
206
|
+
examples :
|
|
207
|
+
|
|
208
|
+
```javascript
|
|
209
|
+
|
|
210
|
+
entity.validate(req.body, "GET"); // will validate "select" properties
|
|
211
|
+
entity.validate(req.body, "PUT"); // will validate "update" properties
|
|
212
|
+
entity.validate(req.body, "DELETE"); // will validate "delete" properties
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
|
|
188
216
|
|
|
189
217
|
### Available options for a property
|
|
190
218
|
|
|
@@ -193,17 +221,18 @@ Any of these can be passed into the options object for each function.
|
|
|
193
221
|
| Name | Type | Description | Default value |
|
|
194
222
|
| :-------------- | :------------------------ | :------------------------------------------------ | :-------------- |
|
|
195
223
|
| key | string | Name of the property |
|
|
196
|
-
| type | Type | Type of the property
|
|
197
|
-
| min | number
|
|
198
|
-
| max | number
|
|
199
|
-
| required | boolean | Is this property required
|
|
224
|
+
| type | Type | Type of the property |
|
|
225
|
+
| min | number \| Date | Minimum value | 0 \| 1900-01-01
|
|
226
|
+
| max | number \| Date | Maximum value | 999999999 \| 2200-12-31
|
|
227
|
+
| required | boolean | Is this property required on insert | false
|
|
228
|
+
| safe | boolean | Is this property safe to send to the client | true
|
|
200
229
|
| typeCheck | boolean | Type is checked if true | false
|
|
201
|
-
|
|
|
230
|
+
| operations | Operation[] | SQL DML operations concerned by the property | [ "select", "insert", "update", "merge", "delete" ]
|
|
202
231
|
| sanitize | boolean | Sanitize the property if true | true
|
|
203
232
|
| normalize | boolean | Normalize the property if true | false
|
|
204
233
|
| control | boolean | Control the property if true | true
|
|
205
|
-
| sanitizer | ((v:any) => any) \| null
|
|
206
|
-
| normalizer | ((v:any) => any) \| null
|
|
234
|
+
| sanitizer | ((v:any) => any) \| null | Sanitizer function if sanitize is true | null
|
|
235
|
+
| normalizer | ((v:any) => any) \| null | Normalizer function if normalize is true | null
|
|
207
236
|
| controller | ((v:any, min:number, max:number, typeCheck:boolean) => any) \| null | Controller function if control is true | null
|
|
208
237
|
|
|
209
238
|
* *Min and max parameters are not used for boolean type*
|
package/dist/antity.d.ts
CHANGED
|
@@ -25,7 +25,9 @@ https://github.com/DWTechs/Antity.js
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
|
|
28
|
+
type Operation = typeof Operations[number];
|
|
28
29
|
type Method = typeof Methods[number];
|
|
30
|
+
|
|
29
31
|
type Type =
|
|
30
32
|
"boolean" |
|
|
31
33
|
"string" |
|
|
@@ -55,7 +57,8 @@ type Type =
|
|
|
55
57
|
"node" |
|
|
56
58
|
"object";
|
|
57
59
|
|
|
58
|
-
declare const
|
|
60
|
+
declare const Operations: readonly [ "select", "insert", "update", "merge", "delete" ];
|
|
61
|
+
declare const Methods: readonly [ "GET", "PATCH", "PUT", "POST", "DELETE" ];
|
|
59
62
|
|
|
60
63
|
declare const Types: Record<Type, {
|
|
61
64
|
validate: (v: any, min: number | Date, max: number | Date, typeCheck: boolean) => boolean;
|
|
@@ -66,16 +69,15 @@ declare const Required: {
|
|
|
66
69
|
};
|
|
67
70
|
|
|
68
71
|
declare class Entity {
|
|
69
|
-
name: string;
|
|
70
72
|
table: string;
|
|
71
|
-
cols: Record<
|
|
73
|
+
cols: Record<Operation, string[]>;
|
|
72
74
|
properties: Property[];
|
|
73
|
-
constructor(
|
|
74
|
-
private init;
|
|
75
|
+
constructor(table: string, properties: Property[]);
|
|
75
76
|
getTable(): string;
|
|
76
|
-
getCols(
|
|
77
|
+
getCols(operation: Operation, stringify?: boolean, pagination?: boolean): string[] | string;
|
|
78
|
+
getUnsafeProps(): string[];
|
|
77
79
|
normalize(rows: Record<string, any>[]): Record<string, any>[];
|
|
78
|
-
validate(rows: Record<string, any>[],
|
|
80
|
+
validate(rows: Record<string, any>[], operation: Operation | Method): string | null;
|
|
79
81
|
private require;
|
|
80
82
|
private control;
|
|
81
83
|
private sanitize;
|
|
@@ -90,11 +92,12 @@ declare const Messages: {
|
|
|
90
92
|
declare class Property {
|
|
91
93
|
key: string;
|
|
92
94
|
type: Type;
|
|
93
|
-
min: number;
|
|
94
|
-
max: number;
|
|
95
|
+
min: number | Date;
|
|
96
|
+
max: number | Date;
|
|
95
97
|
required: boolean;
|
|
98
|
+
safe: boolean;
|
|
96
99
|
typeCheck: boolean;
|
|
97
|
-
|
|
100
|
+
operations: Operation[];
|
|
98
101
|
sanitize: boolean;
|
|
99
102
|
normalize: boolean;
|
|
100
103
|
control: boolean;
|
|
@@ -106,8 +109,9 @@ declare class Property {
|
|
|
106
109
|
min: number | Date,
|
|
107
110
|
max: number | Date,
|
|
108
111
|
required: boolean,
|
|
112
|
+
safe: boolean,
|
|
109
113
|
typeCheck: boolean,
|
|
110
|
-
|
|
114
|
+
operations: Operation[],
|
|
111
115
|
sanitize: boolean,
|
|
112
116
|
normalize: boolean,
|
|
113
117
|
control: boolean,
|
|
@@ -117,13 +121,13 @@ declare class Property {
|
|
|
117
121
|
);
|
|
118
122
|
}
|
|
119
123
|
|
|
120
|
-
export type { Type, Method };
|
|
124
|
+
export type { Type, Operation, Method };
|
|
121
125
|
export {
|
|
122
126
|
Entity,
|
|
123
127
|
Property,
|
|
124
128
|
Messages,
|
|
125
129
|
Types,
|
|
126
130
|
Required,
|
|
127
|
-
|
|
131
|
+
Operations
|
|
128
132
|
};
|
|
129
133
|
|
package/dist/antity.js
CHANGED
|
@@ -24,9 +24,10 @@ SOFTWARE.
|
|
|
24
24
|
https://github.com/DWTechs/Antity.js
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
|
-
import { isBoolean, isStringOfLength, isValidNumber, isValidInteger, isValidFloat, isEven, isOdd, isPositive, isNegative, isPowerOfTwo, isAscii, isArrayOfLength, isEmail, isRegex, isJson, isJWT, isSymbol, isIpAddress, isSlug, isHexadecimal, isValidDate, isValidTimestamp, isFunction, isHtmlElement, isHtmlEventAttribute, isNode, isObject, isNil, isString, isProperty, isArray, isIn, isInteger } from '@dwtechs/checkard';
|
|
27
|
+
import { isBoolean, isStringOfLength, isValidNumber, isValidInteger, isValidFloat, isEven, isOdd, isPositive, isNegative, isPowerOfTwo, isAscii, isArrayOfLength, isEmail, isRegex, isJson, isJWT, isSymbol, isIpAddress, isSlug, isHexadecimal, isValidDate, isValidTimestamp, isFunction, isHtmlElement, isHtmlEventAttribute, isNode, isObject, isNil, isString, isProperty, isArray, isIn, isDate, isInteger } from '@dwtechs/checkard';
|
|
28
|
+
import { log } from '@dwtechs/winstan';
|
|
28
29
|
|
|
29
|
-
const
|
|
30
|
+
const Operations = ["select", "insert", "update", "merge", "delete"];
|
|
30
31
|
|
|
31
32
|
const Types = {
|
|
32
33
|
boolean: {
|
|
@@ -116,24 +117,25 @@ const Required = {
|
|
|
116
117
|
};
|
|
117
118
|
|
|
118
119
|
class Property {
|
|
119
|
-
constructor(key, type, min, max, required, typeCheck,
|
|
120
|
+
constructor(key, type, min, max, required, safe, typeCheck, operations, sanitize, normalize, control, sanitizer, normalizer, controller) {
|
|
120
121
|
if (!isString(key, true))
|
|
121
|
-
throw new Error(`Property
|
|
122
|
+
throw new Error(`Property"key" must be a string. Received ${key}`);
|
|
122
123
|
if (!isProperty(type, Types))
|
|
123
|
-
throw new Error(`Property type must be a valid type. Received ${type}`);
|
|
124
|
-
if (isArray(
|
|
125
|
-
for (const
|
|
126
|
-
if (!isIn(
|
|
127
|
-
throw new Error(`Property
|
|
124
|
+
throw new Error(`Property "type" must be a valid type. Received ${type}`);
|
|
125
|
+
if (isArray(operations)) {
|
|
126
|
+
for (const o of operations) {
|
|
127
|
+
if (!isIn(o, Operations))
|
|
128
|
+
throw new Error(`Property "operations" must be an array of SQL operations. Received ${o}`);
|
|
128
129
|
}
|
|
129
130
|
}
|
|
130
131
|
this.key = key;
|
|
131
132
|
this.type = type;
|
|
132
|
-
this.min =
|
|
133
|
-
this.max =
|
|
133
|
+
this.min = this.interval(min, type, 0, "1900-01-01T00:00:00Z");
|
|
134
|
+
this.max = this.interval(max, type, 999999999, "2200-12-31T00:00:00Z");
|
|
134
135
|
this.required = isBoolean(required) ? required : false;
|
|
136
|
+
this.safe = isBoolean(safe) ? safe : true;
|
|
135
137
|
this.typeCheck = isBoolean(typeCheck) ? typeCheck : false;
|
|
136
|
-
this.
|
|
138
|
+
this.operations = operations || Operations;
|
|
137
139
|
this.sanitize = isBoolean(sanitize) ? sanitize : true;
|
|
138
140
|
this.normalize = isBoolean(normalize) ? normalize : false;
|
|
139
141
|
this.control = isBoolean(control) ? control : true;
|
|
@@ -141,6 +143,11 @@ class Property {
|
|
|
141
143
|
this.normalizer = isFunction(normalizer) ? normalizer : null;
|
|
142
144
|
this.controller = isFunction(controller) ? controller : null;
|
|
143
145
|
}
|
|
146
|
+
interval(val, type, integerDefault, dateDefault) {
|
|
147
|
+
if (type === "date")
|
|
148
|
+
return isDate(val) ? val : new Date(dateDefault);
|
|
149
|
+
return isInteger(val, true) ? val : integerDefault;
|
|
150
|
+
}
|
|
144
151
|
}
|
|
145
152
|
|
|
146
153
|
const Messages = {
|
|
@@ -148,57 +155,71 @@ const Messages = {
|
|
|
148
155
|
invalid: (key, type) => `Invalid ${key}, must be of type ${type}`,
|
|
149
156
|
};
|
|
150
157
|
|
|
158
|
+
const Methods = ["GET", "PATCH", "PUT", "POST", "DELETE"];
|
|
159
|
+
|
|
151
160
|
class Entity {
|
|
152
|
-
constructor(
|
|
153
|
-
this.name = name;
|
|
161
|
+
constructor(table, properties) {
|
|
154
162
|
this.table = table;
|
|
163
|
+
this.properties = [];
|
|
155
164
|
this.cols = {
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
165
|
+
select: [],
|
|
166
|
+
insert: [],
|
|
167
|
+
update: [],
|
|
168
|
+
merge: [],
|
|
169
|
+
delete: []
|
|
161
170
|
};
|
|
162
|
-
this.
|
|
163
|
-
}
|
|
164
|
-
init(properties) {
|
|
165
|
-
const props = [];
|
|
171
|
+
this.unsafeProps = [];
|
|
166
172
|
for (const p of properties) {
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
173
|
+
const prop = new Property(p.key, p.type, p.min, p.max, p.required, p.safe, p.typeCheck, p.operations, p.sanitize, p.normalize, p.control, p.sanitizer, p.normalizer, p.controller);
|
|
174
|
+
this.properties.push(prop);
|
|
175
|
+
for (const o of p.operations) {
|
|
176
|
+
if (o === "update")
|
|
177
|
+
this.cols[o].push(`${p.key} = $${this.cols[o].length + 1}`);
|
|
178
|
+
else
|
|
179
|
+
this.cols[o].push(p.key);
|
|
170
180
|
}
|
|
181
|
+
if (!prop.safe)
|
|
182
|
+
this.unsafeProps.push(prop.key);
|
|
171
183
|
}
|
|
172
|
-
return props;
|
|
173
184
|
}
|
|
174
185
|
getTable() {
|
|
175
186
|
return this.table;
|
|
176
187
|
}
|
|
177
|
-
getCols(
|
|
178
|
-
|
|
188
|
+
getCols(operation, stringify, pagination) {
|
|
189
|
+
const cols = pagination && operation === "select" ? [...this.cols[operation], "COUNT(*) OVER () AS total"] : this.cols[operation];
|
|
190
|
+
return stringify ? cols.join(', ') : cols;
|
|
191
|
+
}
|
|
192
|
+
getUnsafeProps() {
|
|
193
|
+
return this.unsafeProps;
|
|
179
194
|
}
|
|
180
195
|
normalize(rows) {
|
|
181
196
|
for (const r of rows) {
|
|
182
|
-
for (const { key, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
197
|
+
for (const { key, type, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
183
198
|
let v = r[key];
|
|
184
199
|
if (v) {
|
|
185
|
-
if (sanitize)
|
|
200
|
+
if (sanitize) {
|
|
201
|
+
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
186
202
|
v = this.sanitize(v, sanitizer);
|
|
187
|
-
|
|
203
|
+
}
|
|
204
|
+
if (normalize && normalizer) {
|
|
205
|
+
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
188
206
|
v = normalizer(v);
|
|
207
|
+
}
|
|
189
208
|
r[key] = v;
|
|
190
209
|
}
|
|
191
210
|
}
|
|
192
211
|
}
|
|
193
212
|
return rows;
|
|
194
213
|
}
|
|
195
|
-
validate(rows,
|
|
214
|
+
validate(rows, operation) {
|
|
215
|
+
if (isIn(operation, Methods))
|
|
216
|
+
operation = this.mapMethods(operation);
|
|
196
217
|
for (const r of rows) {
|
|
197
|
-
for (const { key, type, min, max, required, typeCheck,
|
|
218
|
+
for (const { key, type, min, max, required, typeCheck, operations, control, controller } of this.properties) {
|
|
198
219
|
const v = r[key];
|
|
199
|
-
if (
|
|
220
|
+
if (isIn(operation, operations)) {
|
|
200
221
|
if (required) {
|
|
201
|
-
const rq = this.require(v, key);
|
|
222
|
+
const rq = this.require(v, key, type);
|
|
202
223
|
if (rq)
|
|
203
224
|
return rq;
|
|
204
225
|
}
|
|
@@ -212,10 +233,12 @@ class Entity {
|
|
|
212
233
|
}
|
|
213
234
|
return null;
|
|
214
235
|
}
|
|
215
|
-
require(v, key) {
|
|
236
|
+
require(v, key, type) {
|
|
237
|
+
log.debug(`require ${key}: ${type} = ${v}`);
|
|
216
238
|
return Required.validate(v) ? null : Messages.missing(key);
|
|
217
239
|
}
|
|
218
240
|
control(v, key, type, min, max, typeCheck, cb) {
|
|
241
|
+
log.debug(`control ${key}: ${type} = ${v}`);
|
|
219
242
|
if (cb)
|
|
220
243
|
return cb(v) ? null : Messages.invalid(key, type);
|
|
221
244
|
return Types[type].validate(v, min, max, typeCheck) ? null : Messages.invalid(key, type);
|
|
@@ -246,6 +269,20 @@ class Entity {
|
|
|
246
269
|
return v;
|
|
247
270
|
}
|
|
248
271
|
}
|
|
272
|
+
mapMethods(method) {
|
|
273
|
+
switch (method) {
|
|
274
|
+
case "GET":
|
|
275
|
+
return Operations[0];
|
|
276
|
+
case "PATCH":
|
|
277
|
+
return Operations[2];
|
|
278
|
+
case "PUT":
|
|
279
|
+
return Operations[2];
|
|
280
|
+
case "POST":
|
|
281
|
+
return Operations[1];
|
|
282
|
+
case "DELETE":
|
|
283
|
+
return Operations[4];
|
|
284
|
+
}
|
|
285
|
+
}
|
|
249
286
|
}
|
|
250
287
|
|
|
251
288
|
export { Entity };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwtechs/antity",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Open source library for easy entity management",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"entities"
|
|
@@ -28,14 +28,16 @@
|
|
|
28
28
|
"build": "node ./scripts/clear && tsc && npm run rollup && node ./scripts/copy && npm run test",
|
|
29
29
|
"rollup:mjs": "rollup --config rollup.config.mjs",
|
|
30
30
|
"rollup:cjs": "rollup --config rollup.config.cjs.mjs",
|
|
31
|
-
"rollup": "npm run rollup:mjs
|
|
31
|
+
"rollup": "npm run rollup:mjs",
|
|
32
32
|
"test": "jest --coverage"
|
|
33
33
|
},
|
|
34
34
|
"files": [
|
|
35
35
|
"dist/"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@dwtechs/checkard": "2.29.2"
|
|
38
|
+
"@dwtechs/checkard": "2.29.2",
|
|
39
|
+
"@dwtechs/winstan": "0.3.0",
|
|
40
|
+
"pg": "8.13.1"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@babel/core": "7.26.0",
|
|
@@ -43,6 +45,7 @@
|
|
|
43
45
|
"@rollup/plugin-commonjs": "28.0.1",
|
|
44
46
|
"@rollup/plugin-node-resolve": "15.3.0",
|
|
45
47
|
"@types/jest": "29.5.14",
|
|
48
|
+
"@types/node": "22.10.1",
|
|
46
49
|
"babel-jest": "29.7.0",
|
|
47
50
|
"core-js": "3.33.0",
|
|
48
51
|
"jest": "29.7.0",
|
package/dist/antity.cjs.js
DELETED
|
@@ -1,556 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
MIT License
|
|
3
|
-
|
|
4
|
-
Copyright (c) 2024 DWTechs
|
|
5
|
-
|
|
6
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
-
in the Software without restriction, including without limitation the rights
|
|
9
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
-
furnished to do so, subject to the following conditions:
|
|
12
|
-
|
|
13
|
-
The above copyright notice and this permission notice shall be included in all
|
|
14
|
-
copies or substantial portions of the Software.
|
|
15
|
-
|
|
16
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
-
SOFTWARE.
|
|
23
|
-
|
|
24
|
-
https://github.com/DWTechs/Antity.js
|
|
25
|
-
*/
|
|
26
|
-
|
|
27
|
-
'use strict';
|
|
28
|
-
|
|
29
|
-
/*
|
|
30
|
-
MIT License
|
|
31
|
-
|
|
32
|
-
Copyright (c) 2009 DWTechs
|
|
33
|
-
|
|
34
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
35
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
36
|
-
in the Software without restriction, including without limitation the rights
|
|
37
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
38
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
39
|
-
furnished to do so, subject to the following conditions:
|
|
40
|
-
|
|
41
|
-
The above copyright notice and this permission notice shall be included in all
|
|
42
|
-
copies or substantial portions of the Software.
|
|
43
|
-
|
|
44
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
45
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
46
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
47
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
48
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
49
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
50
|
-
SOFTWARE.
|
|
51
|
-
|
|
52
|
-
https://github.com/DWTechs/Checkard.js
|
|
53
|
-
*/
|
|
54
|
-
|
|
55
|
-
function isNumeric(n) {
|
|
56
|
-
return !isNaN(n - parseFloat(n));
|
|
57
|
-
}
|
|
58
|
-
function getTag(t) {
|
|
59
|
-
return t == null ? t === undefined ? '[object Undefined]' : '[object Null]' : toString.call(t);
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
function isBoolean(b) {
|
|
63
|
-
return typeof b === "boolean";
|
|
64
|
-
}
|
|
65
|
-
function isNumber(n, type = true) {
|
|
66
|
-
return !isSymbol(n) && !((n === null || n === void 0 ? void 0 : n.constructor) === Array) && (type ? Number(n) === n : isNumeric(n));
|
|
67
|
-
}
|
|
68
|
-
function isSymbol(s) {
|
|
69
|
-
const type = typeof s;
|
|
70
|
-
return type === 'symbol' || (type === 'object' && s != null && getTag(s) === '[object Symbol]');
|
|
71
|
-
}
|
|
72
|
-
function isNil(n) {
|
|
73
|
-
return n == null;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function isFunction(func) {
|
|
77
|
-
return Boolean(func && getTag(func) === "[object Function]");
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const comparisons = {
|
|
81
|
-
'=': (a, b) => a == b,
|
|
82
|
-
'<': (a, b) => a < b,
|
|
83
|
-
'>': (a, b) => a > b,
|
|
84
|
-
'<=': (a, b) => a <= b,
|
|
85
|
-
'>=': (a, b) => a >= b
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
function isAscii(c, ext = true) {
|
|
89
|
-
return isInteger(c, false) && ((ext && c >= 0 && c <= 255) || (c >= 0 && c <= 127));
|
|
90
|
-
}
|
|
91
|
-
function isInteger(n, type = true) {
|
|
92
|
-
if (!isNumber(n, type))
|
|
93
|
-
return false;
|
|
94
|
-
const int = Number.parseInt(String(n), 10);
|
|
95
|
-
return type ? n === int : n == int;
|
|
96
|
-
}
|
|
97
|
-
function isFloat(n, type = true) {
|
|
98
|
-
if (isSymbol(n))
|
|
99
|
-
return false;
|
|
100
|
-
const modulo = n % 1 !== 0;
|
|
101
|
-
return type ? (Number(n) === n && modulo) : (Number(n) == n && modulo);
|
|
102
|
-
}
|
|
103
|
-
function isEven(n, type = true) {
|
|
104
|
-
return isInteger(n, type) && !(n & 1);
|
|
105
|
-
}
|
|
106
|
-
function isOdd(n, type = true) {
|
|
107
|
-
return isInteger(n, type) && Boolean(n & 1);
|
|
108
|
-
}
|
|
109
|
-
function isOrigin(n, type = true) {
|
|
110
|
-
return type ? n === 0 : n == 0;
|
|
111
|
-
}
|
|
112
|
-
function isPositive(n, type = true) {
|
|
113
|
-
return isNumber(n, type) && n > 0;
|
|
114
|
-
}
|
|
115
|
-
function isNegative(n, type = true) {
|
|
116
|
-
return isNumber(n, type) && n < 0;
|
|
117
|
-
}
|
|
118
|
-
function isPowerOfTwo(n, type = true) {
|
|
119
|
-
return isInteger(n, type) && !isOrigin(n, type) && (n & (n - 1)) === 0;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function isValidNumber(n, min = -999999999, max = 999999999, type = true) {
|
|
123
|
-
return isNumber(n, type) && n >= min && n <= max;
|
|
124
|
-
}
|
|
125
|
-
function isValidInteger(n, min = -999999999, max = 999999999, type = true) {
|
|
126
|
-
return isInteger(n, type) && n >= min && n <= max;
|
|
127
|
-
}
|
|
128
|
-
function isValidFloat(n, min = -999999999.9, max = 999999999.9, type = true) {
|
|
129
|
-
return isFloat(n, type) && n >= min && n <= max;
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
function isArray(a, comp, len) {
|
|
133
|
-
return (a === null || a === void 0 ? void 0 : a.constructor) === Array ? (comp && isValidInteger(len, 0, 999999999)) ? comparisons.hasOwnProperty(comp) ? comparisons[comp](a.length, len) : false : true : false;
|
|
134
|
-
}
|
|
135
|
-
function isArrayOfLength(a, min = -999999999, max = 999999999) {
|
|
136
|
-
if (isArray(a, null, null)) {
|
|
137
|
-
const n = a.length;
|
|
138
|
-
return n >= min && n <= max;
|
|
139
|
-
}
|
|
140
|
-
return false;
|
|
141
|
-
}
|
|
142
|
-
function isIn(val, arr) {
|
|
143
|
-
return isArray(arr, '>', 0) ? arr.includes(val) : false;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function isString(s, required = false) {
|
|
147
|
-
return typeof s === "string" && (required ? !!s : true);
|
|
148
|
-
}
|
|
149
|
-
function isStringOfLength(s, min = 0, max = 999999999) {
|
|
150
|
-
if (isString(s, false)) {
|
|
151
|
-
const l = s.length;
|
|
152
|
-
return l >= min && l <= max;
|
|
153
|
-
}
|
|
154
|
-
return false;
|
|
155
|
-
}
|
|
156
|
-
function isJson(s) {
|
|
157
|
-
if (!isString(s))
|
|
158
|
-
return false;
|
|
159
|
-
try {
|
|
160
|
-
JSON.parse(s);
|
|
161
|
-
}
|
|
162
|
-
catch (e) {
|
|
163
|
-
return false;
|
|
164
|
-
}
|
|
165
|
-
return true;
|
|
166
|
-
}
|
|
167
|
-
function isRegex(r, type = true) {
|
|
168
|
-
if (type)
|
|
169
|
-
return r instanceof RegExp;
|
|
170
|
-
try {
|
|
171
|
-
new RegExp(r);
|
|
172
|
-
}
|
|
173
|
-
catch (e) {
|
|
174
|
-
return false;
|
|
175
|
-
}
|
|
176
|
-
return true;
|
|
177
|
-
}
|
|
178
|
-
const emailReg = /^(?=[a-z0-9@.!$%&'*+\/=?^_‘{|}~-]{6,254}$)(?=[a-z0-9.!#$%&'*+\/=?^_‘{|}~-]{1,64}@)[a-z0-9!#$%&'*+\/=?^‘{|}~]+(?:[\._-][a-z0-9!#$%&'*+\/=?^‘{|}~]+)*@(?:(?=[a-z0-9-]{1,63}\.)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+(?=[a-z0-9-]{2,63}$)[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/;
|
|
179
|
-
function isEmail(e) {
|
|
180
|
-
return !isSymbol(e) && emailReg.test(String(e).toLowerCase());
|
|
181
|
-
}
|
|
182
|
-
const ipReg = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
|
|
183
|
-
function isIpAddress(i) {
|
|
184
|
-
return !isSymbol(i) && ipReg.test(i);
|
|
185
|
-
}
|
|
186
|
-
const b64Reg = /^[A-Za-z0-9\-_]+={0,2}$/;
|
|
187
|
-
function isJWT(t) {
|
|
188
|
-
if (!isString(t))
|
|
189
|
-
return false;
|
|
190
|
-
const p = t.split('.');
|
|
191
|
-
if (p.length !== 3)
|
|
192
|
-
return false;
|
|
193
|
-
const header = p[0];
|
|
194
|
-
const payload = p[1];
|
|
195
|
-
const signature = p[3];
|
|
196
|
-
if (b64Reg.test(header) && b64Reg.test(payload) && b64Reg.test(signature)) {
|
|
197
|
-
try {
|
|
198
|
-
return isJson(atob(header)) && isJson(atob(payload));
|
|
199
|
-
}
|
|
200
|
-
catch (e) {
|
|
201
|
-
return false;
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
return false;
|
|
205
|
-
}
|
|
206
|
-
const slugReg = /^[^\s-_](?!.*?[-_]{2,})[a-z0-9-\\][^\s]*[^-_\s]$/;
|
|
207
|
-
function isSlug(s) {
|
|
208
|
-
return isString(s) && slugReg.test(s);
|
|
209
|
-
}
|
|
210
|
-
const hexadecimal = /^(#|0x|0h)?[0-9A-F]+$/i;
|
|
211
|
-
function isHexadecimal(s) {
|
|
212
|
-
return isString(s) && hexadecimal.test(s);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
function isObject(o, empty = false) {
|
|
216
|
-
return o !== null && typeof o === "object" && !isArray(o) && (empty ? !!Object.keys(o).length : true);
|
|
217
|
-
}
|
|
218
|
-
function isProperty(val, obj) {
|
|
219
|
-
const v = String(val);
|
|
220
|
-
return isString(v, true) && isObject(obj) ? Object.keys(obj).includes(v) : false;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
function isHtmlElement(h) {
|
|
224
|
-
return Boolean(typeof HTMLElement === "object"
|
|
225
|
-
? h instanceof HTMLElement
|
|
226
|
-
: h &&
|
|
227
|
-
typeof h === "object" &&
|
|
228
|
-
h.nodeType === 1 &&
|
|
229
|
-
typeof h.nodeName === "string");
|
|
230
|
-
}
|
|
231
|
-
function isHtmlEventAttribute(h) {
|
|
232
|
-
switch (h) {
|
|
233
|
-
case "onafterprint":
|
|
234
|
-
case "onbeforeprint":
|
|
235
|
-
case "onbeforeunload":
|
|
236
|
-
case "onerror":
|
|
237
|
-
case "onhashchange":
|
|
238
|
-
case "onload":
|
|
239
|
-
case "onmessage":
|
|
240
|
-
case "onoffline":
|
|
241
|
-
case "ononline":
|
|
242
|
-
case "onpagehide":
|
|
243
|
-
case "onpageshow":
|
|
244
|
-
case "onpopstate":
|
|
245
|
-
case "onresize":
|
|
246
|
-
case "onstorage":
|
|
247
|
-
case "onunload":
|
|
248
|
-
case "onblur":
|
|
249
|
-
case "onchange":
|
|
250
|
-
case "oncontextmenu":
|
|
251
|
-
case "onfocus":
|
|
252
|
-
case "oninput":
|
|
253
|
-
case "oninvalid":
|
|
254
|
-
case "onreset":
|
|
255
|
-
case "onsearch":
|
|
256
|
-
case "onselect":
|
|
257
|
-
case "onsubmit":
|
|
258
|
-
case "onkeydown":
|
|
259
|
-
case "onkeypress":
|
|
260
|
-
case "onkeyup":
|
|
261
|
-
case "onclick":
|
|
262
|
-
case "ondblclick":
|
|
263
|
-
case "onmousedown":
|
|
264
|
-
case "onmousemove":
|
|
265
|
-
case "onmouseout":
|
|
266
|
-
case "onmouseover":
|
|
267
|
-
case "onmouseup":
|
|
268
|
-
case "onmousewheel":
|
|
269
|
-
case "onwheel":
|
|
270
|
-
case "ondrag":
|
|
271
|
-
case "ondragend":
|
|
272
|
-
case "ondragenter":
|
|
273
|
-
case "ondragleave":
|
|
274
|
-
case "ondragover":
|
|
275
|
-
case "ondragstart":
|
|
276
|
-
case "ondrop":
|
|
277
|
-
case "onscroll":
|
|
278
|
-
case "oncopy":
|
|
279
|
-
case "oncut":
|
|
280
|
-
case "onpaste":
|
|
281
|
-
case "onabort":
|
|
282
|
-
case "oncanplay":
|
|
283
|
-
case "oncanplaythrough":
|
|
284
|
-
case "oncuechange":
|
|
285
|
-
case "ondurationchange":
|
|
286
|
-
case "onemptied":
|
|
287
|
-
case "onended":
|
|
288
|
-
case "onerror":
|
|
289
|
-
case "onloadeddata":
|
|
290
|
-
case "onloadedmetadata":
|
|
291
|
-
case "onloadstart":
|
|
292
|
-
case "onpause":
|
|
293
|
-
case "onplay":
|
|
294
|
-
case "onplaying":
|
|
295
|
-
case "onprogress":
|
|
296
|
-
case "onratechange":
|
|
297
|
-
case "onseeked":
|
|
298
|
-
case "onseeking":
|
|
299
|
-
case "onstalled":
|
|
300
|
-
case "onsuspend":
|
|
301
|
-
case "ontimeupdate":
|
|
302
|
-
case "onvolumechange":
|
|
303
|
-
case "onwaiting":
|
|
304
|
-
case "ontoggle":
|
|
305
|
-
return true;
|
|
306
|
-
default:
|
|
307
|
-
return false;
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
function isNode(n) {
|
|
311
|
-
return Boolean(typeof Node === "object"
|
|
312
|
-
? n instanceof Node
|
|
313
|
-
: n &&
|
|
314
|
-
typeof n === "object" &&
|
|
315
|
-
typeof n.nodeType === "number" &&
|
|
316
|
-
typeof n.nodeName === "string");
|
|
317
|
-
}
|
|
318
|
-
|
|
319
|
-
function isDate(d) {
|
|
320
|
-
return !isNaN(d) && d instanceof Date;
|
|
321
|
-
}
|
|
322
|
-
const minDate = new Date('1/1/1900');
|
|
323
|
-
const maxDate = new Date('1/1/2200');
|
|
324
|
-
function isValidDate(d, min = minDate, max = maxDate) {
|
|
325
|
-
return isDate(d) && d >= min && d <= max;
|
|
326
|
-
}
|
|
327
|
-
function isTimestamp(t, type = true) {
|
|
328
|
-
return isInteger(t, type) && isNumeric(new Date(parseInt(t + '')).getTime());
|
|
329
|
-
}
|
|
330
|
-
function isValidTimestamp(t, min = -2208989361000, max = 7258114800000, type = true) {
|
|
331
|
-
return isTimestamp(t, type) && t >= min && t <= max;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
const Methods = ["GET", "PATCH", "PUT", "POST", "DELETE"];
|
|
335
|
-
|
|
336
|
-
const Types = {
|
|
337
|
-
boolean: {
|
|
338
|
-
validate: (v, _min, _max, _typeCheck) => isBoolean(v)
|
|
339
|
-
},
|
|
340
|
-
string: {
|
|
341
|
-
validate: (v, min, max, _typeCheck) => isStringOfLength(v, min, max)
|
|
342
|
-
},
|
|
343
|
-
number: {
|
|
344
|
-
validate: (v, min, max, typeCheck) => isValidNumber(v, min || undefined, max || undefined, typeCheck || undefined)
|
|
345
|
-
},
|
|
346
|
-
integer: {
|
|
347
|
-
validate: (v, min, max, typeCheck) => isValidInteger(v, min || undefined, max || undefined, typeCheck || undefined)
|
|
348
|
-
},
|
|
349
|
-
float: {
|
|
350
|
-
validate: (v, min, max, typeCheck) => isValidFloat(v, min || undefined, max || undefined, typeCheck || undefined)
|
|
351
|
-
},
|
|
352
|
-
even: {
|
|
353
|
-
validate: (v, _min, _max, typeCheck) => isEven(v, typeCheck || undefined)
|
|
354
|
-
},
|
|
355
|
-
odd: {
|
|
356
|
-
validate: (v, _min, _max, typeCheck) => isOdd(v, typeCheck || undefined)
|
|
357
|
-
},
|
|
358
|
-
positive: {
|
|
359
|
-
validate: (v, _min, _max, typeCheck) => isPositive(v, typeCheck || undefined)
|
|
360
|
-
},
|
|
361
|
-
negative: {
|
|
362
|
-
validate: (v, _min, _max, typeCheck) => isNegative(v, typeCheck || undefined)
|
|
363
|
-
},
|
|
364
|
-
powerOfTwo: {
|
|
365
|
-
validate: (v, _min, _max, typeCheck) => isPowerOfTwo(v, typeCheck || undefined)
|
|
366
|
-
},
|
|
367
|
-
ascii: {
|
|
368
|
-
validate: (v, _min, _max, typeCheck) => isAscii(v, typeCheck || undefined)
|
|
369
|
-
},
|
|
370
|
-
array: {
|
|
371
|
-
validate: (v, min, max, _typeCheck) => isArrayOfLength(v, min || undefined, max || undefined)
|
|
372
|
-
},
|
|
373
|
-
email: {
|
|
374
|
-
validate: (v, _min, _max, _typeCheck) => isEmail(v)
|
|
375
|
-
},
|
|
376
|
-
regex: {
|
|
377
|
-
validate: (v, _min, _max, typeCheck) => isRegex(v, typeCheck || undefined)
|
|
378
|
-
},
|
|
379
|
-
json: {
|
|
380
|
-
validate: (v, _min, _max, _typeCheck) => isJson(v)
|
|
381
|
-
},
|
|
382
|
-
jwt: {
|
|
383
|
-
validate: (v, _min, _max, _typeCheck) => isJWT(v)
|
|
384
|
-
},
|
|
385
|
-
symbol: {
|
|
386
|
-
validate: (v, _min, _max, _typeCheck) => isSymbol(v)
|
|
387
|
-
},
|
|
388
|
-
ipAddress: {
|
|
389
|
-
validate: (v, _min, _max, _typeCheck) => isIpAddress(v)
|
|
390
|
-
},
|
|
391
|
-
slug: {
|
|
392
|
-
validate: (v, _min, _max, _typeCheck) => isSlug(v)
|
|
393
|
-
},
|
|
394
|
-
hexadecimal: {
|
|
395
|
-
validate: (v, _min, _max, _typeCheck) => isHexadecimal(v)
|
|
396
|
-
},
|
|
397
|
-
date: {
|
|
398
|
-
validate: (v, min, max, _typeCheck) => isValidDate(v, min || undefined, max || undefined)
|
|
399
|
-
},
|
|
400
|
-
timestamp: {
|
|
401
|
-
validate: (v, min, max, typeCheck) => isValidTimestamp(v, min || undefined, max || undefined, typeCheck || undefined)
|
|
402
|
-
},
|
|
403
|
-
function: {
|
|
404
|
-
validate: (v, _min, _max, _typeCheck) => isFunction(v)
|
|
405
|
-
},
|
|
406
|
-
htmlElement: {
|
|
407
|
-
validate: (v, _min, _max, _typeCheck) => isHtmlElement(v)
|
|
408
|
-
},
|
|
409
|
-
htmlEventAttribute: {
|
|
410
|
-
validate: (v, _min, _max, _typeCheck) => isHtmlEventAttribute(v)
|
|
411
|
-
},
|
|
412
|
-
node: {
|
|
413
|
-
validate: (v, _min, _max, _typeCheck) => isNode(v)
|
|
414
|
-
},
|
|
415
|
-
object: {
|
|
416
|
-
validate: (v, _min, _max, _typeCheck) => isObject(v)
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
const Required = {
|
|
420
|
-
validate: (v) => !isNil(v)
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
class Property {
|
|
424
|
-
constructor(key, type, min, max, required, typeCheck, methods, sanitize, normalize, control, sanitizer, normalizer, controller) {
|
|
425
|
-
if (!isString(key, true))
|
|
426
|
-
throw new Error(`Property key must be a string. Received ${key}`);
|
|
427
|
-
if (!isProperty(type, Types))
|
|
428
|
-
throw new Error(`Property type must be a valid type. Received ${type}`);
|
|
429
|
-
if (isArray(methods)) {
|
|
430
|
-
for (const m of methods) {
|
|
431
|
-
if (!isIn(m, Methods))
|
|
432
|
-
throw new Error(`Property methods must be an array of REST Methods. Received ${m}`);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
this.key = key;
|
|
436
|
-
this.type = type;
|
|
437
|
-
this.min = isInteger(min, true) ? min : 0;
|
|
438
|
-
this.max = isInteger(max, true) ? max : 999999999;
|
|
439
|
-
this.required = isBoolean(required) ? required : false;
|
|
440
|
-
this.typeCheck = isBoolean(typeCheck) ? typeCheck : false;
|
|
441
|
-
this.methods = methods || Methods;
|
|
442
|
-
this.sanitize = isBoolean(sanitize) ? sanitize : true;
|
|
443
|
-
this.normalize = isBoolean(normalize) ? normalize : false;
|
|
444
|
-
this.control = isBoolean(control) ? control : true;
|
|
445
|
-
this.sanitizer = isFunction(sanitizer) ? sanitizer : null;
|
|
446
|
-
this.normalizer = isFunction(normalizer) ? normalizer : null;
|
|
447
|
-
this.controller = isFunction(controller) ? controller : null;
|
|
448
|
-
}
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
const Messages = {
|
|
452
|
-
missing: (key) => `Missing ${key}`,
|
|
453
|
-
invalid: (key, type) => `Invalid ${key}, must be of type ${type}`,
|
|
454
|
-
};
|
|
455
|
-
|
|
456
|
-
class Entity {
|
|
457
|
-
constructor(name, table, properties) {
|
|
458
|
-
this.name = name;
|
|
459
|
-
this.table = table;
|
|
460
|
-
this.cols = {
|
|
461
|
-
GET: "",
|
|
462
|
-
POST: "",
|
|
463
|
-
PUT: "",
|
|
464
|
-
PATCH: "",
|
|
465
|
-
DELETE: "",
|
|
466
|
-
};
|
|
467
|
-
this.properties = this.init(properties);
|
|
468
|
-
}
|
|
469
|
-
init(properties) {
|
|
470
|
-
const props = [];
|
|
471
|
-
for (const p of properties) {
|
|
472
|
-
props.push(new Property(p.key, p.type, p.min, p.max, p.required, p.typeCheck, p.methods, p.sanitize, p.normalize, p.control, p.sanitizer, p.normalizer, p.controller));
|
|
473
|
-
for (const m of p.methods) {
|
|
474
|
-
this.cols[m] += this.cols[m].length ? `, ${p.key}` : `${p.key}`;
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
return props;
|
|
478
|
-
}
|
|
479
|
-
getTable() {
|
|
480
|
-
return this.table;
|
|
481
|
-
}
|
|
482
|
-
getCols(method) {
|
|
483
|
-
return this.cols[method];
|
|
484
|
-
}
|
|
485
|
-
normalize(rows) {
|
|
486
|
-
for (const r of rows) {
|
|
487
|
-
for (const { key, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
488
|
-
let v = r[key];
|
|
489
|
-
if (v) {
|
|
490
|
-
if (sanitize)
|
|
491
|
-
v = this.sanitize(v, sanitizer);
|
|
492
|
-
if (normalize && normalizer)
|
|
493
|
-
v = normalizer(v);
|
|
494
|
-
r[key] = v;
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
return rows;
|
|
499
|
-
}
|
|
500
|
-
validate(rows, method) {
|
|
501
|
-
for (const r of rows) {
|
|
502
|
-
for (const { key, type, min, max, required, typeCheck, methods, control, controller } of this.properties) {
|
|
503
|
-
const v = r[key];
|
|
504
|
-
if (method && isIn(method, methods)) {
|
|
505
|
-
if (required) {
|
|
506
|
-
const rq = this.require(v, key);
|
|
507
|
-
if (rq)
|
|
508
|
-
return rq;
|
|
509
|
-
}
|
|
510
|
-
if (v && control) {
|
|
511
|
-
const ct = this.control(v, key, type, min, max, typeCheck, controller);
|
|
512
|
-
if (ct)
|
|
513
|
-
return ct;
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
return null;
|
|
519
|
-
}
|
|
520
|
-
require(v, key) {
|
|
521
|
-
return Required.validate(v) ? null : Messages.missing(key);
|
|
522
|
-
}
|
|
523
|
-
control(v, key, type, min, max, typeCheck, cb) {
|
|
524
|
-
if (cb)
|
|
525
|
-
return cb(v) ? null : Messages.invalid(key, type);
|
|
526
|
-
return Types[type].validate(v, min, max, typeCheck) ? null : Messages.invalid(key, type);
|
|
527
|
-
}
|
|
528
|
-
sanitize(v, cb) {
|
|
529
|
-
if (cb)
|
|
530
|
-
return cb(v);
|
|
531
|
-
if (isArray(v, null, null)) {
|
|
532
|
-
for (let d of v) {
|
|
533
|
-
d = this.trim(d);
|
|
534
|
-
}
|
|
535
|
-
return v;
|
|
536
|
-
}
|
|
537
|
-
return this.trim(v);
|
|
538
|
-
}
|
|
539
|
-
trim(v) {
|
|
540
|
-
if (isString(v, true))
|
|
541
|
-
return v.trim();
|
|
542
|
-
if (isObject(v, true)) {
|
|
543
|
-
if (v.has)
|
|
544
|
-
for (const p in v) {
|
|
545
|
-
if (v.prototype.hasOwnProperty.call(p)) {
|
|
546
|
-
let o = v[p];
|
|
547
|
-
if (isString(o, true))
|
|
548
|
-
o = o.trim();
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
return v;
|
|
552
|
-
}
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
exports.Entity = Entity;
|