@dwtechs/antity 0.4.0 → 0.6.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 +75 -58
- package/dist/antity.d.ts +25 -24
- package/dist/antity.js +57 -77
- package/package.json +6 -4
- package/dist/antity.cjs.js +0 -588
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ const entity = new Entity("consumers", [
|
|
|
57
57
|
min: 0,
|
|
58
58
|
max: 120,
|
|
59
59
|
typeCheck: true,
|
|
60
|
-
operations: ["
|
|
60
|
+
operations: ["GET", "PUT", "DELETE"],
|
|
61
61
|
required: true,
|
|
62
62
|
safe: true,
|
|
63
63
|
sanitize: true,
|
|
@@ -73,7 +73,7 @@ const entity = new Entity("consumers", [
|
|
|
73
73
|
min: 0,
|
|
74
74
|
max: 255,
|
|
75
75
|
typeCheck: true,
|
|
76
|
-
operations: ["
|
|
76
|
+
operations: ["GET", "POST", "PUT", "DELETE"],
|
|
77
77
|
required: true,
|
|
78
78
|
safe: true,
|
|
79
79
|
sanitize: true,
|
|
@@ -89,7 +89,7 @@ const entity = new Entity("consumers", [
|
|
|
89
89
|
min: 0,
|
|
90
90
|
max: 255,
|
|
91
91
|
typeCheck: true,
|
|
92
|
-
operations: ["
|
|
92
|
+
operations: ["GET", "POST", "PUT", "DELETE"],
|
|
93
93
|
required: true,
|
|
94
94
|
safe: true,
|
|
95
95
|
sanitize: true,
|
|
@@ -105,7 +105,7 @@ const entity = new Entity("consumers", [
|
|
|
105
105
|
min: 0,
|
|
106
106
|
max: 255,
|
|
107
107
|
typeCheck: true,
|
|
108
|
-
operations: ["
|
|
108
|
+
operations: ["GET", "POST", "PUT", "DELETE"],
|
|
109
109
|
required: true,
|
|
110
110
|
safe: true,
|
|
111
111
|
sanitize: true,
|
|
@@ -118,7 +118,7 @@ const entity = new Entity("consumers", [
|
|
|
118
118
|
]);
|
|
119
119
|
|
|
120
120
|
req.body = entity.normalize(req.body); // will also sanitize if true
|
|
121
|
-
const check = entity.validate(req.body, "
|
|
121
|
+
const check = entity.validate(req.body, "GET");
|
|
122
122
|
const unsafeProps = entity.getUnsafeProps();
|
|
123
123
|
|
|
124
124
|
```
|
|
@@ -129,35 +129,35 @@ const unsafeProps = entity.getUnsafeProps();
|
|
|
129
129
|
|
|
130
130
|
```javascript
|
|
131
131
|
|
|
132
|
-
type Type =
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
132
|
+
type Type =
|
|
133
|
+
"boolean" |
|
|
134
|
+
"string" |
|
|
135
|
+
"number" |
|
|
136
|
+
"integer" |
|
|
137
|
+
"float" |
|
|
138
|
+
"even" |
|
|
139
|
+
"odd" |
|
|
140
|
+
"positive" |
|
|
141
|
+
"negative" |
|
|
142
|
+
"powerOfTwo" |
|
|
143
|
+
"ascii" |
|
|
144
|
+
"array" |
|
|
145
|
+
"jwt" |
|
|
146
|
+
"symbol" |
|
|
147
|
+
"email" |
|
|
148
|
+
"regex" |
|
|
149
|
+
"json" |
|
|
150
|
+
"ipAddress" |
|
|
151
|
+
"slug" |
|
|
152
|
+
"hexadecimal" |
|
|
153
|
+
"date" |
|
|
154
|
+
"timestamp" |
|
|
155
|
+
"function" |
|
|
156
|
+
"htmlElement" |
|
|
157
|
+
"htmlEventAttribute" |
|
|
158
|
+
"node" |
|
|
159
|
+
"object";
|
|
159
160
|
|
|
160
|
-
type Operation = "select" | "insert" | "update" | "merge" | "delete";
|
|
161
161
|
type Method = "GET" | "PATCH" | "PUT" | "POST" | "DELETE";
|
|
162
162
|
|
|
163
163
|
class Property {
|
|
@@ -168,7 +168,7 @@ class Property {
|
|
|
168
168
|
required: boolean;
|
|
169
169
|
safe: boolean;
|
|
170
170
|
typeCheck: boolean;
|
|
171
|
-
|
|
171
|
+
methods: Method[];
|
|
172
172
|
sanitize: boolean;
|
|
173
173
|
normalize: boolean;
|
|
174
174
|
control: boolean;
|
|
@@ -178,38 +178,55 @@ class Property {
|
|
|
178
178
|
};
|
|
179
179
|
|
|
180
180
|
class Entity {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
181
|
+
constructor(name: string, properties: Property[]);
|
|
182
|
+
get name(): string;
|
|
183
|
+
get unsafeProps(): string[];
|
|
184
|
+
get properties(): Property[];
|
|
185
|
+
set name(name: string);
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Retrieves a property from the `properties` array that matches the specified key.
|
|
189
|
+
*
|
|
190
|
+
* @param {string} key - The key of the property to retrieve.
|
|
191
|
+
* @returns {Property | undefined} - The property object if found, otherwise `undefined`.
|
|
192
|
+
*/
|
|
193
|
+
getProp(key: string): Property | undefined;
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Normalizes an array of records by applying sanitization and normalization
|
|
197
|
+
* 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
|
+
*/
|
|
204
|
+
normalize(rows: Record<string, unknown>[]): Record<string, unknown>[];
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Validates a set of rows against the defined properties and operation/method.
|
|
208
|
+
*
|
|
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
|
+
* If a property is required and missing, or if it fails the control checks, the function returns an error message.
|
|
216
|
+
* Otherwise, it returns `null` indicating successful validation.
|
|
217
|
+
*/
|
|
218
|
+
validate(rows: Record<string, unknown>[], method: Method): string | null;
|
|
190
219
|
}
|
|
191
220
|
|
|
192
221
|
```
|
|
193
222
|
|
|
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
223
|
examples :
|
|
207
224
|
|
|
208
225
|
```javascript
|
|
209
226
|
|
|
210
|
-
entity.validate(req.body, "GET"); // will validate
|
|
211
|
-
entity.validate(req.body, "PUT"); // will validate
|
|
212
|
-
entity.validate(req.body, "DELETE"); // will validate
|
|
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
|
|
213
230
|
|
|
214
231
|
```
|
|
215
232
|
|
package/dist/antity.d.ts
CHANGED
|
@@ -25,9 +25,7 @@ https://github.com/DWTechs/Antity.js
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
27
|
|
|
28
|
-
type Operation = typeof Operations[number];
|
|
29
28
|
type Method = typeof Methods[number];
|
|
30
|
-
|
|
31
29
|
type Type =
|
|
32
30
|
"boolean" |
|
|
33
31
|
"string" |
|
|
@@ -57,11 +55,15 @@ type Type =
|
|
|
57
55
|
"node" |
|
|
58
56
|
"object";
|
|
59
57
|
|
|
60
|
-
declare const Operations: readonly [ "select", "insert", "update", "merge", "delete" ];
|
|
61
58
|
declare const Methods: readonly [ "GET", "PATCH", "PUT", "POST", "DELETE" ];
|
|
62
59
|
|
|
63
60
|
declare const Types: Record<Type, {
|
|
64
|
-
validate: (
|
|
61
|
+
validate: (
|
|
62
|
+
v: any,
|
|
63
|
+
min: number | Date,
|
|
64
|
+
max: number | Date,
|
|
65
|
+
typeCheck: boolean
|
|
66
|
+
) => boolean;
|
|
65
67
|
}>;
|
|
66
68
|
|
|
67
69
|
declare const Required: {
|
|
@@ -69,24 +71,22 @@ declare const Required: {
|
|
|
69
71
|
};
|
|
70
72
|
|
|
71
73
|
declare class Entity {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
constructor(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
private sanitize;
|
|
84
|
-
private trim;
|
|
74
|
+
private _name;
|
|
75
|
+
private _unsafeProps;
|
|
76
|
+
private _properties;
|
|
77
|
+
constructor(name: string, properties: Property[]);
|
|
78
|
+
get name(): string;
|
|
79
|
+
get unsafeProps(): string[];
|
|
80
|
+
get properties(): Property[];
|
|
81
|
+
set name(name: string);
|
|
82
|
+
getProp(key: string): Property | undefined;
|
|
83
|
+
normalize(rows: Record<string, unknown>[]): Record<string, unknown>[];
|
|
84
|
+
validate(rows: Record<string, unknown>[], method: Method): string | null;
|
|
85
85
|
}
|
|
86
86
|
|
|
87
87
|
declare const Messages: {
|
|
88
|
-
|
|
89
|
-
|
|
88
|
+
missing: (key: string) => string;
|
|
89
|
+
invalid: (key: string, type: Type) => string;
|
|
90
90
|
};
|
|
91
91
|
|
|
92
92
|
declare class Property {
|
|
@@ -97,21 +97,22 @@ declare class Property {
|
|
|
97
97
|
required: boolean;
|
|
98
98
|
safe: boolean;
|
|
99
99
|
typeCheck: boolean;
|
|
100
|
-
|
|
100
|
+
methods: Method[];
|
|
101
101
|
sanitize: boolean;
|
|
102
102
|
normalize: boolean;
|
|
103
103
|
control: boolean;
|
|
104
104
|
sanitizer: ((v: any) => any) | null;
|
|
105
105
|
normalizer: ((v: any) => any) | null;
|
|
106
106
|
controller: ((v: any) => any) | null;
|
|
107
|
-
constructor(
|
|
107
|
+
constructor(
|
|
108
|
+
key: string,
|
|
108
109
|
type: Type,
|
|
109
110
|
min: number | Date,
|
|
110
111
|
max: number | Date,
|
|
111
112
|
required: boolean,
|
|
112
113
|
safe: boolean,
|
|
113
114
|
typeCheck: boolean,
|
|
114
|
-
|
|
115
|
+
methods: Method[],
|
|
115
116
|
sanitize: boolean,
|
|
116
117
|
normalize: boolean,
|
|
117
118
|
control: boolean,
|
|
@@ -121,13 +122,13 @@ declare class Property {
|
|
|
121
122
|
);
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
export type { Type,
|
|
125
|
+
export type { Type, Method };
|
|
125
126
|
export {
|
|
126
127
|
Entity,
|
|
127
128
|
Property,
|
|
128
129
|
Messages,
|
|
129
130
|
Types,
|
|
130
131
|
Required,
|
|
131
|
-
|
|
132
|
+
Methods,
|
|
132
133
|
};
|
|
133
134
|
|
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,
|
|
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, isString, isProperty, isArray, isIn, isDate, isNumber, isInteger, isNil } from '@dwtechs/checkard';
|
|
28
|
+
import { log } from '@dwtechs/winstan';
|
|
28
29
|
|
|
29
|
-
const
|
|
30
|
+
const Methods = ["GET", "PATCH", "PUT", "POST", "DELETE"];
|
|
30
31
|
|
|
31
32
|
const Types = {
|
|
32
33
|
boolean: {
|
|
@@ -111,20 +112,17 @@ const Types = {
|
|
|
111
112
|
validate: (v, _min, _max, _typeCheck) => isObject(v)
|
|
112
113
|
}
|
|
113
114
|
};
|
|
114
|
-
const Required = {
|
|
115
|
-
validate: (v) => !isNil(v)
|
|
116
|
-
};
|
|
117
115
|
|
|
118
116
|
class Property {
|
|
119
|
-
constructor(key, type, min, max, required, safe, typeCheck,
|
|
120
|
-
if (!isString(key,
|
|
121
|
-
throw new Error(`Property"key" must be a string. Received ${key}`);
|
|
122
|
-
if (!isProperty(
|
|
117
|
+
constructor(key, type, min, max, required, safe, typeCheck, methods, sanitize, normalize, control, sanitizer, normalizer, controller) {
|
|
118
|
+
if (!isString(key, "!0"))
|
|
119
|
+
throw new Error(`Property "key" must be a string. Received ${key}`);
|
|
120
|
+
if (!isProperty(Types, type))
|
|
123
121
|
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 "
|
|
122
|
+
if (isArray(methods)) {
|
|
123
|
+
for (const m of methods) {
|
|
124
|
+
if (!isIn(Methods, m))
|
|
125
|
+
throw new Error(`Property "methods" must be an array of REST methods. Received ${m}`);
|
|
128
126
|
}
|
|
129
127
|
}
|
|
130
128
|
this.key = key;
|
|
@@ -134,7 +132,7 @@ class Property {
|
|
|
134
132
|
this.required = isBoolean(required) ? required : false;
|
|
135
133
|
this.safe = isBoolean(safe) ? safe : true;
|
|
136
134
|
this.typeCheck = isBoolean(typeCheck) ? typeCheck : false;
|
|
137
|
-
this.
|
|
135
|
+
this.methods = methods || Methods;
|
|
138
136
|
this.sanitize = isBoolean(sanitize) ? sanitize : true;
|
|
139
137
|
this.normalize = isBoolean(normalize) ? normalize : false;
|
|
140
138
|
this.control = isBoolean(control) ? control : true;
|
|
@@ -145,7 +143,7 @@ class Property {
|
|
|
145
143
|
interval(val, type, integerDefault, dateDefault) {
|
|
146
144
|
if (type === "date")
|
|
147
145
|
return isDate(val) ? val : new Date(dateDefault);
|
|
148
|
-
return isInteger(val, true) ? val : integerDefault;
|
|
146
|
+
return (isNumber(val, true) && isInteger(val, true)) ? val : integerDefault;
|
|
149
147
|
}
|
|
150
148
|
}
|
|
151
149
|
|
|
@@ -154,52 +152,46 @@ const Messages = {
|
|
|
154
152
|
invalid: (key, type) => `Invalid ${key}, must be of type ${type}`,
|
|
155
153
|
};
|
|
156
154
|
|
|
157
|
-
const Methods = ["GET", "PATCH", "PUT", "POST", "DELETE"];
|
|
158
|
-
|
|
159
155
|
class Entity {
|
|
160
|
-
constructor(
|
|
161
|
-
this.
|
|
162
|
-
this.
|
|
163
|
-
this.
|
|
164
|
-
select: [],
|
|
165
|
-
insert: [],
|
|
166
|
-
update: [],
|
|
167
|
-
merge: [],
|
|
168
|
-
delete: []
|
|
169
|
-
};
|
|
170
|
-
this.unsafeProps = [];
|
|
156
|
+
constructor(name, properties) {
|
|
157
|
+
this._name = name;
|
|
158
|
+
this._properties = [];
|
|
159
|
+
this._unsafeProps = [];
|
|
171
160
|
for (const p of properties) {
|
|
172
|
-
const prop = new Property(p.key, p.type, p.min, p.max, p.required, p.safe, p.typeCheck, p.
|
|
173
|
-
this.
|
|
174
|
-
for (const o of p.operations) {
|
|
175
|
-
if (o === "update")
|
|
176
|
-
this.cols[o].push(`${p.key} = $${this.cols[o].length + 1}`);
|
|
177
|
-
else
|
|
178
|
-
this.cols[o].push(p.key);
|
|
179
|
-
}
|
|
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.control, p.sanitizer, p.normalizer, p.controller);
|
|
162
|
+
this._properties.push(prop);
|
|
180
163
|
if (!prop.safe)
|
|
181
|
-
this.
|
|
164
|
+
this._unsafeProps.push(prop.key);
|
|
182
165
|
}
|
|
183
166
|
}
|
|
184
|
-
|
|
185
|
-
return this.
|
|
167
|
+
get name() {
|
|
168
|
+
return this._name;
|
|
169
|
+
}
|
|
170
|
+
get unsafeProps() {
|
|
171
|
+
return this._unsafeProps;
|
|
186
172
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
return stringify ? cols.join(', ') : cols;
|
|
173
|
+
get properties() {
|
|
174
|
+
return this._properties;
|
|
190
175
|
}
|
|
191
|
-
|
|
192
|
-
|
|
176
|
+
set name(name) {
|
|
177
|
+
if (!isString(name, "!0"))
|
|
178
|
+
throw new Error('name must be a string of length > 0');
|
|
179
|
+
this._name = name;
|
|
180
|
+
}
|
|
181
|
+
getProp(key) {
|
|
182
|
+
return this.properties.find(p => p.key === key);
|
|
193
183
|
}
|
|
194
184
|
normalize(rows) {
|
|
195
185
|
for (const r of rows) {
|
|
196
|
-
for (const { key, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
186
|
+
for (const { key, type, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
197
187
|
let v = r[key];
|
|
198
188
|
if (v) {
|
|
199
189
|
if (sanitize) {
|
|
190
|
+
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
200
191
|
v = this.sanitize(v, sanitizer);
|
|
201
192
|
}
|
|
202
193
|
if (normalize && normalizer) {
|
|
194
|
+
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
203
195
|
v = normalizer(v);
|
|
204
196
|
}
|
|
205
197
|
r[key] = v;
|
|
@@ -208,15 +200,15 @@ class Entity {
|
|
|
208
200
|
}
|
|
209
201
|
return rows;
|
|
210
202
|
}
|
|
211
|
-
validate(rows,
|
|
212
|
-
if (isIn(
|
|
213
|
-
|
|
203
|
+
validate(rows, method) {
|
|
204
|
+
if (!isIn(Methods, method))
|
|
205
|
+
return `Invalid REST method. Received: ${method}. Must be one of: ${Methods.toString()}`;
|
|
214
206
|
for (const r of rows) {
|
|
215
|
-
for (const { key, type, min, max, required, typeCheck,
|
|
207
|
+
for (const { key, type, min, max, required, typeCheck, methods, control, controller } of this.properties) {
|
|
216
208
|
const v = r[key];
|
|
217
|
-
if (isIn(
|
|
209
|
+
if (isIn(methods, method)) {
|
|
218
210
|
if (required) {
|
|
219
|
-
const rq = this.require(v, key);
|
|
211
|
+
const rq = this.require(v, key, type);
|
|
220
212
|
if (rq)
|
|
221
213
|
return rq;
|
|
222
214
|
}
|
|
@@ -230,13 +222,16 @@ class Entity {
|
|
|
230
222
|
}
|
|
231
223
|
return null;
|
|
232
224
|
}
|
|
233
|
-
require(v, key) {
|
|
234
|
-
|
|
225
|
+
require(v, key, type) {
|
|
226
|
+
log.debug(`require ${key}: ${type} = ${v}`);
|
|
227
|
+
return isNil(v) ? Messages.missing(key) : null;
|
|
235
228
|
}
|
|
236
229
|
control(v, key, type, min, max, typeCheck, cb) {
|
|
230
|
+
log.debug(`control ${key}: ${type} = ${v}`);
|
|
237
231
|
if (cb)
|
|
238
232
|
return cb(v) ? null : Messages.invalid(key, type);
|
|
239
|
-
|
|
233
|
+
const val = Types[type].validate(v, min, max, typeCheck);
|
|
234
|
+
return val ? null : Messages.invalid(key, type);
|
|
240
235
|
}
|
|
241
236
|
sanitize(v, cb) {
|
|
242
237
|
if (cb)
|
|
@@ -250,33 +245,18 @@ class Entity {
|
|
|
250
245
|
return this.trim(v);
|
|
251
246
|
}
|
|
252
247
|
trim(v) {
|
|
253
|
-
if (isString(v,
|
|
248
|
+
if (isString(v, "!0"))
|
|
254
249
|
return v.trim();
|
|
255
250
|
if (isObject(v, true)) {
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
o = o.trim();
|
|
262
|
-
}
|
|
251
|
+
for (const k in v) {
|
|
252
|
+
if (Object.prototype.hasOwnProperty.call(v, k)) {
|
|
253
|
+
let o = v[k];
|
|
254
|
+
if (isString(o, "!0", null))
|
|
255
|
+
o = o.trim();
|
|
263
256
|
}
|
|
264
|
-
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
mapMethods(method) {
|
|
268
|
-
switch (method) {
|
|
269
|
-
case "GET":
|
|
270
|
-
return Operations[0];
|
|
271
|
-
case "PATCH":
|
|
272
|
-
return Operations[2];
|
|
273
|
-
case "PUT":
|
|
274
|
-
return Operations[2];
|
|
275
|
-
case "POST":
|
|
276
|
-
return Operations[1];
|
|
277
|
-
case "DELETE":
|
|
278
|
-
return Operations[4];
|
|
257
|
+
}
|
|
279
258
|
}
|
|
259
|
+
return v;
|
|
280
260
|
}
|
|
281
261
|
}
|
|
282
262
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dwtechs/antity",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Open source library for easy entity management",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"entities"
|
|
@@ -25,18 +25,20 @@
|
|
|
25
25
|
"contributors": [],
|
|
26
26
|
"scripts": {
|
|
27
27
|
"start": "",
|
|
28
|
+
"prebuild": "npm install",
|
|
28
29
|
"build": "node ./scripts/clear && tsc && npm run rollup && node ./scripts/copy && npm run test",
|
|
29
30
|
"rollup:mjs": "rollup --config rollup.config.mjs",
|
|
30
31
|
"rollup:cjs": "rollup --config rollup.config.cjs.mjs",
|
|
31
|
-
"rollup": "npm run rollup:mjs
|
|
32
|
+
"rollup": "npm run rollup:mjs",
|
|
32
33
|
"test": "jest --coverage"
|
|
33
34
|
},
|
|
34
35
|
"files": [
|
|
35
36
|
"dist/"
|
|
36
37
|
],
|
|
37
38
|
"dependencies": {
|
|
38
|
-
"@dwtechs/checkard": "2.
|
|
39
|
-
"@dwtechs/winstan": "0.
|
|
39
|
+
"@dwtechs/checkard": "3.2.3",
|
|
40
|
+
"@dwtechs/winstan": "0.4.0",
|
|
41
|
+
"@dwtechs/sparray": "0.1.1",
|
|
40
42
|
"pg": "8.13.1"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
package/dist/antity.cjs.js
DELETED
|
@@ -1,588 +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 Operations = ["select", "insert", "update", "merge", "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, safe, typeCheck, operations, 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(operations)) {
|
|
430
|
-
for (const o of operations) {
|
|
431
|
-
if (!isIn(o, Operations))
|
|
432
|
-
throw new Error(`Property "operations" must be an array of SQL operations. Received ${o}`);
|
|
433
|
-
}
|
|
434
|
-
}
|
|
435
|
-
this.key = key;
|
|
436
|
-
this.type = type;
|
|
437
|
-
this.min = this.interval(min, type, 0, "1900-01-01T00:00:00Z");
|
|
438
|
-
this.max = this.interval(max, type, 999999999, "2200-12-31T00:00:00Z");
|
|
439
|
-
this.required = isBoolean(required) ? required : false;
|
|
440
|
-
this.safe = isBoolean(safe) ? safe : true;
|
|
441
|
-
this.typeCheck = isBoolean(typeCheck) ? typeCheck : false;
|
|
442
|
-
this.operations = operations || Operations;
|
|
443
|
-
this.sanitize = isBoolean(sanitize) ? sanitize : true;
|
|
444
|
-
this.normalize = isBoolean(normalize) ? normalize : false;
|
|
445
|
-
this.control = isBoolean(control) ? control : true;
|
|
446
|
-
this.sanitizer = isFunction(sanitizer) ? sanitizer : null;
|
|
447
|
-
this.normalizer = isFunction(normalizer) ? normalizer : null;
|
|
448
|
-
this.controller = isFunction(controller) ? controller : null;
|
|
449
|
-
}
|
|
450
|
-
interval(val, type, integerDefault, dateDefault) {
|
|
451
|
-
if (type === "date")
|
|
452
|
-
return isDate(val) ? val : new Date(dateDefault);
|
|
453
|
-
return isInteger(val, true) ? val : integerDefault;
|
|
454
|
-
}
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
const Messages = {
|
|
458
|
-
missing: (key) => `Missing ${key}`,
|
|
459
|
-
invalid: (key, type) => `Invalid ${key}, must be of type ${type}`,
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
const Methods = ["GET", "PATCH", "PUT", "POST", "DELETE"];
|
|
463
|
-
|
|
464
|
-
class Entity {
|
|
465
|
-
constructor(table, properties) {
|
|
466
|
-
this.table = table;
|
|
467
|
-
this.properties = [];
|
|
468
|
-
this.cols = {
|
|
469
|
-
select: [],
|
|
470
|
-
insert: [],
|
|
471
|
-
update: [],
|
|
472
|
-
merge: [],
|
|
473
|
-
delete: []
|
|
474
|
-
};
|
|
475
|
-
this.unsafeProps = [];
|
|
476
|
-
for (const p of properties) {
|
|
477
|
-
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);
|
|
478
|
-
this.properties.push(prop);
|
|
479
|
-
for (const o of p.operations) {
|
|
480
|
-
if (o === "update")
|
|
481
|
-
this.cols[o].push(`${p.key} = $${this.cols[o].length + 1}`);
|
|
482
|
-
else
|
|
483
|
-
this.cols[o].push(p.key);
|
|
484
|
-
}
|
|
485
|
-
if (!prop.safe)
|
|
486
|
-
this.unsafeProps.push(prop.key);
|
|
487
|
-
}
|
|
488
|
-
}
|
|
489
|
-
getTable() {
|
|
490
|
-
return this.table;
|
|
491
|
-
}
|
|
492
|
-
getCols(operation, stringify, pagination) {
|
|
493
|
-
const cols = pagination && operation === "select" ? [...this.cols[operation], "COUNT(*) OVER () AS total"] : this.cols[operation];
|
|
494
|
-
return stringify ? cols.join(', ') : cols;
|
|
495
|
-
}
|
|
496
|
-
getUnsafeProps() {
|
|
497
|
-
return this.unsafeProps;
|
|
498
|
-
}
|
|
499
|
-
normalize(rows) {
|
|
500
|
-
for (const r of rows) {
|
|
501
|
-
for (const { key, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
502
|
-
let v = r[key];
|
|
503
|
-
if (v) {
|
|
504
|
-
if (sanitize) {
|
|
505
|
-
v = this.sanitize(v, sanitizer);
|
|
506
|
-
}
|
|
507
|
-
if (normalize && normalizer) {
|
|
508
|
-
v = normalizer(v);
|
|
509
|
-
}
|
|
510
|
-
r[key] = v;
|
|
511
|
-
}
|
|
512
|
-
}
|
|
513
|
-
}
|
|
514
|
-
return rows;
|
|
515
|
-
}
|
|
516
|
-
validate(rows, operation) {
|
|
517
|
-
if (isIn(operation, Methods))
|
|
518
|
-
operation = this.mapMethods(operation);
|
|
519
|
-
for (const r of rows) {
|
|
520
|
-
for (const { key, type, min, max, required, typeCheck, operations, control, controller } of this.properties) {
|
|
521
|
-
const v = r[key];
|
|
522
|
-
if (isIn(operation, operations)) {
|
|
523
|
-
if (required) {
|
|
524
|
-
const rq = this.require(v, key);
|
|
525
|
-
if (rq)
|
|
526
|
-
return rq;
|
|
527
|
-
}
|
|
528
|
-
if (v && control) {
|
|
529
|
-
const ct = this.control(v, key, type, min, max, typeCheck, controller);
|
|
530
|
-
if (ct)
|
|
531
|
-
return ct;
|
|
532
|
-
}
|
|
533
|
-
}
|
|
534
|
-
}
|
|
535
|
-
}
|
|
536
|
-
return null;
|
|
537
|
-
}
|
|
538
|
-
require(v, key) {
|
|
539
|
-
return Required.validate(v) ? null : Messages.missing(key);
|
|
540
|
-
}
|
|
541
|
-
control(v, key, type, min, max, typeCheck, cb) {
|
|
542
|
-
if (cb)
|
|
543
|
-
return cb(v) ? null : Messages.invalid(key, type);
|
|
544
|
-
return Types[type].validate(v, min, max, typeCheck) ? null : Messages.invalid(key, type);
|
|
545
|
-
}
|
|
546
|
-
sanitize(v, cb) {
|
|
547
|
-
if (cb)
|
|
548
|
-
return cb(v);
|
|
549
|
-
if (isArray(v, null, null)) {
|
|
550
|
-
for (let d of v) {
|
|
551
|
-
d = this.trim(d);
|
|
552
|
-
}
|
|
553
|
-
return v;
|
|
554
|
-
}
|
|
555
|
-
return this.trim(v);
|
|
556
|
-
}
|
|
557
|
-
trim(v) {
|
|
558
|
-
if (isString(v, true))
|
|
559
|
-
return v.trim();
|
|
560
|
-
if (isObject(v, true)) {
|
|
561
|
-
if (v.has)
|
|
562
|
-
for (const p in v) {
|
|
563
|
-
if (v.prototype.hasOwnProperty.call(p)) {
|
|
564
|
-
let o = v[p];
|
|
565
|
-
if (isString(o, true))
|
|
566
|
-
o = o.trim();
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
return v;
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
mapMethods(method) {
|
|
573
|
-
switch (method) {
|
|
574
|
-
case "GET":
|
|
575
|
-
return Operations[0];
|
|
576
|
-
case "PATCH":
|
|
577
|
-
return Operations[2];
|
|
578
|
-
case "PUT":
|
|
579
|
-
return Operations[2];
|
|
580
|
-
case "POST":
|
|
581
|
-
return Operations[1];
|
|
582
|
-
case "DELETE":
|
|
583
|
-
return Operations[4];
|
|
584
|
-
}
|
|
585
|
-
}
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
exports.Entity = Entity;
|