@vpmedia/simplify 1.60.0 → 1.61.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,13 @@
1
+ ## [1.61.0] - 2026-01-14
2
+
3
+ ### 🚜 Refactor
4
+
5
+ - Improve validation error message
6
+
7
+ ### ⚙️ Miscellaneous Tasks
8
+
9
+ - Release
10
+ - *(release)* V1.61.0
1
11
  ## [1.60.0] - 2026-01-14
2
12
 
3
13
  ### 💼 Other
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vpmedia/simplify",
3
- "version": "1.60.0",
3
+ "version": "1.61.0",
4
4
  "description": "@vpmedia/simplify",
5
5
  "author": "Andras Csizmadia <andras@vpmedia.hu> (www.vpmedia.hu)",
6
6
  "license": "MIT",
@@ -1,9 +1,17 @@
1
- import { getTypeFromValue } from '../util/string.js';
1
+ import { getDisplayValue, getTypeFromValue } from '../util/string.js';
2
2
  import { isArrayOf, isEnum } from '../util/validate.js';
3
3
  import { TypeCheckError } from './TypeCheckError.js';
4
4
 
5
- const VALIDATOR_FALLBACK_NAME = '<anonymous>';
6
-
5
+ /**
6
+ * Get error message for validator exceptions.
7
+ * @param {string} validatorName - Validator name.
8
+ * @param {unknown} value - Input value.
9
+ */
10
+ const getErrorMessage = (validatorName, value) => {
11
+ const displayValue = getDisplayValue(value);
12
+ const displayType = getTypeFromValue(value);
13
+ throw new TypeCheckError(`Validation failed: ${validatorName || '<anonymous>'} - ${displayValue} (${displayType})`);
14
+ };
7
15
  /**
8
16
  * Type check a value using a validator.
9
17
  * @template T
@@ -14,9 +22,8 @@ const VALIDATOR_FALLBACK_NAME = '<anonymous>';
14
22
  */
15
23
  export const typeCheck = (value, validator) => {
16
24
  if (!validator(value)) {
17
- const validatorName = validator.name || VALIDATOR_FALLBACK_NAME;
18
- const displayValue = getTypeFromValue(value);
19
- throw new TypeCheckError(`Validation failed: ${validatorName} (${displayValue})`);
25
+ const errorMessage = getErrorMessage(validator.name, value);
26
+ throw new TypeCheckError(errorMessage);
20
27
  }
21
28
  return value;
22
29
  };
@@ -31,9 +38,8 @@ export const typeCheck = (value, validator) => {
31
38
  */
32
39
  export const typeCheckArray = (value, validator) => {
33
40
  if (!isArrayOf(value, validator)) {
34
- const validatorName = validator.name || VALIDATOR_FALLBACK_NAME;
35
- const displayValue = getTypeFromValue(value);
36
- throw new TypeCheckError(`Validation failed: ${validatorName} (${displayValue})`);
41
+ const errorMessage = getErrorMessage(validator.name, value);
42
+ throw new TypeCheckError(errorMessage);
37
43
  }
38
44
  return value;
39
45
  };
@@ -47,9 +53,8 @@ export const typeCheckArray = (value, validator) => {
47
53
  */
48
54
  export const typeCheckEnum = (value, choices) => {
49
55
  if (!isEnum(value, choices)) {
50
- const validatorName = 'isEnum';
51
- const displayValue = getTypeFromValue(value);
52
- throw new TypeCheckError(`Validation failed: ${validatorName} (${displayValue})`);
56
+ const errorMessage = getErrorMessage('isEnum', value);
57
+ throw new TypeCheckError(errorMessage);
53
58
  }
54
59
  return value;
55
60
  };
@@ -24,5 +24,12 @@ describe('typecheck', () => {
24
24
  expect(() => typeCheckEnum(null, ['BB'])).toThrowError(TypeCheckError);
25
25
  // @ts-expect-error
26
26
  expect(() => typeCheckEnum(['AA'], null)).toThrowError(TypeCheckError);
27
+ try {
28
+ typeCheckEnum('AA', ['BB']);
29
+ } catch (error) {
30
+ if (error instanceof Error) {
31
+ expect(error.message).toBe('Validation failed: isEnum - "AA" (string)');
32
+ }
33
+ }
27
34
  });
28
35
  });
