@dwtechs/antity 0.13.0 → 0.14.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
@@ -112,9 +112,9 @@ const entity = new Entity("consumers", [
112
112
  },
113
113
  ]);
114
114
 
115
- // add a consumer. Used when loggin in from user service
116
- router.post("/", entity.normalize, entity.validate, ...);
117
- // or use check method to both normalize and validate at once
115
+ // add a consumer. Used when logging in from user service
116
+ router.post("/", entity.normalizeArray, entity.validateArray, ...);
117
+ // or use check method to normalize and validate array at once
118
118
  router.put("/", entity.check, ...);
119
119
 
120
120
  ```
@@ -227,11 +227,12 @@ class Entity {
227
227
  getPropsByMethod(method: Method): Property[];
228
228
 
229
229
  /**
230
- * Normalizes each row in req.body.rows according to property config and HTTP method.
230
+ * Normalizes an array of records by applying sanitization and normalization
231
+ * rules defined in the properties of the class.
231
232
  *
232
- * - Applies sanitization if `sanitize: true` and method matches
233
- * - Applies normalization if `normalize: true` and method matches
234
- * - Mutates req.body.rows with sanitized/normalized values
233
+ * - Applies sanitization if `sanitize: true`
234
+ * - Applies normalization if `normalize: true`
235
+ * - Mutates req.body.rows or req.body with sanitized/normalized values
235
236
  * - Calls next(error) on failure, next() on success
236
237
  *
237
238
  * @param {Request} req - Express request object containing rows
@@ -241,25 +242,58 @@ class Entity {
241
242
  * @returns {void}
242
243
  *
243
244
  * **Input Properties Required:**
244
- * - `req.body.rows` (array) - Array of objects to normalize
245
+ * - `req.body.rows` (array) or `req.body` (array) - Array of objects to normalize
245
246
  * - Each property config can specify sanitize, normalize, etc.
246
247
  *
247
248
  * **Output Properties:**
248
- * - Mutates `req.body.rows` with sanitized/normalized values
249
- * - Calls next(error) if any row fails normalization, next() if all pass
249
+ * - Mutates array with sanitized/normalized values
250
+ * - Calls next(error) if normalization fails, next() if all pass
250
251
  *
251
252
  * @example
252
253
  * ```typescript
