@dwtechs/antity 0.16.0 → 0.18.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 CHANGED
@@ -136,7 +136,10 @@ type Type =
136
136
  "htmlElement" |
137
137
  "htmlEventAttribute" |
138
138
  "node" |
139
- "object";
139
+ "object" |
140
+ "ansiEscapeCode" |
141
+ "locale" |
142
+ "timeZone";
140
143
 
141
144
  type Method = "PATCH" | "PUT" | "POST";
142
145
 
package/dist/antity.d.ts CHANGED
@@ -55,7 +55,10 @@ type Type =
55
55
  "htmlElement" |
56
56
  "htmlEventAttribute" |
57
57
  "node" |
58
- "object";
58
+ "object" |
59
+ "ansiEscapeCode" |
60
+ "locale" |
61
+ "timeZone";
59
62
 
60
63
  declare class Entity {
61
64
  private _name;
package/dist/antity.js CHANGED
@@ -24,8 +24,9 @@ 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, isValidPassword, 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';
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, isAnsiEscapeCode, isLocale, isTimeZone, isString, isProperty, isArray, isIn, isDate, isNumber, isInteger, isNil } from '@dwtechs/checkard';
28
28
  import { log } from '@dwtechs/winstan';
29
+ import { isValidPassword } from '@dwtechs/passken';
29
30
 
30
31
  const LOGS_PREFIX = "Antity: ";
31
32
  const METHODS = ["PATCH", "PUT", "POST"];
@@ -48,7 +49,7 @@ const Types = {
48
49
  validate: (v, min, max, typeCheck) => isValidNumber(v, min || undefined, max || undefined, typeCheck || undefined, true)
49
50
  },
50
51
  integer: {
51
- validate: (v, min, max, typeCheck) => isValidInteger(v, min !== null && min !== void 0 ? min : undefined, max !== null && max !== void 0 ? max : undefined, typeCheck || undefined, true)
52
+ validate: (v, min, max, typeCheck) => isValidInteger(v, min ?? undefined, max ?? undefined, typeCheck || undefined, true)
52
53
  },
