@dwtechs/antity 0.4.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/dist/antity.js +8 -3
- package/package.json +3 -3
- package/dist/antity.cjs.js +0 -588
package/dist/antity.js
CHANGED
|
@@ -25,6 +25,7 @@ https://github.com/DWTechs/Antity.js
|
|
|
25
25
|
*/
|
|
26
26
|
|
|
27
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
30
|
const Operations = ["select", "insert", "update", "merge", "delete"];
|
|
30
31
|
|
|
@@ -193,13 +194,15 @@ class Entity {
|
|
|
193
194
|
}
|
|
194
195
|
normalize(rows) {
|
|
195
196
|
for (const r of rows) {
|
|
196
|
-
for (const { key, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
197
|
+
for (const { key, type, sanitize, normalize, sanitizer, normalizer, } of this.properties) {
|
|
197
198
|
let v = r[key];
|
|
198
199
|
if (v) {
|
|
199
200
|
if (sanitize) {
|
|
201
|
+
log.debug(`sanitize ${key}: ${type} = ${v}`);
|
|
200
202
|
v = this.sanitize(v, sanitizer);
|
|
201
203
|
}
|
|
202
204
|
if (normalize && normalizer) {
|
|
205
|
+
log.debug(`normalize ${key}: ${type} = ${v}`);
|
|
203
206
|
v = normalizer(v);
|
|
204
207
|
}
|
|
205
208
|
r[key] = v;
|
|
@@ -216,7 +219,7 @@ class Entity {
|
|
|
216
219
|
const v = r[key];
|
|
217
220
|
if (isIn(operation, operations)) {
|
|
218
221
|
if (required) {
|
|
219
|
-
const rq = this.require(v, key);
|
|
222
|
+
const rq = this.require(v, key, type);
|
|
220
223
|
if (rq)
|
|
221
224
|
return rq;
|
|
222
225
|
}
|
|
@@ -230,10 +233,12 @@ class Entity {
|
|
|
230
233
|
}
|
|
231
234
|
return null;
|
|
232
235
|
}
|
|
233
|
-
require(v, key) {
|
|
236
|
+
require(v, key, type) {
|
|
237
|
+
log.debug(`require ${key}: ${type} = ${v}`);
|
|
234
238
|
return Required.validate(v) ? null : Messages.missing(key);
|
|
235
239
|
}
|
|
236
240
|
control(v, key, type, min, max, typeCheck, cb) {
|
|
241
|
+
log.debug(`control ${key}: ${type} = ${v}`);
|
|
237
242
|
if (cb)
|
|
238
243
|
return cb(v) ? null : Messages.invalid(key, type);
|
|
239
244
|
return Types[type].validate(v, min, max, typeCheck) ? null : Messages.invalid(key, type);
|
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,7 +28,7 @@
|
|
|
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": [
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
38
|
"@dwtechs/checkard": "2.29.2",
|
|
39
|
-
"@dwtechs/winstan": "0.
|
|
39
|
+
"@dwtechs/winstan": "0.3.0",
|
|
40
40
|
"pg": "8.13.1"
|
|
41
41
|
},
|
|
42
42
|
"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;
|