@oxog/vld 1.1.1 → 1.3.1

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.
Files changed (150) hide show
  1. package/CHANGELOG.md +157 -0
  2. package/README.md +1128 -840
  3. package/dist/codecs/index.d.ts +89 -0
  4. package/dist/codecs/index.d.ts.map +1 -0
  5. package/dist/codecs/index.js +256 -0
  6. package/dist/codecs/index.js.map +1 -0
  7. package/dist/coercion/boolean.d.ts.map +1 -1
  8. package/dist/coercion/boolean.js +6 -2
  9. package/dist/coercion/boolean.js.map +1 -1
  10. package/dist/coercion/string.d.ts.map +1 -1
  11. package/dist/coercion/string.js +146 -10
  12. package/dist/coercion/string.js.map +1 -1
  13. package/dist/index.d.ts +14 -0
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +27 -1
  16. package/dist/index.js.map +1 -1
  17. package/dist/locales/af.d.ts.map +1 -1
  18. package/dist/locales/af.js +15 -1
  19. package/dist/locales/af.js.map +1 -1
  20. package/dist/locales/ar.d.ts.map +1 -1
  21. package/dist/locales/ar.js +15 -1
  22. package/dist/locales/ar.js.map +1 -1
  23. package/dist/locales/bn.d.ts.map +1 -1
  24. package/dist/locales/bn.js +15 -1
  25. package/dist/locales/bn.js.map +1 -1
  26. package/dist/locales/da.d.ts.map +1 -1
  27. package/dist/locales/da.js +15 -1
  28. package/dist/locales/da.js.map +1 -1
  29. package/dist/locales/de.d.ts.map +1 -1
  30. package/dist/locales/de.js +15 -1
  31. package/dist/locales/de.js.map +1 -1
  32. package/dist/locales/en.d.ts.map +1 -1
  33. package/dist/locales/en.js +15 -1
  34. package/dist/locales/en.js.map +1 -1
  35. package/dist/locales/es-MX.d.ts.map +1 -1
  36. package/dist/locales/es-MX.js +15 -1
  37. package/dist/locales/es-MX.js.map +1 -1
  38. package/dist/locales/es.d.ts.map +1 -1
  39. package/dist/locales/es.js +15 -1
  40. package/dist/locales/es.js.map +1 -1
  41. package/dist/locales/fi.d.ts.map +1 -1
  42. package/dist/locales/fi.js +15 -1
  43. package/dist/locales/fi.js.map +1 -1
  44. package/dist/locales/fr.d.ts.map +1 -1
  45. package/dist/locales/fr.js +15 -1
  46. package/dist/locales/fr.js.map +1 -1
  47. package/dist/locales/hi.d.ts.map +1 -1
  48. package/dist/locales/hi.js +15 -1
  49. package/dist/locales/hi.js.map +1 -1
  50. package/dist/locales/id.d.ts.map +1 -1
  51. package/dist/locales/id.js +15 -1
  52. package/dist/locales/id.js.map +1 -1
  53. package/dist/locales/it.d.ts.map +1 -1
  54. package/dist/locales/it.js +15 -1
  55. package/dist/locales/it.js.map +1 -1
  56. package/dist/locales/ja.d.ts.map +1 -1
  57. package/dist/locales/ja.js +15 -1
  58. package/dist/locales/ja.js.map +1 -1
  59. package/dist/locales/ko.d.ts.map +1 -1
  60. package/dist/locales/ko.js +15 -1
  61. package/dist/locales/ko.js.map +1 -1
  62. package/dist/locales/nl.d.ts.map +1 -1
  63. package/dist/locales/nl.js +15 -1
  64. package/dist/locales/nl.js.map +1 -1
  65. package/dist/locales/no.d.ts.map +1 -1
  66. package/dist/locales/no.js +15 -1
  67. package/dist/locales/no.js.map +1 -1
  68. package/dist/locales/pl.d.ts.map +1 -1
  69. package/dist/locales/pl.js +15 -1
  70. package/dist/locales/pl.js.map +1 -1
  71. package/dist/locales/pt-BR.d.ts.map +1 -1
  72. package/dist/locales/pt-BR.js +15 -1
  73. package/dist/locales/pt-BR.js.map +1 -1
  74. package/dist/locales/pt.d.ts.map +1 -1
  75. package/dist/locales/pt.js +15 -1
  76. package/dist/locales/pt.js.map +1 -1
  77. package/dist/locales/ru.d.ts.map +1 -1
  78. package/dist/locales/ru.js +15 -1
  79. package/dist/locales/ru.js.map +1 -1
  80. package/dist/locales/sv.d.ts.map +1 -1
  81. package/dist/locales/sv.js +15 -1
  82. package/dist/locales/sv.js.map +1 -1
  83. package/dist/locales/sw.d.ts.map +1 -1
  84. package/dist/locales/sw.js +15 -1
  85. package/dist/locales/sw.js.map +1 -1
  86. package/dist/locales/th.d.ts.map +1 -1
  87. package/dist/locales/th.js +15 -1
  88. package/dist/locales/th.js.map +1 -1
  89. package/dist/locales/tr.d.ts.map +1 -1
  90. package/dist/locales/tr.js +15 -1
  91. package/dist/locales/tr.js.map +1 -1
  92. package/dist/locales/types.d.ts +10 -0
  93. package/dist/locales/types.d.ts.map +1 -1
  94. package/dist/locales/types.js.map +1 -1
  95. package/dist/locales/vi.d.ts.map +1 -1
  96. package/dist/locales/vi.js +15 -1
  97. package/dist/locales/vi.js.map +1 -1
  98. package/dist/locales/zh.d.ts.map +1 -1
  99. package/dist/locales/zh.js +15 -1
  100. package/dist/locales/zh.js.map +1 -1
  101. package/dist/utils/codec-utils.d.ts +44 -0
  102. package/dist/utils/codec-utils.d.ts.map +1 -0
  103. package/dist/utils/codec-utils.js +205 -0
  104. package/dist/utils/codec-utils.js.map +1 -0
  105. package/dist/utils/deep-merge.d.ts +1 -0
  106. package/dist/utils/deep-merge.d.ts.map +1 -1
  107. package/dist/utils/deep-merge.js +33 -8
  108. package/dist/utils/deep-merge.js.map +1 -1
  109. package/dist/validators/array.d.ts +5 -0
  110. package/dist/validators/array.d.ts.map +1 -1
  111. package/dist/validators/array.js +30 -1
  112. package/dist/validators/array.js.map +1 -1
  113. package/dist/validators/base64.d.ts +18 -0
  114. package/dist/validators/base64.d.ts.map +1 -0
  115. package/dist/validators/base64.js +65 -0
  116. package/dist/validators/base64.js.map +1 -0
  117. package/dist/validators/codec.d.ts +55 -0
  118. package/dist/validators/codec.d.ts.map +1 -0
  119. package/dist/validators/codec.js +182 -0
  120. package/dist/validators/codec.js.map +1 -0
  121. package/dist/validators/date.d.ts +5 -1
  122. package/dist/validators/date.d.ts.map +1 -1
  123. package/dist/validators/date.js +53 -29
  124. package/dist/validators/date.js.map +1 -1
  125. package/dist/validators/hex.d.ts +17 -0
  126. package/dist/validators/hex.d.ts.map +1 -0
  127. package/dist/validators/hex.js +61 -0
  128. package/dist/validators/hex.js.map +1 -0
  129. package/dist/validators/number.d.ts.map +1 -1
  130. package/dist/validators/number.js +16 -3
  131. package/dist/validators/number.js.map +1 -1
  132. package/dist/validators/object.d.ts +5 -0
  133. package/dist/validators/object.d.ts.map +1 -1
  134. package/dist/validators/object.js +58 -6
  135. package/dist/validators/object.js.map +1 -1
  136. package/dist/validators/record.d.ts.map +1 -1
  137. package/dist/validators/record.js +6 -0
  138. package/dist/validators/record.js.map +1 -1
  139. package/dist/validators/string.d.ts.map +1 -1
  140. package/dist/validators/string.js +86 -4
  141. package/dist/validators/string.js.map +1 -1
  142. package/dist/validators/uint8array.d.ts +25 -0
  143. package/dist/validators/uint8array.d.ts.map +1 -0
  144. package/dist/validators/uint8array.js +87 -0
  145. package/dist/validators/uint8array.js.map +1 -0
  146. package/dist/validators/union.d.ts +1 -0
  147. package/dist/validators/union.d.ts.map +1 -1
  148. package/dist/validators/union.js +31 -20
  149. package/dist/validators/union.js.map +1 -1
  150. package/package.json +1 -1
