valgen 5.2.1 → 5.3.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/CHANGELOG.md CHANGED
@@ -1,3 +1,18 @@
1
+ # v5.3.0
2
+ [2024-05-06]
3
+
4
+ ### Changes
5
+
6
+ * Added validation generation option to enable coercing by default. ([`5b012ee`](https://github.com/panates/valgen/commit/5b012ee21b89e601ebb7d9f624d93042862da8ca))
7
+
8
+ # v5.2.2
9
+ [2024-03-29]
10
+
11
+ ### Changes
12
+
13
+ * Updated dependencies ([`9d9af6f`](https://github.com/panates/valgen/commit/9d9af6fadeece926a8ec1bc93d14ffc7ace625d0))
14
+ * Updated dependencies ([`636ce75`](https://github.com/panates/valgen/commit/636ce759e83e765661e7c5c8730c6b824076d344))
15
+
1
16
  # v5.2.1
2
17
  [2024-03-27]
3
18
 
@@ -44,7 +44,11 @@ class Context {
44
44
  return x;
45
45
  const k = m[1];
46
46
  let v = issue[k];
47
- if (!v && m[1] === 'label' && (this.location || this.property))
47
+ if (k === 'value') {
48
+ const s = String(issue.value);
49
+ return s.length < 30 ? s : s.substring(0, 30) + '..';
50
+ }
51
+ if (!v && k === 'label' && (this.location || this.property))
48
52
  v = '`' + (this.location || this.property) + '`';
49
53
  if (v != null)
50
54
  return v;
package/cjs/index.js CHANGED
@@ -26,7 +26,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
26
26
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
27
27
  };
28
28
  Object.defineProperty(exports, "__esModule", { value: true });
29
- exports.isHexadecimal = exports.isDecimal = exports.isAscii = exports.isAlphanumeric = exports.isAlpha = exports.isUppercase = exports.isLowercase = exports.isJWT = exports.isHexColor = exports.isETHAddress = exports.isBtcAddress = exports.isISSN = exports.isFQDN = exports.isEAN = exports.isIBAN = exports.isCreditCard = exports.isBIC = exports.isBase64 = exports.isURL = exports.isPort = exports.isMACAddress = exports.isIPRange = exports.isIP = exports.isMobilePhone = exports.isEmail = exports.isUUID5 = exports.isUUID4 = exports.isUUID3 = exports.isUUID2 = exports.isUUID1 = exports.isUUID = exports.isString = exports.isObjectId = exports.isObject = exports.isNumber = exports.isUndefined = exports.isDefined = exports.isNullish = exports.isNull = exports.isInteger = exports.isNotEmpty = exports.isEmpty = exports.isDateString = exports.isDate = exports.isBoolean = exports.isBigint = exports.isArray = exports.isAny = exports.vg = void 0;
29
+ exports.toArray = exports.isHexadecimal = exports.isDecimal = exports.isAscii = exports.isAlphanumeric = exports.isAlpha = exports.isUppercase = exports.isLowercase = exports.isJWT = exports.isHexColor = exports.isETHAddress = exports.isBtcAddress = exports.isISSN = exports.isFQDN = exports.isEAN = exports.isIBAN = exports.isCreditCard = exports.isBIC = exports.isBase64 = exports.isURL = exports.isPort = exports.isMACAddress = exports.isIPRange = exports.isIP = exports.isMobilePhone = exports.isEmail = exports.isUUID5 = exports.isUUID4 = exports.isUUID3 = exports.isUUID2 = exports.isUUID1 = exports.isUUID = exports.isString = exports.isObjectId = exports.isObject = exports.isNumber = exports.isUndefined = exports.isDefined = exports.isNullish = exports.isNull = exports.isInteger = exports.isNotEmpty = exports.isEmpty = exports.isDateString = exports.isDate = exports.isBoolean = exports.isBigint = exports.isArray = exports.isAny = exports.vg = void 0;
30
+ exports.toString = exports.toNumber = exports.toInteger = exports.toDateString = exports.toDate = exports.toBoolean = void 0;
30
31
  const vg = __importStar(require("./rules/index.js"));
31
32
  exports.vg = vg;
32
33
  __exportStar(require("./constants.js"), exports);
@@ -127,3 +128,17 @@ const isDecimal = vg.isDecimal();
127
128
  exports.isDecimal = isDecimal;
128
129
  const isHexadecimal = vg.isHexadecimal();
129
130
  exports.isHexadecimal = isHexadecimal;
131
+ const toArray = vg.isArray(isAny, { coerce: true });
132
+ exports.toArray = toArray;
133
+ const toBoolean = vg.isBoolean({ coerce: true });
134
+ exports.toBoolean = toBoolean;
135
+ const toDate = vg.isDate({ coerce: true });
136
+ exports.toDate = toDate;
137
+ const toDateString = vg.isDateString({ coerce: true });
138
+ exports.toDateString = toDateString;
139
+ const toInteger = vg.isInteger({ coerce: true });
140
+ exports.toInteger = toInteger;
141
+ const toNumber = vg.isNumber({ coerce: true });
142
+ exports.toNumber = toNumber;
143
+ const toString = vg.isString({ coerce: true });
144
+ exports.toString = toString;
@@ -9,10 +9,11 @@ const index_js_1 = require("../core/index.js");
9
9
  */
10
10
  function isArray(itemValidator, options) {
11
11
  return (0, index_js_1.validator)('isArray', function (input, context, _this) {
12
- if (input != null && context.coerce && !Array.isArray(input))
12
+ const coerce = options?.coerce || context.coerce;
13
+ if (input != null && coerce && !Array.isArray(input))
13
14
  input = [input];
14
15
  if (!Array.isArray(input)) {
15
- context.fail(_this, `{{label}} must be an array`, input);
16
+ context.fail(_this, `"{{value}}" is not an array value`, input);
16
17
  return;
17
18
  }
18
19
  if (!itemValidator)
@@ -9,12 +9,14 @@ const index_js_1 = require("../core/index.js");
9
9
  */
10
10
  function isBigint(options) {
11
11
  return (0, index_js_1.validator)('isBigint', function (input, context, _this) {
12
+ const coerce = options?.coerce || context.coerce;
12
13
  if (typeof input === 'bigint')
13
14
  return input;
14
15
  if ((typeof input === 'number' && !isNaN(input)) ||
15
- (typeof input === 'string' && context.coerce))
16
+ (typeof input === 'string' && coerce))
16
17
  return BigInt(input);
17
- context.fail(_this, `{{label}} must be an integer number`, input);
18
+ const t = typeof input === 'string' ? 'String ' : '';
19
+ context.fail(_this, `${t}"{{value}}" is not a valid BigInt value`, input);
18
20
  }, options);
19
21
  }
20
22
  exports.isBigint = isBigint;
@@ -11,7 +11,8 @@ const FALSE_PATTERN = /^false|f|0|no|n$/i;
11
11
  */
12
12
  function isBoolean(options) {
13
13
  return (0, index_js_1.validator)('isBoolean', function (input, context, _this) {
14
- if (input != null && typeof input !== 'boolean' && context.coerce) {
14
+ const coerce = options?.coerce || context.coerce;
15
+ if (input != null && typeof input !== 'boolean' && coerce) {
15
16
  if (typeof input === 'string') {
16
17
  if (TRUE_PATTERN.test(input))
17
18
  return true;
@@ -24,7 +25,8 @@ function isBoolean(options) {
24
25
  }
25
26
  if (typeof input === 'boolean')
26
27
  return input;
27
- context.fail(_this, `{{label}} must be a boolean`, input);
28
+ const t = typeof input === 'string' ? 'String ' : '';
29
+ context.fail(_this, `${t}"{{value}}" is not a valid boolean value`, input);
28
30
  }, options);
29
31
  }
30
32
  exports.isBoolean = isBoolean;
@@ -13,11 +13,12 @@ const DATE_PATTERN = /^(\d{4})(?:-(0[0-9]|1[0-2]))?(?:-([0-2][0-9]|3[0-1]))?(?:[
13
13
  function isDate(options) {
14
14
  const precision = options?.precision;
15
15
  return (0, index_js_1.validator)('isDate', function (input, context, _this) {
16
+ const coerce = options?.coerce || context.coerce;
16
17
  let d;
17
18
  if (input instanceof Date)
18
19
  d = input;
19
- else if (input != null && context.coerce) {
20
- if (typeof input === 'string' && context.coerce) {
20
+ else if (input != null && coerce) {
21
+ if (typeof input === 'string' && coerce) {
21
22
  d = (0, date_fns_1.parseISO)(input);
22
23
  }
23
24
  else if (typeof input === 'number')
@@ -36,7 +37,7 @@ function isDate(options) {
36
37
  d.setHours(0, 0, 0, 0);
37
38
  return d;
38
39
  }
39
- context.fail(_this, `{{label}} must be a Date instance or a date string`, input);
40
+ context.fail(_this, `"{{value}}" is not a valid date value`, input, { ...options });
40
41
  }, options);
41
42
  }
42
43
  exports.isDate = isDate;
@@ -49,6 +50,7 @@ function isDateString(options) {
49
50
  const precision = options?.precision;
50
51
  const trim = options?.trim;
51
52
  return (0, index_js_1.validator)('isDateString', function (input, context, _this) {
53
+ const coerce = options?.coerce || context.coerce;
52
54
  if (typeof input === 'string') {
53
55
  const m = DATE_PATTERN.exec(input);
54
56
  if (m) {
@@ -59,7 +61,7 @@ function isDateString(options) {
59
61
  (precision === 'month' && m[2]) ||
60
62
  (precision === 'date' && m[2] && m[3]) ||
61
63
  (precision === 'time' && m[2] && m[3] && m[4])) {
62
- if (!context.coerce)
64
+ if (!coerce)
63
65
  return input;
64
66
  let s = m[1];
65
67
  if (m[2])
@@ -87,7 +89,7 @@ function isDateString(options) {
87
89
  ? (0, date_fns_1.formatISO)(input, { representation: 'date' })
88
90
  : (0, date_fns_1.formatISO)(input).substring(0, 19);
89
91
  }
90
- context.fail(_this, `{{label}} is not a valid date string`, input, { ...options });
92
+ context.fail(_this, `"{{value}}" is not a valid date string`, input, { ...options });
91
93
  }, options);
92
94
  }
93
95
  exports.isDateString = isDateString;
@@ -13,24 +13,29 @@ function isEmpty(options) {
13
13
  if (typeof input === 'string') {
14
14
  if (!input)
15
15
  return input;
16
+ context.fail(_this, `Is not an empty string`, input);
16
17
  }
17
18
  else if (Array.isArray(input)) {
18
19
  if (!input.length)
19
20
  return input;
21
+ context.fail(_this, `Is not an empty array`, input);
20
22
  }
21
23
  else if (input instanceof Set) {
22
24
  if (!input.size)
23
25
  return input;
26
+ context.fail(_this, `Is not an empty Set`, input);
24
27
  }
25
28
  else if (input instanceof Map) {
26
29
  if (!input.size)
27
30
  return input;
31
+ context.fail(_this, `Is not an empty Map`, input);
28
32
  }
29
33
  else if (typeof input === 'object') {
30
34
  if (!Object.keys(input).length)
31
35
  return input;
36
+ context.fail(_this, `Is not an empty Object`, input);
32
37
  }
33
- context.fail(_this, `{{label}} must be empty`, input);
38
+ context.fail(_this, `Is not empty`, input);
34
39
  }, options);
35
40
  }
36
41
  exports.isEmpty = isEmpty;
@@ -44,25 +49,30 @@ function isNotEmpty(options) {
44
49
  if (typeof input === 'string') {
45
50
  if (input)
46
51
  return input;
52
+ context.fail(_this, `Value is an empty string`, input);
47
53
  }
48
54
  else if (Array.isArray(input)) {
49
55
  if (input.length)
50
56
  return input;
57
+ context.fail(_this, `Value is an empty array`, input);
51
58
  }
52
59
  else if (input instanceof Set) {
53
60
  if (input.size)
54
61
  return input;
62
+ context.fail(_this, `Value is an empty Set`, input);
55
63
  }
56
64
  else if (input instanceof Map) {
57
65
  if (input.size)
58
66
  return input;
67
+ context.fail(_this, `Value is an empty Map`, input);
59
68
  }
60
69
  else if (typeof input === 'object') {
61
70
  if (Object.keys(input).length)
62
71
  return input;
72
+ context.fail(_this, `Value is an empty Object`, input);
63
73
  }
64
74
  }
65
- context.fail(_this, `{{label}} mustn't be empty`, input);
75
+ context.fail(_this, `Value is empty`, input);
66
76
  }, options);
67
77
  }
68
78
  exports.isNotEmpty = isNotEmpty;
@@ -9,7 +9,8 @@ const index_js_1 = require("../core/index.js");
9
9
  */
10
10
  function isInteger(options) {
11
11
  return (0, index_js_1.validator)('isInteger', function (input, context, _this) {
12
- if (input != null && typeof input !== 'number' && context.coerce) {
12
+ const coerce = options?.coerce || context.coerce;
13
+ if (input != null && typeof input !== 'number' && coerce) {
13
14
  if (typeof input === 'string')
14
15
  input = parseFloat(input);
15
16
  if (typeof input === 'bigint') {
@@ -20,7 +21,9 @@ function isInteger(options) {
20
21
  }
21
22
  if (typeof input === 'number' && !isNaN(input) && Number.isInteger(input))
22
23
  return input;
23
- context.fail(_this, `{{label}} must be an integer number`, input);
24
+ const t = typeof input === 'bigint' ? 'BigInt ' :
25
+ (typeof input === 'string' ? 'String ' : '');
26
+ context.fail(_this, `${t}"{{value}}" is not a valid integer value`, input);
24
27
  }, options);
25
28
  }
26
29
  exports.isInteger = isInteger;
@@ -10,9 +10,10 @@ function isNull(options) {
10
10
  return (0, index_js_1.validator)('isNull', function (input, context, _this) {
11
11
  if (input === null)
12
12
  return input;
13
- if (context.coerce)
13
+ const coerce = options?.coerce || context.coerce;
14
+ if (coerce)
14
15
  return null;
15
- context.fail(_this, `{{label}} must be null`, input);
16
+ context.fail(_this, `"{{value}}" is not null`, input);
16
17
  }, options);
17
18
  }
18
19
  exports.isNull = isNull;
@@ -24,9 +25,10 @@ function isNullish(options) {
24
25
  return (0, index_js_1.validator)('isNullish', function (input, context, _this) {
25
26
  if (input == null)
26
27
  return input;
27
- if (context.coerce)
28
+ const coerce = options?.coerce || context.coerce;
29
+ if (coerce)
28
30
  return null;
29
- context.fail(_this, `{{label}} must be null or undefined`, input);
31
+ context.fail(_this, `"{{value}}" is not nullish`, input);
30
32
  }, options);
31
33
  }
32
34
  exports.isNullish = isNullish;
@@ -38,7 +40,7 @@ function isDefined(options) {
38
40
  return (0, index_js_1.validator)('is-defined', function (input, context, _this) {
39
41
  if (input !== undefined)
40
42
  return input;
41
- context.fail(_this, `{{label}} must be defined`, input);
43
+ context.fail(_this, `Is not defined`, input);
42
44
  }, options);
43
45
  }
44
46
  exports.isDefined = isDefined;
@@ -48,7 +50,7 @@ exports.isDefined = isDefined;
48
50
  */
49
51
  function isUndefined(options) {
50
52
  return (0, index_js_1.validator)('isUndefined', function (input, context, _this) {
51
- if (context.coerce)
53
+ if (options?.coerce || context.coerce)
52
54
  return undefined;
53
55
  if (input === undefined)
54
56
  return;
@@ -9,18 +9,21 @@ const index_js_1 = require("../core/index.js");
9
9
  */
10
10
  function isNumber(options) {
11
11
  return (0, index_js_1.validator)('isNumber', function (input, context, _this) {
12
- if (input != null && typeof input !== 'number' && context.coerce) {
12
+ const coerce = options?.coerce || context.coerce;
13
+ if (input != null && typeof input !== 'number' && coerce) {
13
14
  if (typeof input === 'string')
14
15
  input = parseFloat(input);
15
16
  if (typeof input === 'bigint') {
16
17
  const v = Number(input);
17
18
  if (input === BigInt(v))
18
- input = v;
19
+ return v;
19
20
  }
20
21
  }
21
22
  if (typeof input === 'number' && !isNaN(input))
22
23
  return input;
23
- context.fail(_this, `{{label}} must be a number`, input);
24
+ const t = typeof input === 'bigint' ? 'BigInt ' :
25
+ (typeof input === 'string' ? 'String ' : '');
26
+ context.fail(_this, `${t}"{{value}}" is not a valid number value`, input);
24
27
  }, options);
25
28
  }
26
29
  exports.isNumber = isNumber;
@@ -18,7 +18,7 @@ function isObjectId(options) {
18
18
  typeof input.toHexString === 'function' &&
19
19
  _isObjectIdValue(input.toHexString()))))
20
20
  return input;
21
- context.fail(_this, `{{label}} must be an ObjectId`, input);
21
+ context.fail(_this, `"{{value}}" is not a valid ObjectId`, input);
22
22
  }, options);
23
23
  }
24
24
  exports.isObjectId = isObjectId;
@@ -37,7 +37,8 @@ function isObject(schema, options) {
37
37
  const _rule = (0, index_js_1.validator)('isObject', function (input, context, _this) {
38
38
  if (ctor && ctor[constants_js_1.preValidation])
39
39
  input = ctor[constants_js_1.preValidation](input, context, _this);
40
- if (typeof input === 'string' && context.coerce)
40
+ const coerce = options?.coerce || context.coerce;
41
+ if (typeof input === 'string' && coerce)
41
42
  input = JSON.parse(input);
42
43
  if (!(input && typeof input === 'object')) {
43
44
  context.fail(_this, `{{label}} must be an object`, input);
@@ -9,7 +9,8 @@ const index_js_1 = require("../core/index.js");
9
9
  */
10
10
  function isString(options) {
11
11
  return (0, index_js_1.validator)('isString', function (input, context, _this) {
12
- if (input != null && typeof input !== 'string' && context.coerce) {
12
+ const coerce = options?.coerce || context.coerce;
13
+ if (input != null && typeof input !== 'string' && coerce) {
13
14
  if (typeof input === 'object') {
14
15
  if (typeof input.toJSON === 'function')
15
16
  input = input.toJSON();
@@ -4,10 +4,11 @@ exports.isTuple = void 0;
4
4
  const index_js_1 = require("../core/index.js");
5
5
  function isTuple(items, options) {
6
6
  return (0, index_js_1.validator)('isTuple', function (input, context, _this) {
7
- if (input != null && context.coerce && !Array.isArray(input))
7
+ const coerce = options?.coerce || context.coerce;
8
+ if (input != null && coerce && !Array.isArray(input))
8
9
  input = [input];
9
10
  if (!Array.isArray(input)) {
10
- context.fail(_this, `{{label}} must be a tuple`, input);
11
+ context.fail(_this, `"{{value}}" is not a valid tuple`, input);
11
12
  return;
12
13
  }
13
14
  const location = context.location || '';
@@ -83,7 +83,7 @@ function range(minValue, maxValue, options) {
83
83
  if (typeof minValue === 'string' && typeof maxValue === 'string' &&
84
84
  typeof input === 'string' && input >= minValue && input <= maxValue)
85
85
  return input;
86
- context.fail(_this, `{{label}} must be between ${minValue} and ${maxValue}`, input);
86
+ context.fail(_this, `Value must be between ${minValue} and ${maxValue}`, input);
87
87
  }, options);
88
88
  }
89
89
  exports.range = range;
@@ -30,7 +30,7 @@ function union(codecs) {
30
30
  delete context.fail;
31
31
  if (passed)
32
32
  return v;
33
- context.fail(_this, `{{location}} didn't match any of required format`, input);
33
+ context.fail(_this, `Value didn't match any on union rules`, input);
34
34
  });
35
35
  }
36
36
  exports.union = union;
@@ -41,7 +41,11 @@ export class Context {
41
41
  return x;
42
42
  const k = m[1];
43
43
  let v = issue[k];
44
- if (!v && m[1] === 'label' && (this.location || this.property))
44
+ if (k === 'value') {
45
+ const s = String(issue.value);
46
+ return s.length < 30 ? s : s.substring(0, 30) + '..';
47
+ }
48
+ if (!v && k === 'label' && (this.location || this.property))
45
49
  v = '`' + (this.location || this.property) + '`';
46
50
  if (v != null)
47
51
  return v;
package/esm/index.js CHANGED
@@ -49,4 +49,11 @@ const isAlphanumeric = vg.isAlphanumeric();
49
49
  const isAscii = vg.isAscii();
50
50
  const isDecimal = vg.isDecimal();
51
51
  const isHexadecimal = vg.isHexadecimal();
52
- export { vg, isAny, isArray, isBigint, isBoolean, isDate, isDateString, isEmpty, isNotEmpty, isInteger, isNull, isNullish, isDefined, isUndefined, isNumber, isObject, isObjectId, isString, isUUID, isUUID1, isUUID2, isUUID3, isUUID4, isUUID5, isEmail, isMobilePhone, isIP, isIPRange, isMACAddress, isPort, isURL, isBase64, isBIC, isCreditCard, isIBAN, isEAN, isFQDN, isISSN, isBtcAddress, isETHAddress, isHexColor, isJWT, isLowercase, isUppercase, isAlpha, isAlphanumeric, isAscii, isDecimal, isHexadecimal };
52
+ const toArray = vg.isArray(isAny, { coerce: true });
53
+ const toBoolean = vg.isBoolean({ coerce: true });
54
+ const toDate = vg.isDate({ coerce: true });
55
+ const toDateString = vg.isDateString({ coerce: true });
56
+ const toInteger = vg.isInteger({ coerce: true });
57
+ const toNumber = vg.isNumber({ coerce: true });
58
+ const toString = vg.isString({ coerce: true });
59
+ export { vg, isAny, isArray, isBigint, isBoolean, isDate, isDateString, isEmpty, isNotEmpty, isInteger, isNull, isNullish, isDefined, isUndefined, isNumber, isObject, isObjectId, isString, isUUID, isUUID1, isUUID2, isUUID3, isUUID4, isUUID5, isEmail, isMobilePhone, isIP, isIPRange, isMACAddress, isPort, isURL, isBase64, isBIC, isCreditCard, isIBAN, isEAN, isFQDN, isISSN, isBtcAddress, isETHAddress, isHexColor, isJWT, isLowercase, isUppercase, isAlpha, isAlphanumeric, isAscii, isDecimal, isHexadecimal, toArray, toBoolean, toDate, toDateString, toInteger, toNumber, toString };
@@ -6,10 +6,11 @@ import { validator, } from '../core/index.js';
6
6
  */
7
7
  export function isArray(itemValidator, options) {
8
8
  return validator('isArray', function (input, context, _this) {
9
- if (input != null && context.coerce && !Array.isArray(input))
9
+ const coerce = options?.coerce || context.coerce;
10
+ if (input != null && coerce && !Array.isArray(input))
10
11
  input = [input];
11
12
  if (!Array.isArray(input)) {
12
- context.fail(_this, `{{label}} must be an array`, input);
13
+ context.fail(_this, `"{{value}}" is not an array value`, input);
13
14
  return;
14
15
  }
15
16
  if (!itemValidator)
@@ -6,11 +6,13 @@ import { validator } from '../core/index.js';
6
6
  */
7
7
  export function isBigint(options) {
8
8
  return validator('isBigint', function (input, context, _this) {
9
+ const coerce = options?.coerce || context.coerce;
9
10
  if (typeof input === 'bigint')
10
11
  return input;
11
12
  if ((typeof input === 'number' && !isNaN(input)) ||
12
- (typeof input === 'string' && context.coerce))
13
+ (typeof input === 'string' && coerce))
13
14
  return BigInt(input);
14
- context.fail(_this, `{{label}} must be an integer number`, input);
15
+ const t = typeof input === 'string' ? 'String ' : '';
16
+ context.fail(_this, `${t}"{{value}}" is not a valid BigInt value`, input);
15
17
  }, options);
16
18
  }
@@ -8,7 +8,8 @@ const FALSE_PATTERN = /^false|f|0|no|n$/i;
8
8
  */
9
9
  export function isBoolean(options) {
10
10
  return validator('isBoolean', function (input, context, _this) {
11
- if (input != null && typeof input !== 'boolean' && context.coerce) {
11
+ const coerce = options?.coerce || context.coerce;
12
+ if (input != null && typeof input !== 'boolean' && coerce) {
12
13
  if (typeof input === 'string') {
13
14
  if (TRUE_PATTERN.test(input))
14
15
  return true;
@@ -21,6 +22,7 @@ export function isBoolean(options) {
21
22
  }
22
23
  if (typeof input === 'boolean')
23
24
  return input;
24
- context.fail(_this, `{{label}} must be a boolean`, input);
25
+ const t = typeof input === 'string' ? 'String ' : '';
26
+ context.fail(_this, `${t}"{{value}}" is not a valid boolean value`, input);
25
27
  }, options);
26
28
  }
@@ -10,11 +10,12 @@ const DATE_PATTERN = /^(\d{4})(?:-(0[0-9]|1[0-2]))?(?:-([0-2][0-9]|3[0-1]))?(?:[
10
10
  export function isDate(options) {
11
11
  const precision = options?.precision;
12
12
  return validator('isDate', function (input, context, _this) {
13
+ const coerce = options?.coerce || context.coerce;
13
14
  let d;
14
15
  if (input instanceof Date)
15
16
  d = input;
16
- else if (input != null && context.coerce) {
17
- if (typeof input === 'string' && context.coerce) {
17
+ else if (input != null && coerce) {
18
+ if (typeof input === 'string' && coerce) {
18
19
  d = parseISO(input);
19
20
  }
20
21
  else if (typeof input === 'number')
@@ -33,7 +34,7 @@ export function isDate(options) {
33
34
  d.setHours(0, 0, 0, 0);
34
35
  return d;
35
36
  }
36
- context.fail(_this, `{{label}} must be a Date instance or a date string`, input);
37
+ context.fail(_this, `"{{value}}" is not a valid date value`, input, { ...options });
37
38
  }, options);
38
39
  }
39
40
  /**
@@ -45,6 +46,7 @@ export function isDateString(options) {
45
46
  const precision = options?.precision;
46
47
  const trim = options?.trim;
47
48
  return validator('isDateString', function (input, context, _this) {
49
+ const coerce = options?.coerce || context.coerce;
48
50
  if (typeof input === 'string') {
49
51
  const m = DATE_PATTERN.exec(input);
50
52
  if (m) {
@@ -55,7 +57,7 @@ export function isDateString(options) {
55
57
  (precision === 'month' && m[2]) ||
56
58
  (precision === 'date' && m[2] && m[3]) ||
57
59
  (precision === 'time' && m[2] && m[3] && m[4])) {
58
- if (!context.coerce)
60
+ if (!coerce)
59
61
  return input;
60
62
  let s = m[1];
61
63
  if (m[2])
@@ -83,6 +85,6 @@ export function isDateString(options) {
83
85
  ? formatISO(input, { representation: 'date' })
84
86
  : formatISO(input).substring(0, 19);
85
87
  }
86
- context.fail(_this, `{{label}} is not a valid date string`, input, { ...options });
88
+ context.fail(_this, `"{{value}}" is not a valid date string`, input, { ...options });
87
89
  }, options);
88
90
  }
@@ -10,24 +10,29 @@ export function isEmpty(options) {
10
10
  if (typeof input === 'string') {
11
11
  if (!input)
12
12
  return input;
13
+ context.fail(_this, `Is not an empty string`, input);
13
14
  }
14
15
  else if (Array.isArray(input)) {
15
16
  if (!input.length)
16
17
  return input;
18
+ context.fail(_this, `Is not an empty array`, input);
17
19
  }
18
20
  else if (input instanceof Set) {
19
21
  if (!input.size)
20
22
  return input;
23
+ context.fail(_this, `Is not an empty Set`, input);
21
24
  }
22
25
  else if (input instanceof Map) {
23
26
  if (!input.size)
24
27
  return input;
28
+ context.fail(_this, `Is not an empty Map`, input);
25
29
  }
26
30
  else if (typeof input === 'object') {
27
31
  if (!Object.keys(input).length)
28
32
  return input;
33
+ context.fail(_this, `Is not an empty Object`, input);
29
34
  }
30
- context.fail(_this, `{{label}} must be empty`, input);
35
+ context.fail(_this, `Is not empty`, input);
31
36
  }, options);
32
37
  }
33
38
  /**
@@ -40,24 +45,29 @@ export function isNotEmpty(options) {
40
45
  if (typeof input === 'string') {
41
46
  if (input)
42
47
  return input;
48
+ context.fail(_this, `Value is an empty string`, input);
43
49
  }
44
50
  else if (Array.isArray(input)) {
45
51
  if (input.length)
46
52
  return input;
53
+ context.fail(_this, `Value is an empty array`, input);
47
54
  }
48
55
  else if (input instanceof Set) {
49
56
  if (input.size)
50
57
  return input;
58
+ context.fail(_this, `Value is an empty Set`, input);
51
59
  }
52
60
  else if (input instanceof Map) {
53
61
  if (input.size)
54
62
  return input;
63
+ context.fail(_this, `Value is an empty Map`, input);
55
64
  }
56
65
  else if (typeof input === 'object') {
57
66
  if (Object.keys(input).length)
58
67
  return input;
68
+ context.fail(_this, `Value is an empty Object`, input);
59
69
  }
60
70
  }
61
- context.fail(_this, `{{label}} mustn't be empty`, input);
71
+ context.fail(_this, `Value is empty`, input);
62
72
  }, options);
63
73
  }
@@ -6,7 +6,8 @@ import { validator } from '../core/index.js';
6
6
  */
7
7
  export function isInteger(options) {
8
8
  return validator('isInteger', function (input, context, _this) {
9
- if (input != null && typeof input !== 'number' && context.coerce) {
9
+ const coerce = options?.coerce || context.coerce;
10
+ if (input != null && typeof input !== 'number' && coerce) {
10
11
  if (typeof input === 'string')
11
12
  input = parseFloat(input);
12
13
  if (typeof input === 'bigint') {
@@ -17,6 +18,8 @@ export function isInteger(options) {
17
18
  }
18
19
  if (typeof input === 'number' && !isNaN(input) && Number.isInteger(input))
19
20
  return input;
20
- context.fail(_this, `{{label}} must be an integer number`, input);
21
+ const t = typeof input === 'bigint' ? 'BigInt ' :
22
+ (typeof input === 'string' ? 'String ' : '');
23
+ context.fail(_this, `${t}"{{value}}" is not a valid integer value`, input);
21
24
  }, options);
22
25
  }
@@ -7,9 +7,10 @@ export function isNull(options) {
7
7
  return validator('isNull', function (input, context, _this) {
8
8
  if (input === null)
9
9
  return input;
10
- if (context.coerce)
10
+ const coerce = options?.coerce || context.coerce;
11
+ if (coerce)
11
12
  return null;
12
- context.fail(_this, `{{label}} must be null`, input);
13
+ context.fail(_this, `"{{value}}" is not null`, input);
13
14
  }, options);
14
15
  }
15
16
  /**
@@ -20,9 +21,10 @@ export function isNullish(options) {
20
21
  return validator('isNullish', function (input, context, _this) {
21
22
  if (input == null)
22
23
  return input;
23
- if (context.coerce)
24
+ const coerce = options?.coerce || context.coerce;
25
+ if (coerce)
24
26
  return null;
25
- context.fail(_this, `{{label}} must be null or undefined`, input);
27
+ context.fail(_this, `"{{value}}" is not nullish`, input);
26
28
  }, options);
27
29
  }
28
30
  /**
@@ -33,7 +35,7 @@ export function isDefined(options) {
33
35
  return validator('is-defined', function (input, context, _this) {
34
36
  if (input !== undefined)
35
37
  return input;
36
- context.fail(_this, `{{label}} must be defined`, input);
38
+ context.fail(_this, `Is not defined`, input);
37
39
  }, options);
38
40
  }
39
41
  /**
@@ -42,7 +44,7 @@ export function isDefined(options) {
42
44
  */
43
45
  export function isUndefined(options) {
44
46
  return validator('isUndefined', function (input, context, _this) {
45
- if (context.coerce)
47
+ if (options?.coerce || context.coerce)
46
48
  return undefined;
47
49
  if (input === undefined)
48
50
  return;
@@ -6,17 +6,20 @@ import { validator } from '../core/index.js';
6
6
  */
7
7
  export function isNumber(options) {
8
8
  return validator('isNumber', function (input, context, _this) {
9
- if (input != null && typeof input !== 'number' && context.coerce) {
9
+ const coerce = options?.coerce || context.coerce;
10
+ if (input != null && typeof input !== 'number' && coerce) {
10
11
  if (typeof input === 'string')
11
12
  input = parseFloat(input);
12
13
  if (typeof input === 'bigint') {
13
14
  const v = Number(input);
14
15
  if (input === BigInt(v))
15
- input = v;
16
+ return v;
16
17
  }
17
18
  }
18
19
  if (typeof input === 'number' && !isNaN(input))
19
20
  return input;
20
- context.fail(_this, `{{label}} must be a number`, input);
21
+ const t = typeof input === 'bigint' ? 'BigInt ' :
22
+ (typeof input === 'string' ? 'String ' : '');
23
+ context.fail(_this, `${t}"{{value}}" is not a valid number value`, input);
21
24
  }, options);
22
25
  }
@@ -12,7 +12,7 @@ export function isObjectId(options) {
12
12
  typeof input.toHexString === 'function' &&
13
13
  _isObjectIdValue(input.toHexString()))))
14
14
  return input;
15
- context.fail(_this, `{{label}} must be an ObjectId`, input);
15
+ context.fail(_this, `"{{value}}" is not a valid ObjectId`, input);
16
16
  }, options);
17
17
  }
18
18
  function _isObjectIdValue(input) {
@@ -34,7 +34,8 @@ export function isObject(schema, options) {
34
34
  const _rule = validator('isObject', function (input, context, _this) {
35
35
  if (ctor && ctor[preValidation])
36
36
  input = ctor[preValidation](input, context, _this);
37
- if (typeof input === 'string' && context.coerce)
37
+ const coerce = options?.coerce || context.coerce;
38
+ if (typeof input === 'string' && coerce)
38
39
  input = JSON.parse(input);
39
40
  if (!(input && typeof input === 'object')) {
40
41
  context.fail(_this, `{{label}} must be an object`, input);
@@ -6,7 +6,8 @@ import { validator } from '../core/index.js';
6
6
  */
7
7
  export function isString(options) {
8
8
  return validator('isString', function (input, context, _this) {
9
- if (input != null && typeof input !== 'string' && context.coerce) {
9
+ const coerce = options?.coerce || context.coerce;
10
+ if (input != null && typeof input !== 'string' && coerce) {
10
11
  if (typeof input === 'object') {
11
12
  if (typeof input.toJSON === 'function')
12
13
  input = input.toJSON();
@@ -1,10 +1,11 @@
1
1
  import { validator } from '../core/index.js';
2
2
  export function isTuple(items, options) {
3
3
  return validator('isTuple', function (input, context, _this) {
4
- if (input != null && context.coerce && !Array.isArray(input))
4
+ const coerce = options?.coerce || context.coerce;
5
+ if (input != null && coerce && !Array.isArray(input))
5
6
  input = [input];
6
7
  if (!Array.isArray(input)) {
7
- context.fail(_this, `{{label}} must be a tuple`, input);
8
+ context.fail(_this, `"{{value}}" is not a valid tuple`, input);
8
9
  return;
9
10
  }
10
11
  const location = context.location || '';
@@ -76,6 +76,6 @@ export function range(minValue, maxValue, options) {
76
76
  if (typeof minValue === 'string' && typeof maxValue === 'string' &&
77
77
  typeof input === 'string' && input >= minValue && input <= maxValue)
78
78
  return input;
79
- context.fail(_this, `{{label}} must be between ${minValue} and ${maxValue}`, input);
79
+ context.fail(_this, `Value must be between ${minValue} and ${maxValue}`, input);
80
80
  }, options);
81
81
  }
@@ -27,6 +27,6 @@ export function union(codecs) {
27
27
  delete context.fail;
28
28
  if (passed)
29
29
  return v;
30
- context.fail(_this, `{{location}} didn't match any of required format`, input);
30
+ context.fail(_this, `Value didn't match any on union rules`, input);
31
31
  });
32
32
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "valgen",
3
3
  "description": "Fast runtime type validator, converter and io (encoding/decoding) library",
4
- "version": "5.2.1",
4
+ "version": "5.3.0",
5
5
  "author": "Panates",
6
6
  "contributors": [
7
7
  "Eray Hanoglu <e.hanoglu@panates.com>"
@@ -14,7 +14,7 @@
14
14
  "dependencies": {
15
15
  "@types/validator": "^13.11.9",
16
16
  "date-fns": "^3.6.0",
17
- "ts-gems": "^3.2.1",
17
+ "ts-gems": "^3.4.0",
18
18
  "validator": "^13.11.0"
19
19
  },
20
20
  "type": "module",
@@ -14,6 +14,7 @@ export interface ErrorIssue {
14
14
  export type OnFailFunction = (issue: ErrorIssue, context: Context, _super?: OnFailFunction) => string | Omit<ErrorIssue, 'id' | 'input'>;
15
15
  export interface ValidationOptions {
16
16
  onFail?: OnFailFunction;
17
+ coerce?: boolean;
17
18
  }
18
19
  export interface ExecutionOptions extends ValidationOptions {
19
20
  coerce?: boolean;
@@ -50,4 +50,11 @@ declare const isAlphanumeric: import("./core/validator.js").Validator<string, st
50
50
  declare const isAscii: import("./core/validator.js").Validator<string, string, import("./core/types.js").ExecutionOptions>;
51
51
  declare const isDecimal: import("./core/validator.js").Validator<string, string, import("./core/types.js").ExecutionOptions>;
52
52
  declare const isHexadecimal: import("./core/validator.js").Validator<string, string, import("./core/types.js").ExecutionOptions>;
53
- export { vg, isAny, isArray, isBigint, isBoolean, isDate, isDateString, isEmpty, isNotEmpty, isInteger, isNull, isNullish, isDefined, isUndefined, isNumber, isObject, isObjectId, isString, isUUID, isUUID1, isUUID2, isUUID3, isUUID4, isUUID5, isEmail, isMobilePhone, isIP, isIPRange, isMACAddress, isPort, isURL, isBase64, isBIC, isCreditCard, isIBAN, isEAN, isFQDN, isISSN, isBtcAddress, isETHAddress, isHexColor, isJWT, isLowercase, isUppercase, isAlpha, isAlphanumeric, isAscii, isDecimal, isHexadecimal };
53
+ declare const toArray: import("./core/validator.js").Validator<any[], any, import("./core/types.js").ExecutionOptions>;
54
+ declare const toBoolean: import("./core/validator.js").Validator<boolean | undefined, unknown, import("./core/types.js").ExecutionOptions>;
55
+ declare const toDate: import("./core/validator.js").Validator<Date, string | number | Date, import("./core/types.js").ExecutionOptions>;
56
+ declare const toDateString: import("./core/validator.js").Validator<string, string | number | Date, import("./core/types.js").ExecutionOptions>;
57
+ declare const toInteger: import("./core/validator.js").Validator<number, unknown, import("./core/types.js").ExecutionOptions>;
58
+ declare const toNumber: import("./core/validator.js").Validator<number, unknown, import("./core/types.js").ExecutionOptions>;
59
+ declare const toString: import("./core/validator.js").Validator<string, unknown, import("./core/types.js").ExecutionOptions>;
60
+ export { vg, isAny, isArray, isBigint, isBoolean, isDate, isDateString, isEmpty, isNotEmpty, isInteger, isNull, isNullish, isDefined, isUndefined, isNumber, isObject, isObjectId, isString, isUUID, isUUID1, isUUID2, isUUID3, isUUID4, isUUID5, isEmail, isMobilePhone, isIP, isIPRange, isMACAddress, isPort, isURL, isBase64, isBIC, isCreditCard, isIBAN, isEAN, isFQDN, isISSN, isBtcAddress, isETHAddress, isHexColor, isJWT, isLowercase, isUppercase, isAlpha, isAlphanumeric, isAscii, isDecimal, isHexadecimal, toArray, toBoolean, toDate, toDateString, toInteger, toNumber, toString };
@@ -3,9 +3,9 @@ import { Validator } from '../core/index.js';
3
3
  *
4
4
  * @validator pipe
5
5
  */
6
- export declare function pipe<T>(...rules: [...Validator[], Validator<T, any>]): Validator<T, any, import("../core/types.js").ExecutionOptions>;
6
+ export declare function pipe<T>(...rules: Validator[]): Validator<T>;
7
7
  /**
8
8
  * Test given value against to all codecs and returns original input
9
9
  * @validator allOf
10
10
  */
11
- export declare function allOf(...rules: Validator[]): Validator<any, any, import("../core/types.js").ExecutionOptions>;
11
+ export declare function allOf<T = any>(...rules: Validator[]): Validator<T>;