@@ -59,3 +59,18 @@ export const saveAsFile = (filename, text) => {
59
59
  * @returns {string} Type in human readable format.
60
60
  */
61
61
  export const getTypeFromValue = (value) => Object.prototype.toString.call(value).slice(8, -1).toLowerCase();
62
+
63
+ /**
64
+ * Get value in human readable format.
65
+ * @param {unknown} value - The value to check.
66
+ * @returns {string} Value in human readable format.
67
+ */
68
+ export const getDisplayValue = (value) => {
69
+ if (typeof value === 'string') {
70
+ return `"${value}"`;
71
+ }
72
+ if (typeof value === 'object') {
73
+ return JSON.stringify(value);
74
+ }
75
+ return String(value);
76
+ };
@@ -1,6 +1,6 @@
1
1
  /* eslint-disable unicorn/no-useless-undefined */
2
2
 
3
- import { underscoreToCamelCase, capitalize, addLeadingZero, getTypeFromValue } from './string.js';
3
+ import { underscoreToCamelCase, capitalize, addLeadingZero, getTypeFromValue, getDisplayValue } from './string.js';
4
4
 
5
5
  test('Tests add leading zero', () => {
6
6
  expect(addLeadingZero(1)).toBe('01');
@@ -47,7 +47,7 @@ test('Converts underscore to camelCase', () => {
47
47
  expect(underscoreToCamelCase('test_variable_name')).toBe('testVariableName');
48
48
  });
49
49
 
50
- test('getDisplayValue', () => {
50
+ test('getTypeFromValue', () => {
51
51
  expect(getTypeFromValue('test')).toBe('string');
52
52
  expect(getTypeFromValue(() => null)).toBe('function');
53
53
  expect(getTypeFromValue([])).toBe('array');
@@ -57,3 +57,14 @@ test('getDisplayValue', () => {
57
57
  expect(getTypeFromValue(true)).toBe('boolean');
58
58
  expect(getTypeFromValue(undefined)).toBe('undefined');
59
59
  });
60
+
61
+ test('getDisplayValue', () => {
62
+ expect(getDisplayValue('test')).toBe('"test"');
63
+ expect(getDisplayValue(() => null)).toBe('() => null');
64
+ expect(getDisplayValue([])).toBe('[]');
65
+ expect(getDisplayValue({})).toBe('{}');
66
+ expect(getDisplayValue(new Date())).not.toBe(null);
67
+ expect(getDisplayValue(null)).toBe('null');
68
+ expect(getDisplayValue(true)).toBe('true');
69
+ expect(getDisplayValue(undefined)).toBe('undefined');
70
+ });
@@ -1 +1 @@
1
- {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/typecheck/util.js"],"names":[],"mappings":"AAcO,0BANM,CAAC,SACH,OAAO,aACP,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,GAC5B,CAAC,CAUb;AAUM,+BANM,CAAC,SACH,OAAO,EAAE,aACT,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,GAC5B,CAAC,EAAE,CAUf;AASM,qCALI,MAAM,GAAG,MAAM,WACf,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACnF,MAAM,GAAG,MAAM,CAU3B"}
1
+ {"version":3,"file":"util.d.ts","sourceRoot":"","sources":["../../src/typecheck/util.js"],"names":[],"mappings":"AAsBO,0BANM,CAAC,SACH,OAAO,aACP,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,GAC5B,CAAC,CASb;AAUM,+BANM,CAAC,SACH,OAAO,EAAE,aACT,CAAC,KAAK,EAAE,OAAO,KAAK,KAAK,IAAI,CAAC,GAC5B,CAAC,EAAE,CASf;AASM,qCALI,MAAM,GAAG,MAAM,WACf,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,GACnF,MAAM,GAAG,MAAM,CAS3B"}
@@ -3,4 +3,5 @@ export function capitalize(value: string | null | undefined): string | null;
3
3
  export function underscoreToCamelCase(value: string): string;
4
4
  export function saveAsFile(filename: string, text: string): void;
5
5
  export function getTypeFromValue(value: unknown): string;
6
+ export function getDisplayValue(value: unknown): string;
6
7
  //# sourceMappingURL=string.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/util/string.js"],"names":[],"mappings":"AAMO,sCAJI,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,SAClC,MAAM,GACJ,MAAM,GAAG,IAAI,CAWzB;AAOM,kCAHI,MAAM,GAAG,IAAI,GAAG,SAAS,GACvB,MAAM,GAAG,IAAI,CAWzB;AAOM,6CAHI,MAAM,GACJ,MAAM,CAEmF;AAO/F,qCAHI,MAAM,QACN,MAAM,QAUhB;AAOM,wCAHI,OAAO,GACL,MAAM,CAEwF"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/util/string.js"],"names":[],"mappings":"AAMO,sCAJI,MAAM,GAAG,MAAM,GAAG,IAAI,GAAG,SAAS,SAClC,MAAM,GACJ,MAAM,GAAG,IAAI,CAWzB;AAOM,kCAHI,MAAM,GAAG,IAAI,GAAG,SAAS,GACvB,MAAM,GAAG,IAAI,CAWzB;AAOM,6CAHI,MAAM,GACJ,MAAM,CAEmF;AAO/F,qCAHI,MAAM,QACN,MAAM,QAUhB;AAOM,wCAHI,OAAO,GACL,MAAM,CAEwF;AAOpG,uCAHI,OAAO,GACL,MAAM,CAUlB"}