binhend 2.3.6 → 2.3.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "binhend",
3
- "version": "2.3.6",
3
+ "version": "2.3.8",
4
4
  "description": "",
5
5
  "main": "index.js",
6
6
  "author": "Nguyen Duc Binh",
@@ -1,7 +1,17 @@
1
1
 
2
- const HttpError = require('./HttpError');
2
+ function StatusCode(code = 500) {
3
+ /**
4
+ * Range of HTTP codes are from 100 to 599.
5
+ * HTTP code 500 is `Internal Server Error`.
6
+ */
7
+ return Number.isInteger(code) && code >= 100 && code <= 599 ? code : 500;
8
+ }
3
9
 
4
10
  module.exports = function (error, response, next) {
5
- if (!(error instanceof HttpError)) return next(error);
6
- response.status(error.httpCode || 500).json({ error: error.message || 'Internal Server Error' });
11
+ if (Object.prototype.hasOwnProperty.call(error, 'httpCode')) {
12
+ response.status(StatusCode(error.httpCode)).json({ error: error.message || 'Internal Server Error' });
13
+ }
14
+ else {
15
+ next(error);
16
+ }
7
17
  };
@@ -10,6 +10,17 @@ const types = require('@binhend/types');
10
10
  * @property {*=} default - The default value being used if null or undefined
11
11
  */
12
12
 
13
+ /**
14
+ * Type options used in validation functions.
15
+ *
16
+ * @param {object} input - Options for validation.
17
+ * @returns {Options}
18
+ * @throws {HttpError}
19
+ */
20
+ function Options(input = {}) {
21
+ return input;
22
+ }
23
+
13
24
  /**
14
25
  * Throw error by default for invalid input.
15
26
  * A `HttpError` is thrown for `router` sending response to client.
@@ -263,6 +274,44 @@ function Prop(key, object, validator, options) {
263
274
  });
264
275
  }
265
276
 
277
+ /**
278
+ * Return an object with all properties defined in the validator, using non-strict validation.
279
+ * Instead of throwing errors, invalid values are set to `null` by enforcing `{ default: null, required: false }` across all validations.
280
+ *
281
+ * @template V
282
+ * @param {((...args: any[]) => V)} [validator] - Validation function
283
+ * @returns {V} - An object with keys bypass requirement
284
+ * @throws {HttpError} - If validation fails
285
+ */
286
+ function DefaultObject(validator) {
287
+ OptionControl.default = null;
288
+ OptionControl.required = false;
289
+
290
+ try {
291
+ var value = validator();
292
+ return value;
293
+ }
294
+ catch (error) {
295
+ // TODO app log error for debug
296
+ throw new HttpError(HttpCodes.INTERNAL_SERVER_ERROR, `Type validation failed`);
297
+ }
298
+ finally {
299
+ delete OptionControl.default;
300
+ delete OptionControl.required;
301
+ }
302
+ }
303
+
304
+ /**
305
+ * Returns an empty object as the validator output without performing any validation.
306
+ *
307
+ * @template V
308
+ * @param {((...args: any[]) => V)} [validator] - Validation function
309
+ * @returns {V} - An empty object with no property
310
+ */
311
+ function EmptyObject(validator) {
312
+ return /** @type {V} */ ({});
313
+ }
314
+
266
315
  /**
267
316
  * Validate an input being a function
268
317
  *
@@ -330,7 +379,7 @@ function Enum(input, enumValues, options = {}) {
330
379
 
331
380
  return Validator(
332
381
  input, (input) => enumValues.includes(input),
333
- { ...options, message: options.message || `Value {${input}} is not defined in enum` }
382
+ { ...options, message: options?.message || `${options?.name || 'Value'} {${input}} is not defined in ${options?.type || 'Enum'}` }
334
383
  );
335
384
  }
336
385
 
@@ -396,10 +445,12 @@ function NotNullish(input, options = {}) {
396
445
  /**
397
446
  * Generic validator that accepts a validation function
398
447
  *
399
- * @param {*} input - Input value needs to be validated.
448
+ * @template T
449
+ *
450
+ * @param {T} input - Input value needs to be validated.
400
451
  * @param {Function} validate - Validation function that returns boolean
401
452
  * @param {Options} options - Additional options for validation.
402
- * @returns {*} - The validated input
453
+ * @returns {T} - The validated input
403
454
  * @throws {HttpError} - If validation fails
404
455
  */
405
456
  function Validator(input, validate, options = {}) {
@@ -407,12 +458,22 @@ function Validator(input, validate, options = {}) {
407
458
  return input;
408
459
  }
409
460
 
461
+ options = { ...options, ...OptionControl }; // prevent options being null
462
+
410
463
  // use default value (options.default - must also be valid) if has, when input is invalid
411
- if (options.hasOwnProperty('default') && validate(options.default)) {
412
- return options.default;
464
+ if (options.hasOwnProperty('default')) {
465
+ var defaultValue = options.default;
466
+
467
+ if (validate(defaultValue)) {
468
+ return defaultValue;
469
+ }
470
+
471
+ if (!options.required && types.isNullish(defaultValue)) {
472
+ return defaultValue;
473
+ }
413
474
  }
414
475
 
415
- // allow null or undefined by default, set `options.required=true` for not allowing
476
+ // accept `null` or `undefined` by default, set `options.required=true` for not accepting nullish values
416
477
  if (!options.required && types.isNullish(input)) {
417
478
  return input;
418
479
  }
@@ -430,6 +491,8 @@ function Validator(input, validate, options = {}) {
430
491
  }
431
492
  }
432
493
 
494
+ const OptionControl = {};
495
+
433
496
  module.exports = {
434
497
  String,
435
498
  Number,
@@ -440,6 +503,7 @@ module.exports = {
440
503
  PropIf, Prop,
441
504
  AssignIf, Assign,
442
505
  Value, Optional,
506
+ DefaultObject, EmptyObject,
443
507
  Function,
444
508
  AsyncFunction,
445
509
  Date,
@@ -449,5 +513,6 @@ module.exports = {
449
513
  NotNull,
450
514
  NotNullish,
451
515
  Validator,
452
- throwError
516
+ throwError,
517
+ Options
453
518
  };