53
54
  float: {
54
55
  validate: (v, min, max, typeCheck) => isValidFloat(v, min || undefined, max || undefined, typeCheck || undefined, true)
@@ -77,12 +78,12 @@ const Types = {
77
78
  password: {
78
79
  validate: (v, min, max, _typeCheck) => {
79
80
  const o = {
80
- minLength: min || PWD_MIN_LENGTH,
81
- maxLength: max || PWD_MAX_LENGTH,
82
- lowerCase: PWD_LOWERCASE,
83
- upperCase: PWD_UPPERCASE,
84
- number: PWD_NUMBERS,
85
- specialCharacter: PWD_SYMBOLS,
81
+ minLen: min || PWD_MIN_LENGTH,
82
+ maxLen: max || PWD_MAX_LENGTH,
83
+ lcase: PWD_LOWERCASE,
84
+ ucase: PWD_UPPERCASE,
85
+ num: PWD_NUMBERS,
86
+ sym: PWD_SYMBOLS,
86
87
  };
87
88
  return isValidPassword(v, o, true);
88
89
  }
@@ -131,10 +132,29 @@ const Types = {
131
132
  },
132
133
  object: {
133
134
  validate: (v, _min, _max, _typeCheck) => isObject(v, true)
135
+ },
136
+ ansiEscapeCode: {
137
+ validate: (v, _min, _max, _typeCheck) => isAnsiEscapeCode(v, true)
138
+ },
139
+ locale: {
140
+ validate: (v, _min, _max, typeCheck) => isLocale(v, typeCheck || undefined, true)
141
+ },
142
+ timeZone: {
143
+ validate: (v, _min, _max, _typeCheck) => isTimeZone(v, true)
134
144
  }
135
145
  };
136
146
 
137
147
  class Property {
148
+ key;
149
+ type;
150
+ min;
151
+ max;
152
+ isPrivate;
153
+ requiredFor;
154
+ isTypeChecked;
155
+ sanitizer;
156
+ normalizer;
157
+ validator;
138
158
  constructor(key, type, min, max, isPrivate, requiredFor, isTypeChecked, sanitizer, normalizer, validator) {
139
159
  try {
140
160
  isString(key, "!0", null, true);
@@ -180,8 +200,8 @@ function sanitize(v, cb) {
180
200
  if (cb)
181
201
  return cb(v);
182
202
  if (isArray(v, null, null)) {
183
- for (let d of v) {
184
- d = trim(d);
203
+ for (let i = 0; i < v.length; i++) {
204
+ v[i] = trim(v[i]);
185
205
  }
186
206
  return v;
187
207
  }
@@ -191,12 +211,11 @@ function trim(v) {
191
211
  if (isString(v, "!0"))
192
212
  return v.trim();
193
213
  if (isObject(v, true)) {
194
- for (const k in v) {
195
- if (Object.prototype.hasOwnProperty.call(v, k)) {
196
- let o = v[k];
197
- if (isString(o, "!0", null))
198
- o = o.trim();
199
- }
214
+ const obj = v;
215
+ for (const k of Object.keys(obj)) {
216
+ const o = obj[k];
217
+ if (isString(o, "!0", null))
218
+ obj[k] = o.trim();
200
219
  }
201
220
  }
202
221
  return v;
@@ -208,7 +227,7 @@ function normalize(record, properties) {
208
227
  if (v) {
209
228
  log.debug(`sanitize ${key}: ${type} = ${v}`);
210
229
  v = sanitize(v, sanitizer);
211
- if (isFunction(normalizer)) {
230
+ if (normalizer) {
212
231
  log.debug(`normalize ${key}: ${type} = ${v}`);
213
232
  v = normalizer(v);
214
233
  }
@@ -247,7 +266,7 @@ function require(v, key, type) {
247
266
  function validate(record, properties, method) {
248
267
  for (const { key, type, min, max, requiredFor, isTypeChecked, validator } of properties) {
249
268
  const v = record[key];
250
- if (isIn(requiredFor, method)) {
269
+ if (requiredFor.includes(method)) {
251
270
  const rq = require(v, key, type);
252
271
  if (rq)
253
272
  return rq;
@@ -261,71 +280,27 @@ function validate(record, properties, method) {
261
280
  return null;
262
281
  }
263
282
 
283
+ const STANDARD_PROP_KEYS = new Set(['key', 'type', 'min', 'max', 'isPrivate', 'requiredFor', 'isTypeChecked', 'sanitizer', 'normalizer', 'validator']);
264
284
  class Entity {
285
+ _name;
286
+ _privateProps;
287
+ _properties;
288
+ _propsByMethod;
265
289
  constructor(name, properties) {
266
- this.normalizeArray = (req, _res, next) => {
267
- var _a;
268
- log.debug(`normalizeArray ${this.name}`);
269
- const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
270
- if (!isArray(rows, ">", 0))
271
- return next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no rows found in request body` });
272
- for (const r of rows) {
273
- normalize(r, this._properties);
274
- }
275
- next();
276
- };
277
- this.normalizeOne = (req, _res, next) => {
278
- log.debug(`normalizeOne ${this.name}`);
279
- const r = req.body;
280
- if (!isObject(r, true))
281
- return next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no data found in request body` });
282
- normalize(r, this._properties);
283
- next();
284
- };
285
- this.validateArray = (req, _res, next) => {
286
- var _a;
287
- log.debug(`validateArray ${this.name}`);
288
- const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
289
- const method = req.method;
290
- if (!isArray(rows, ">", 0))
291
- return next({ statusCode: 400, message: `${LOGS_PREFIX}Validate: no rows found in request body` });
292
- if (!isIn(METHODS, method))
293
- return next({
294
- statusCode: 400,
295
- message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}`
296
- });
297
- for (const r of rows) {
298
- const error = validate(r, this._properties, method);
299
- if (error)
300
- return next(error);
301
- }
302
- next();
303
- };
304
- this.validateOne = (req, _res, next) => {
305
- log.debug(`validateOne ${this.name}`);
306
- const record = req.body;
307
- const method = req.method;
308
- if (!isObject(record, true))
309
- return next({ statusCode: 400, message: `${LOGS_PREFIX}Validate: no data found in request body` });
310
- if (!isIn(METHODS, method))
311
- return next({
312
- statusCode: 400,
313
- message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}`
314
- });
315
- const error = validate(record, this._properties, method);
316
- if (error)
317
- return next(error);
318
- next();
319
- };
320
290
  this._name = name;
321
291
  this._properties = [];
322
292
  this._privateProps = [];
293
+ this._propsByMethod = new Map(METHODS.map(m => [m, []]));
323
294
  for (const p of properties) {
324
295
  const prop = new Property(p.key, p.type, p.min, p.max, p.isPrivate, p.requiredFor, p.isTypeChecked, p.sanitizer, p.normalizer, p.validator);
325
- Object.assign(prop, p);
296
+ for (const k of Object.keys(p))
297
+ if (!STANDARD_PROP_KEYS.has(k))
298
+ prop[k] = p[k];
326
299
  this._properties.push(prop);
327
300
  if (prop.isPrivate)
328
301
  this._privateProps.push(prop.key);
302
+ for (const m of prop.requiredFor)
303
+ this._propsByMethod.get(m)?.push(prop);
329
304
  }
330
305
  }
331
306
  get name() {
@@ -346,13 +321,70 @@ class Entity {
346
321
  return this.properties.find(p => p.key === key);
347
322
  }
348
323
  getPropsByMethod(method) {
349
- const props = [];
350
- for (const p of this.properties) {
351
- if (isIn(p.requiredFor, method, 0))
352
- props.push(p);
353
- }
354
- return props;
324
+ return this._propsByMethod.get(method) ?? [];
355
325
  }
326
+ normalizeArray = (req, _res, next) => {
327
+ log.debug(`normalizeArray ${this.name}`);
328
+ const rows = req.body?.rows;
329
+ if (!isArray(rows, ">", 0)) {
330
+ next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no rows found in request body` });
331
+ return;
332
+ }
333
+ for (const r of rows) {
334
+ normalize(r, this._properties);
335
+ }
336
+ next();
337
+ };
338
+ normalizeOne = (req, _res, next) => {
339
+ log.debug(`normalizeOne ${this.name}`);
340
+ const r = req.body;
341
+ if (!isObject(r, true)) {
342
+ next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no data found in request body` });
343
+ return;
344
+ }
345
+ normalize(r, this._properties);
346
+ next();
347
+ };
348
+ validateArray = (req, _res, next) => {
349
+ log.debug(`validateArray ${this.name}`);
350
+ const rows = req.body?.rows;
351
+ const method = req.method;
352
+ if (!isArray(rows, ">", 0)) {
353
+ next({ statusCode: 400, message: `${LOGS_PREFIX}Validate: no rows found in request body` });
354
+ return;
355
+ }
356
+ if (!METHODS.includes(method)) {
357
+ next({ statusCode: 400, message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}` });
358
+ return;
359
+ }
360
+ for (const r of rows) {
361
+ const error = validate(r, this._properties, method);
362
+ if (error) {
363
+ next(error);
364
+ return;
365
+ }
366
+ }
367
+ next();
368
+ };
369
+ validateOne = (req, _res, next) => {
370
+ log.debug(`validateOne ${this.name}`);
371
+ const record = req.body;
372
+ const method = req.method;
373
+ if (!isObject(record, true)) {
374
+ next({ statusCode: 400, message: `${LOGS_PREFIX}Validate: no data found in request body` });
375
+ return;
376
+ }
377
+ if (!METHODS.includes(method)) {
378
+ next({ statusCode: 400, message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}` });
379
+ return;
380
+ }
381
+ const error = validate(record, this._properties, method);
382
+ if (error) {
383
+ next(error);
384
+ return;
385
+ }
386
+ next();
387
+ };
356
388
  }
357
389
 
358
390
  export { Entity };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwtechs/antity",
3
- "version": "0.16.0",
3
+ "version": "0.18.0",
4
4
  "description": "Open source library for easy entity management",
5
5
  "keywords": [
6
6
  "entities"
@@ -13,8 +13,7 @@
13
13
  "url": "https://github.com/DWTechs/Antity.js"
14
14
  },
15
15
  "bugs": {
16
- "url": "https://github.com/DWTechs/Antity.js/issues",
17
- "email": ""
16
+ "url": "https://github.com/DWTechs/Antity.js/issues"
18
17
  },
19
18
  "license": "MIT",
20
19
  "author": {
@@ -22,36 +21,34 @@
22
21
  "email": "http://www.lcluber.com/contact",
23
22
  "url": "http://www.lcluber.com"
24
23
  },
25
- "contributors": [],
26
24
  "scripts": {
27
- "start": "",
28
25
  "prebuild": "npm install",
29
26
  "build": "node ./scripts/clear && tsc && npm run rollup && node ./scripts/copy && npm run test",
30
- "rollup:mjs": "rollup --config rollup.config.mjs",
31
- "rollup:cjs": "rollup --config rollup.config.cjs.mjs",
32
- "rollup": "npm run rollup:mjs",
33
- "test": "jest --coverage --config jest.config.js"
27
+ "rollup": "rollup --config rollup.config.mjs",
28
+ "test": "jest --coverage"
34
29
  },
35
30
  "files": [
36
31
  "dist/"
37
32
  ],
33
+ "engines": {
34
+ "node": ">= 22"
35
+ },
38
36
  "dependencies": {
39
- "@dwtechs/checkard": "3.5.1",
40
- "@dwtechs/winstan": "0.4.0",
41
- "@dwtechs/sparray": "0.2.1"
37
+ "@dwtechs/checkard": "3.6.0",
38
+ "@dwtechs/passken": "0.6.1",
39
+ "@dwtechs/sparray": "0.2.1",
40
+ "@dwtechs/winstan": "0.7.0"
42
41
  },
43
42
  "devDependencies": {
44
43
  "@babel/core": "7.26.0",
45
44
  "@babel/preset-env": "7.26.0",
46
- "@rollup/plugin-commonjs": "28.0.1",
47
- "@rollup/plugin-node-resolve": "15.3.0",
45
+ "@types/express": "5.0.6",
48
46
  "@types/jest": "29.5.14",
49
- "@types/node": "22.10.1",
50
- "@types/express": "5.0.0",
47
+ "@types/node": "25.6.0",
51
48
  "babel-jest": "29.7.0",
52
49
  "core-js": "3.33.0",
53
50
  "jest": "29.7.0",
54
51
  "rollup": "4.24.0",
55
- "typescript": "5.8.3"
52
+ "typescript": "6.0.3"
56
53
  }
57
54
  }