@@ -20,36 +20,47 @@ export class VldUnion extends VldBase {
20
20
  }
21
21
  /**
22
22
  * Create type checker based on validator type for fast path optimization
23
+ * Uses a safer approach that's less prone to spoofing
23
24
  */
24
25
  createTypeChecker(validator) {
25
- // Quick type checks based on validator type
26
- const className = validator.constructor.name;
27
- switch (className) {
28
- case 'VldString':
26
+ // More conservative approach that prioritizes security and stability
27
+ // Only use fast path checks for very common, unambiguous types
28
+ try {
29
+ // Test basic types with safe parsing to validate the validator
30
+ const stringTest = validator.safeParse('test');
31
+ if (stringTest.success) {
29
32
  return (v) => typeof v === 'string';
30
- case 'VldNumber':
33
+ }
34
+ const numberTest = validator.safeParse(123);
35
+ if (numberTest.success) {
31
36
  return (v) => typeof v === 'number' && !isNaN(v);
32
- case 'VldBoolean':
37
+ }
38
+ const booleanTest = validator.safeParse(true);
39
+ if (booleanTest.success) {
33
40
  return (v) => typeof v === 'boolean';
34
- case 'VldDate':
35
- return (v) => v instanceof Date || (typeof v === 'string' && !isNaN(Date.parse(v)));
36
- case 'VldArray':
41
+ }
42
+ const arrayTest = validator.safeParse([]);
43
+ if (arrayTest.success) {
37
44
  return (v) => Array.isArray(v);
38
- case 'VldObject':
45
+ }
46
+ const objectTest = validator.safeParse({});
47
+ if (objectTest.success) {
39
48
  return (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
40
- case 'VldBigInt':
41
- return (v) => typeof v === 'bigint';
42
- case 'VldSymbol':
43
- return (v) => typeof v === 'symbol';
44
- case 'VldNull':
49
+ }
50
+ const nullTest = validator.safeParse(null);
51
+ if (nullTest.success) {
45
52
  return (v) => v === null;
46
- case 'VldUndefined':
47
- return (v) => v === undefined;
48
- case 'VldVoid':
53
+ }
54
+ const undefinedTest = validator.safeParse(undefined);
55
+ if (undefinedTest.success) {
49
56
  return (v) => v === undefined;
50
- default:
51
- return () => true; // No quick check available
57
+ }
58
+ }
59
+ catch {
60
+ // If safe testing fails, fall back to safe validation
52
61
  }
62
+ // Fallback: no quick check available - use safe validation
63
+ return () => true;
53
64
  }
54
65
  /**
55
66
  * Create a new union validator
@@ -1 +1 @@
1
- {"version":3,"file":"union.js","sourceRoot":"","sources":["../../src/validators/union.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAe,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEzC;;;GAGG;AACH,MAAM,OAAO,QAAiD,SAAQ,OAGrE;IAOC;;OAEG;IACH,YACE,UAAa,EACb,YAAqB;QAErB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,YAAY,GAAG,IAAI,GAAG,EAAE,CAAC;QAE9B,6CAA6C;QAC7C,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;YACnC,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC;QACtE,CAAC;IACH,CAAC;IAED;;OAEG;IACK,iBAAiB,CAAC,SAA4B;QACpD,4CAA4C;QAC5C,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,CAAC;QAE7C,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,WAAW;gBACd,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACtC,KAAK,WAAW;gBACd,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,CAAW,CAAC,CAAC;YAC7D,KAAK,YAAY;gBACf,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,SAAS,CAAC;YACvC,KAAK,SAAS;gBACZ,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,YAAY,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAW,CAAC,CAAC,CAAC,CAAC;YAChG,KAAK,UAAU;gBACb,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACjC,KAAK,WAAW;gBACd,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YACzE,KAAK,WAAW;gBACd,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACtC,KAAK,WAAW;gBACd,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;YACtC,KAAK,SAAS;gBACZ,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC;YAC3B,KAAK,cAAc;gBACjB,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;YAChC,KAAK,SAAS;gBACZ,OAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC;YAChC;gBACE,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,2BAA2B;QAClD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,MAAM,CAAC,MAAM,CAAyC,GAAG,UAAa;QACpE,OAAO,IAAI,QAAQ,CAAC,UAAU,CAAC,CAAC;IAClC,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,KAAc;QAClB,mEAAmE;QACnE,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAErD,8CAA8C;YAC9C,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,4CAA4C;YAC5C,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,MAAM,CAAC,IAAI,CAAC;YACrB,CAAC;QACH,CAAC;QAED,yDAAyD;QACzD,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,MAAM,IAAI,KAAK,CACb,IAAI,CAAC,YAAY;YACjB,WAAW,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CACnC,CAAC;IACJ,CAAC;IAED;;;OAGG;IACH,SAAS,CAAC,KAAc;QACtB,+BAA+B;QAC/B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAErD,8CAA8C;YAC9C,IAAI,WAAW,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBACvC,SAAS;YACX,CAAC;YAED,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;gBACnB,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QAED,0CAA0C;QAC1C,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,KAAK,MAAM,SAAS,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;YAC1C,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACpB,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;QACH,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,IAAI,KAAK,CACd,IAAI,CAAC,YAAY;gBACjB,WAAW,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CACnC;SACF,CAAC;IACJ,CAAC;CACF","sourcesContent":["import { VldBase, ParseResult } from './base';\nimport { getMessages } from '../locales';\n\n/**\n * Optimized immutable union validator for multiple type options\n * Features type-checking shortcuts for 110x performance improvement\n */\nexport class VldUnion<T extends readonly VldBase<any, any>[]> extends VldBase<\n unknown,\n T[number] extends VldBase<any, infer U> ? U : never\n> {\n private readonly validators: T;\n private readonly errorMessage?: string;\n \n // Cache for type checking optimization\n private readonly typeCheckers: Map<VldBase<any, any>, (value: unknown) => boolean>;\n \n /**\n * Private constructor to enforce immutability\n */\n private constructor(\n validators: T,\n errorMessage?: string\n ) {\n super();\n this.validators = validators;\n this.errorMessage = errorMessage;\n this.typeCheckers = new Map();\n \n // Pre-compile type checkers for common types\n for (const validator of validators) {\n this.typeCheckers.set(validator, this.createTypeChecker(validator));\n }\n }\n \n /**\n * Create type checker based on validator type for fast path optimization\n */\n private createTypeChecker(validator: VldBase<any, any>): (value: unknown) => boolean {\n // Quick type checks based on validator type\n const className = validator.constructor.name;\n \n switch (className) {\n case 'VldString':\n return (v) => typeof v === 'string';\n case 'VldNumber':\n return (v) => typeof v === 'number' && !isNaN(v as number);\n case 'VldBoolean':\n return (v) => typeof v === 'boolean';\n case 'VldDate':\n return (v) => v instanceof Date || (typeof v === 'string' && !isNaN(Date.parse(v as string)));\n case 'VldArray':\n return (v) => Array.isArray(v);\n case 'VldObject':\n return (v) => typeof v === 'object' && v !== null && !Array.isArray(v);\n case 'VldBigInt':\n return (v) => typeof v === 'bigint';\n case 'VldSymbol':\n return (v) => typeof v === 'symbol';\n case 'VldNull':\n return (v) => v === null;\n case 'VldUndefined':\n return (v) => v === undefined;\n case 'VldVoid':\n return (v) => v === undefined;\n default:\n return () => true; // No quick check available\n }\n }\n \n /**\n * Create a new union validator\n */\n static create<T extends readonly VldBase<any, any>[]>(...validators: T): VldUnion<T> {\n return new VldUnion(validators);\n }\n \n /**\n * Parse and validate a value against union options\n * Optimized with type checking and safeParse to avoid try-catch overhead\n */\n parse(value: unknown): T[number] extends VldBase<any, infer U> ? U : never {\n // Fast path: try validators that are likely to match based on type\n for (const validator of this.validators) {\n const typeChecker = this.typeCheckers.get(validator);\n \n // Skip validators that definitely won't match\n if (typeChecker && !typeChecker(value)) {\n continue;\n }\n \n // Use safeParse to avoid try-catch overhead\n const result = validator.safeParse(value);\n if (result.success) {\n return result.data;\n }\n }\n \n // Slow path: collect all errors for better error message\n const errors: string[] = [];\n for (const validator of this.validators) {\n const result = validator.safeParse(value);\n if (!result.success) {\n errors.push(result.error.message);\n }\n }\n \n throw new Error(\n this.errorMessage || \n getMessages().unionNoMatch(errors)\n );\n }\n \n /**\n * Safely parse and validate a value against union options\n * Optimized version using type checking shortcuts\n */\n safeParse(value: unknown): ParseResult<T[number] extends VldBase<any, infer U> ? U : never> {\n // Fast path with type checking\n for (const validator of this.validators) {\n const typeChecker = this.typeCheckers.get(validator);\n \n // Skip validators that definitely won't match\n if (typeChecker && !typeChecker(value)) {\n continue;\n }\n \n const result = validator.safeParse(value);\n if (result.success) {\n return result;\n }\n }\n \n // All failed - collect errors for message\n const errors: string[] = [];\n for (const validator of this.validators) {\n const result = validator.safeParse(value);\n if (!result.success) {\n errors.push(result.error.message);\n }\n }\n \n return {\n success: false,\n error: new Error(\n this.errorMessage || \n getMessages().unionNoMatch(errors)\n )\n };\n }\n}"]}
1
+ {"version":3,"file":"union.js","sourceRoot":"","sources":["../../src/validators/union.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldBase, ParseResult } from './base';\nimport { getMessages } from '../locales';\n\n/**\n * Optimized immutable union validator for multiple type options\n * Features type-checking shortcuts for 110x performance improvement\n */\nexport class VldUnion<T extends readonly VldBase<any, any>[]> extends VldBase<\n unknown,\n T[number] extends VldBase<any, infer U> ? U : never\n> {\n private readonly validators: T;\n private readonly errorMessage?: string;\n \n // Cache for type checking optimization\n private readonly typeCheckers: Map<VldBase<any, any>, (value: unknown) => boolean>;\n \n /**\n * Private constructor to enforce immutability\n */\n private constructor(\n validators: T,\n errorMessage?: string\n ) {\n super();\n this.validators = validators;\n this.errorMessage = errorMessage;\n this.typeCheckers = new Map();\n \n // Pre-compile type checkers for common types\n for (const validator of validators) {\n this.typeCheckers.set(validator, this.createTypeChecker(validator));\n }\n }\n \n /**\n * Create type checker based on validator type for fast path optimization\n * Uses a safer approach that's less prone to spoofing\n */\n private createTypeChecker(validator: VldBase<any, any>): (value: unknown) => boolean {\n // More conservative approach that prioritizes security and stability\n // Only use fast path checks for very common, unambiguous types\n\n try {\n // Test basic types with safe parsing to validate the validator\n const stringTest = validator.safeParse('test');\n if (stringTest.success) {\n return (v) => typeof v === 'string';\n }\n\n const numberTest = validator.safeParse(123);\n if (numberTest.success) {\n return (v) => typeof v === 'number' && !isNaN(v as number);\n }\n\n const booleanTest = validator.safeParse(true);\n if (booleanTest.success) {\n return (v) => typeof v === 'boolean';\n }\n\n const arrayTest = validator.safeParse([]);\n if (arrayTest.success) {\n return (v) => Array.isArray(v);\n }\n\n const objectTest = validator.safeParse({});\n if (objectTest.success) {\n return (v) => typeof v === 'object' && v !== null && !Array.isArray(v);\n }\n\n const nullTest = validator.safeParse(null);\n if (nullTest.success) {\n return (v) => v === null;\n }\n\n const undefinedTest = validator.safeParse(undefined);\n if (undefinedTest.success) {\n return (v) => v === undefined;\n }\n } catch {\n // If safe testing fails, fall back to safe validation\n }\n\n // Fallback: no quick check available - use safe validation\n return () => true;\n }\n \n /**\n * Create a new union validator\n */\n static create<T extends readonly VldBase<any, any>[]>(...validators: T): VldUnion<T> {\n return new VldUnion(validators);\n }\n \n /**\n * Parse and validate a value against union options\n * Optimized with type checking and safeParse to avoid try-catch overhead\n */\n parse(value: unknown): T[number] extends VldBase<any, infer U> ? U : never {\n // Fast path: try validators that are likely to match based on type\n for (const validator of this.validators) {\n const typeChecker = this.typeCheckers.get(validator);\n \n // Skip validators that definitely won't match\n if (typeChecker && !typeChecker(value)) {\n continue;\n }\n \n // Use safeParse to avoid try-catch overhead\n const result = validator.safeParse(value);\n if (result.success) {\n return result.data;\n }\n }\n \n // Slow path: collect all errors for better error message\n const errors: string[] = [];\n for (const validator of this.validators) {\n const result = validator.safeParse(value);\n if (!result.success) {\n errors.push(result.error.message);\n }\n }\n \n throw new Error(\n this.errorMessage || \n getMessages().unionNoMatch(errors)\n );\n }\n \n /**\n * Safely parse and validate a value against union options\n * Optimized version using type checking shortcuts\n */\n safeParse(value: unknown): ParseResult<T[number] extends VldBase<any, infer U> ? U : never> {\n // Fast path with type checking\n for (const validator of this.validators) {\n const typeChecker = this.typeCheckers.get(validator);\n \n // Skip validators that definitely won't match\n if (typeChecker && !typeChecker(value)) {\n continue;\n }\n \n const result = validator.safeParse(value);\n if (result.success) {\n return result;\n }\n }\n \n // All failed - collect errors for message\n const errors: string[] = [];\n for (const validator of this.validators) {\n const result = validator.safeParse(value);\n if (!result.success) {\n errors.push(result.error.message);\n }\n }\n \n return {\n success: false,\n error: new Error(\n this.errorMessage || \n getMessages().unionNoMatch(errors)\n )\n };\n }\n}"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oxog/vld",
3
- "version": "1.1.1",
3
+ "version": "1.3.1",
4
4
  "description": "Ultra-fast TypeScript-first schema validation with zero dependencies and 27+ language support",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",