253
- * router.post('/entity', entity.normalize, (req, res) => {
254
+ * router.post('/entities', entity.normalizeArray, (req, res) => {
254
255
  * // req.body.rows are now sanitized and normalized
255
256
  * res.json({ success: true });
256
257
  * });
257
258
  * ```
258
259
  */
259
- normalize: (req: Request, _res: Response, next: NextFunction) => void;
260
+ normalizeArray: (req: Request, _res: Response, next: NextFunction) => void;
261
+
262
+ /**
263
+ * Normalizes a single record by applying sanitization and normalization
264
+ * rules defined in the properties of the class.
265
+ *
266
+ * - Applies sanitization if `sanitize: true`
267
+ * - Applies normalization if `normalize: true`
268
+ * - Mutates req.body with sanitized/normalized values
269
+ * - Calls next(error) on failure, next() on success
270
+ *
271
+ * @param {Request} req - Express request object containing a single record
272
+ * @param {Response} _res - Express response object (not used)
273
+ * @param {NextFunction} next - Express next function
274
+ *
275
+ * @returns {void}
276
+ *
277
+ * **Input Properties Required:**
278
+ * - `req.body` (object) - Single object to normalize
279
+ * - Each property config can specify sanitize, normalize, etc.
280
+ *
281
+ * **Output Properties:**
282
+ * - Mutates `req.body` with sanitized/normalized values
283
+ * - Calls next(error) if normalization fails, next() if success
284
+ *
285
+ * @example
286
+ * ```typescript
287
+ * router.post('/entity', entity.normalizeOne, (req, res) => {
288
+ * // req.body is now sanitized and normalized
289
+ * res.json({ success: true });
290
+ * });
291
+ * ```
292
+ */
293
+ normalizeOne: (req: Request, _res: Response, next: NextFunction) => void;
260
294
 
261
295
  /**
262
- * Validates each row in req.body.rows according to property config and HTTP method.
296
+ * Validates an array of rows according to property config and HTTP method.
263
297
  *
264
298
  * - Checks required properties and validates values
265
299
  * - Calls next(error) on failure, next() on success
@@ -271,7 +305,7 @@ class Entity {
271
305
  * @returns {void}
272
306
  *
273
307
  * **Input Properties Required:**
274
- * - `req.body.rows` (array) - Array of objects to validate
308
+ * - `req.body.rows` (array) or `req.body` (array) - Array of objects to validate
275
309
  * - Each property config can specify validate, required, etc.
276
310
  *
277
311
  * **Output Properties:**
@@ -279,13 +313,42 @@ class Entity {
279
313
  *
280
314
  * @example
281
315
  * ```typescript
282
- * router.post('/entity', entity.validate, (req, res) => {
316
+ * router.post('/entities', entity.validateArray, (req, res) => {
283
317
  * // req.body.rows are now validated
284
318
  * res.json({ success: true });
285
319
  * });
286
320
  * ```
287
321
  */
288
- validate: (req: Request, _res: Response, next: NextFunction) => void;
322
+ validateArray: (req: Request, _res: Response, next: NextFunction) => void;
323
+
324
+ /**
325
+ * Validates a single record according to property config and HTTP method.
326
+ *
327
+ * - Checks required properties and validates values
328
+ * - Calls next(error) on failure, next() on success
329
+ *
330
+ * @param {Request} req - Express request object containing a single record
331
+ * @param {Response} _res - Express response object (not used)
332
+ * @param {NextFunction} next - Express next function
333
+ *
334
+ * @returns {void}
335
+ *
336
+ * **Input Properties Required:**
337
+ * - `req.body` (object) - Single object to validate
338
+ * - Each property config can specify validate, required, etc.
339
+ *
340
+ * **Output Properties:**
341
+ * - Calls next(error) if validation fails, next() if success
342
+ *
343
+ * @example
344
+ * ```typescript
345
+ * router.post('/entity', entity.validateOne, (req, res) => {
346
+ * // req.body is now validated
347
+ * res.json({ success: true });
348
+ * });
349
+ * ```
350
+ */
351
+ validateOne: (req: Request, _res: Response, next: NextFunction) => void;
289
352
 
290
353
  /**
291
354
  * Checks, sanitizes, normalizes, and validates each row in req.body.rows according to property config and HTTP method.
@@ -321,8 +384,10 @@ class Entity {
321
384
  }
322
385
 
323
386
  ```
324
- normalize() and validate() methods are made to be used as Express.js middlewares.
325
- Each method will look for data to work on in the **req.body.rows** parameter.
387
+ **normalizeArray()**, **normalizeOne()**, **validateArray()**, and **validateOne()** methods are made to be used as Express.js middlewares.
388
+
389
+ - **normalizeArray()** and **validateArray()** will look for data in the **req.body.rows** parameter or **req.body** as an array.
390
+ - **normalizeOne()** and **validateOne()** will look for data in the **req.body** parameter as a single object.
326
391
 
327
392
 
328
393
  ### Password validation
package/dist/antity.d.ts CHANGED
@@ -68,8 +68,10 @@ declare class Entity {
68
68
  set name(name: string);
69
69
  getProp(key: string): Property | undefined;
70
70
  getPropsByMethod(method: Method): Property[];
71
- normalize: (req: Request, _res: Response, next: NextFunction) => void;
72
- validate: (req: Request, _res: Response, next: NextFunction) => void;
71
+ normalizeArray: (req: Request, _res: Response, next: NextFunction) => void;
72
+ normalizeOne: (req: Request, _res: Response, next: NextFunction) => void;
73
+ validateArray: (req: Request, _res: Response, next: NextFunction) => void;
74
+ validateOne: (req: Request, _res: Response, next: NextFunction) => void;
73
75
  check: (req: Request, _res: Response, next: NextFunction) => void;
74
76
  }
75
77
 
package/dist/antity.js CHANGED
@@ -233,38 +233,69 @@ function require(v, key, type) {
233
233
  return isNil(v) ? { statusCode: 400, message: `${LOGS_PREFIX}Missing ${key} of type ${type}` } : null;
234
234
  }
235
235
 
236
+ function applyNormalization(record, properties) {
237
+ for (const { key, type, sanitize: sanitize$1, normalize, sanitizer, normalizer, } of properties) {
238
+ let v = record[key];
239
+ if (v) {
240
+ if (sanitize$1) {
241
+ log.debug(`sanitize ${key}: ${type} = ${v}`);
242
+ v = sanitize(v, sanitizer);
243
+ }
244
+ if (normalize && isFunction(normalizer)) {
245
+ log.debug(`normalize ${key}: ${type} = ${v}`);
246
+ v = normalizer(v);
247
+ }
248
+ record[key] = v;
249
+ }
250
+ }
251
+ }
252
+
253
+ function applyValidation(record, properties, method) {
254
+ for (const { key, type, min, max, required, typeCheck, methods, validate, validator } of properties) {
255
+ const v = record[key];
256
+ if (isIn(methods, method)) {
257
+ if (required) {
258
+ const rq = require(v, key, type);
259
+ if (rq)
260
+ return rq;
261
+ }
262
+ if (v && validate) {
263
+ const ct = control(v, key, type, min, max, typeCheck, validator);
264
+ if (ct)
265
+ return ct;
266
+ }
267
+ }
268
+ }
269
+ return null;
270
+ }
271
+
236
272
  class Entity {
237
273
  constructor(name, properties) {
238
- this.normalize = (req, _res, next) => {
274
+ this.normalizeArray = (req, _res, next) => {
239
275
  var _a;
276
+ log.debug(`normalizeArray ${this.name}`);
240
277
  const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
241
- log.debug(`normalize ${this.name}`);
242
- if (!isArray(rows, "!0"))
278
+ if (!isArray(rows, ">", 0))
243
279
  return next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no rows found in request body` });
244
280
  for (const r of rows) {
245
- for (const { key, type, sanitize: sanitize$1, normalize, sanitizer, normalizer, } of this._properties) {
246
- let v = r[key];
247
- if (v) {
248
- if (sanitize$1) {
249
- log.debug(`sanitize ${key}: ${type} = ${v}`);
250
- v = sanitize(v, sanitizer);
251
- }
252
- if (normalize && isFunction(normalizer)) {
253
- log.debug(`normalize ${key}: ${type} = ${v}`);
254
- v = normalizer(v);
255
- }
256
- r[key] = v;
257
- }
258
- }
281
+ applyNormalization(r, this._properties);
259
282
  }
260
283
  next();
261
284
  };
262
- this.validate = (req, _res, next) => {
285
+ this.normalizeOne = (req, _res, next) => {
286
+ log.debug(`normalizeOne ${this.name}`);
287
+ const record = req.body;
288
+ if (!isObject(record, true))
289
+ return next({ statusCode: 400, message: `${LOGS_PREFIX}Normalize: no data found in request body` });
290
+ applyNormalization(record, this._properties);
291
+ next();
292
+ };
293
+ this.validateArray = (req, _res, next) => {
263
294
  var _a;
295
+ log.debug(`validateArray ${this.name}`);
264
296
  const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
265
297
  const method = req.method;
266
- log.debug(`validate ${this.name}`);
267
- if (!isArray(rows, "!0"))
298
+ if (!isArray(rows, ">", 0))
268
299
  return next({ statusCode: 400, message: `${LOGS_PREFIX}Validate: no rows found in request body` });
269
300
  if (!isIn(METHODS, method))
270
301
  return next({
@@ -272,24 +303,28 @@ class Entity {
272
303
  message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}`
273
304
  });
274
305
  for (const r of rows) {
275
- for (const { key, type, min, max, required, typeCheck, methods, validate, validator } of this._properties) {
276
- const v = r[key];
277
- if (isIn(methods, method)) {
278
- if (required) {
279
- const rq = require(v, key, type);
280
- if (rq)
281
- return next(rq);
282
- }
283
- if (v && validate) {
284
- const ct = control(v, key, type, min, max, typeCheck, validator);
285
- if (ct)
286
- return next(ct);
287
- }
288
- }
289
- }
306
+ const error = applyValidation(r, this._properties, method);
307
+ if (error)
308
+ return next(error);
290
309
  }
291
310
  next();
292
311
  };
312
+ this.validateOne = (req, _res, next) => {
313
+ log.debug(`validateOne ${this.name}`);
314
+ const record = req.body;
315
+ const method = req.method;
316
+ if (!isObject(record, true))
317
+ return next({ statusCode: 400, message: `${LOGS_PREFIX}Validate: no data found in request body` });
318
+ if (!isIn(METHODS, method))
319
+ return next({
320
+ statusCode: 400,
321
+ message: `${LOGS_PREFIX}Invalid REST method. Received: ${method}. Must be one of: ${METHODS.toString()}`
322
+ });
323
+ const error = applyValidation(record, this._properties, method);
324
+ if (error)
325
+ return next(error);
326
+ next();
327
+ };
293
328
  this.check = (req, _res, next) => {
294
329
  var _a;
295
330
  const rows = (_a = req.body) === null || _a === void 0 ? void 0 : _a.rows;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dwtechs/antity",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Open source library for easy entity management",
5
5
  "keywords": [
6
6
  "entities"