@oxog/vld 1.3.1 → 1.4.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.
Files changed (257) hide show
  1. package/CHANGELOG.md +49 -0
  2. package/README.md +1129 -1128
  3. package/dist/coercion/bigint.js +1 -1
  4. package/dist/coercion/boolean.js +1 -1
  5. package/dist/coercion/date.js +1 -1
  6. package/dist/coercion/number.d.ts.map +1 -1
  7. package/dist/coercion/number.js +20 -4
  8. package/dist/coercion/number.js.map +1 -1
  9. package/dist/coercion/string.d.ts.map +1 -1
  10. package/dist/coercion/string.js +9 -73
  11. package/dist/coercion/string.js.map +1 -1
  12. package/dist/index.d.ts +593 -3
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +76 -5
  15. package/dist/index.js.map +1 -1
  16. package/dist/locales/af.d.ts.map +1 -1
  17. package/dist/locales/af.js +18 -1
  18. package/dist/locales/af.js.map +1 -1
  19. package/dist/locales/ar.d.ts.map +1 -1
  20. package/dist/locales/ar.js +18 -1
  21. package/dist/locales/ar.js.map +1 -1
  22. package/dist/locales/backup-en.d.ts +3 -0
  23. package/dist/locales/backup-en.d.ts.map +1 -0
  24. package/dist/locales/backup-en.js +105 -0
  25. package/dist/locales/backup-en.js.map +1 -0
  26. package/dist/locales/bn.d.ts.map +1 -1
  27. package/dist/locales/bn.js +18 -1
  28. package/dist/locales/bn.js.map +1 -1
  29. package/dist/locales/da.d.ts.map +1 -1
  30. package/dist/locales/da.js +18 -1
  31. package/dist/locales/da.js.map +1 -1
  32. package/dist/locales/de.d.ts.map +1 -1
  33. package/dist/locales/de.js +18 -1
  34. package/dist/locales/de.js.map +1 -1
  35. package/dist/locales/en.d.ts.map +1 -1
  36. package/dist/locales/en.js +18 -1
  37. package/dist/locales/en.js.map +1 -1
  38. package/dist/locales/es-MX.d.ts.map +1 -1
  39. package/dist/locales/es-MX.js +17 -1
  40. package/dist/locales/es-MX.js.map +1 -1
  41. package/dist/locales/es.d.ts.map +1 -1
  42. package/dist/locales/es.js +18 -1
  43. package/dist/locales/es.js.map +1 -1
  44. package/dist/locales/fi.d.ts.map +1 -1
  45. package/dist/locales/fi.js +18 -1
  46. package/dist/locales/fi.js.map +1 -1
  47. package/dist/locales/fr.d.ts.map +1 -1
  48. package/dist/locales/fr.js +18 -1
  49. package/dist/locales/fr.js.map +1 -1
  50. package/dist/locales/hi.d.ts.map +1 -1
  51. package/dist/locales/hi.js +18 -1
  52. package/dist/locales/hi.js.map +1 -1
  53. package/dist/locales/id.d.ts.map +1 -1
  54. package/dist/locales/id.js +18 -1
  55. package/dist/locales/id.js.map +1 -1
  56. package/dist/locales/it.d.ts.map +1 -1
  57. package/dist/locales/it.js +18 -1
  58. package/dist/locales/it.js.map +1 -1
  59. package/dist/locales/ja.d.ts.map +1 -1
  60. package/dist/locales/ja.js +18 -1
  61. package/dist/locales/ja.js.map +1 -1
  62. package/dist/locales/ko.d.ts.map +1 -1
  63. package/dist/locales/ko.js +18 -1
  64. package/dist/locales/ko.js.map +1 -1
  65. package/dist/locales/nl.d.ts.map +1 -1
  66. package/dist/locales/nl.js +18 -1
  67. package/dist/locales/nl.js.map +1 -1
  68. package/dist/locales/no.d.ts.map +1 -1
  69. package/dist/locales/no.js +18 -1
  70. package/dist/locales/no.js.map +1 -1
  71. package/dist/locales/pl.d.ts.map +1 -1
  72. package/dist/locales/pl.js +18 -1
  73. package/dist/locales/pl.js.map +1 -1
  74. package/dist/locales/pt-BR.d.ts.map +1 -1
  75. package/dist/locales/pt-BR.js +18 -1
  76. package/dist/locales/pt-BR.js.map +1 -1
  77. package/dist/locales/pt.d.ts.map +1 -1
  78. package/dist/locales/pt.js +18 -1
  79. package/dist/locales/pt.js.map +1 -1
  80. package/dist/locales/ru.d.ts.map +1 -1
  81. package/dist/locales/ru.js +18 -1
  82. package/dist/locales/ru.js.map +1 -1
  83. package/dist/locales/sv.d.ts.map +1 -1
  84. package/dist/locales/sv.js +18 -1
  85. package/dist/locales/sv.js.map +1 -1
  86. package/dist/locales/sw.d.ts.map +1 -1
  87. package/dist/locales/sw.js +18 -1
  88. package/dist/locales/sw.js.map +1 -1
  89. package/dist/locales/th.d.ts.map +1 -1
  90. package/dist/locales/th.js +18 -1
  91. package/dist/locales/th.js.map +1 -1
  92. package/dist/locales/tr.d.ts.map +1 -1
  93. package/dist/locales/tr.js +18 -1
  94. package/dist/locales/tr.js.map +1 -1
  95. package/dist/locales/types.d.ts +13 -0
  96. package/dist/locales/types.d.ts.map +1 -1
  97. package/dist/locales/types.js.map +1 -1
  98. package/dist/locales/vi.d.ts.map +1 -1
  99. package/dist/locales/vi.js +18 -1
  100. package/dist/locales/vi.js.map +1 -1
  101. package/dist/locales/zh.d.ts.map +1 -1
  102. package/dist/locales/zh.js +18 -1
  103. package/dist/locales/zh.js.map +1 -1
  104. package/dist/utils/codec-utils.d.ts +2 -0
  105. package/dist/utils/codec-utils.d.ts.map +1 -1
  106. package/dist/utils/codec-utils.js +22 -4
  107. package/dist/utils/codec-utils.js.map +1 -1
  108. package/dist/utils/deep-merge.d.ts +2 -0
  109. package/dist/utils/deep-merge.d.ts.map +1 -1
  110. package/dist/utils/deep-merge.js +22 -39
  111. package/dist/utils/deep-merge.js.map +1 -1
  112. package/dist/utils/ip-validation.d.ts +11 -0
  113. package/dist/utils/ip-validation.d.ts.map +1 -0
  114. package/dist/utils/ip-validation.js +78 -0
  115. package/dist/utils/ip-validation.js.map +1 -0
  116. package/dist/utils/security.d.ts +12 -0
  117. package/dist/utils/security.d.ts.map +1 -0
  118. package/dist/utils/security.js +61 -0
  119. package/dist/utils/security.js.map +1 -0
  120. package/dist/validators/array.d.ts +3 -1
  121. package/dist/validators/array.d.ts.map +1 -1
  122. package/dist/validators/array.js +41 -15
  123. package/dist/validators/array.js.map +1 -1
  124. package/dist/validators/base.d.ts +131 -0
  125. package/dist/validators/base.d.ts.map +1 -1
  126. package/dist/validators/base.js +247 -1
  127. package/dist/validators/base.js.map +1 -1
  128. package/dist/validators/base64.js +1 -1
  129. package/dist/validators/bigint.d.ts +20 -0
  130. package/dist/validators/bigint.d.ts.map +1 -1
  131. package/dist/validators/bigint.js +39 -1
  132. package/dist/validators/bigint.js.map +1 -1
  133. package/dist/validators/boolean.js +29 -1
  134. package/dist/validators/boolean.js.map +1 -1
  135. package/dist/validators/codec.js +1 -1
  136. package/dist/validators/custom.d.ts +47 -0
  137. package/dist/validators/custom.d.ts.map +1 -0
  138. package/dist/validators/custom.js +50 -0
  139. package/dist/validators/custom.js.map +1 -0
  140. package/dist/validators/date.d.ts +16 -0
  141. package/dist/validators/date.d.ts.map +1 -1
  142. package/dist/validators/date.js +62 -7
  143. package/dist/validators/date.js.map +1 -1
  144. package/dist/validators/discriminated-union.d.ts +29 -0
  145. package/dist/validators/discriminated-union.d.ts.map +1 -0
  146. package/dist/validators/discriminated-union.js +98 -0
  147. package/dist/validators/discriminated-union.js.map +1 -0
  148. package/dist/validators/enum.d.ts +10 -0
  149. package/dist/validators/enum.d.ts.map +1 -1
  150. package/dist/validators/enum.js +38 -1
  151. package/dist/validators/enum.js.map +1 -1
  152. package/dist/validators/file.d.ts +57 -0
  153. package/dist/validators/file.d.ts.map +1 -0
  154. package/dist/validators/file.js +114 -0
  155. package/dist/validators/file.js.map +1 -0
  156. package/dist/validators/function.d.ts +26 -0
  157. package/dist/validators/function.d.ts.map +1 -0
  158. package/dist/validators/function.js +45 -0
  159. package/dist/validators/function.js.map +1 -0
  160. package/dist/validators/hex.d.ts.map +1 -1
  161. package/dist/validators/hex.js +3 -2
  162. package/dist/validators/hex.js.map +1 -1
  163. package/dist/validators/index.d.ts +18 -1
  164. package/dist/validators/index.d.ts.map +1 -1
  165. package/dist/validators/index.js +16 -1
  166. package/dist/validators/index.js.map +1 -1
  167. package/dist/validators/intersection.d.ts.map +1 -1
  168. package/dist/validators/intersection.js +15 -8
  169. package/dist/validators/intersection.js.map +1 -1
  170. package/dist/validators/json.d.ts +26 -0
  171. package/dist/validators/json.d.ts.map +1 -0
  172. package/dist/validators/json.js +64 -0
  173. package/dist/validators/json.js.map +1 -0
  174. package/dist/validators/lazy.d.ts +28 -0
  175. package/dist/validators/lazy.d.ts.map +1 -0
  176. package/dist/validators/lazy.js +42 -0
  177. package/dist/validators/lazy.js.map +1 -0
  178. package/dist/validators/literal.js +1 -1
  179. package/dist/validators/map.js +1 -1
  180. package/dist/validators/nan.d.ts +17 -0
  181. package/dist/validators/nan.d.ts.map +1 -0
  182. package/dist/validators/nan.js +32 -0
  183. package/dist/validators/nan.js.map +1 -0
  184. package/dist/validators/never.js +1 -1
  185. package/dist/validators/null.d.ts +16 -0
  186. package/dist/validators/null.d.ts.map +1 -0
  187. package/dist/validators/null.js +31 -0
  188. package/dist/validators/null.js.map +1 -0
  189. package/dist/validators/number.d.ts +22 -0
  190. package/dist/validators/number.d.ts.map +1 -1
  191. package/dist/validators/number.js +47 -8
  192. package/dist/validators/number.js.map +1 -1
  193. package/dist/validators/object.d.ts +32 -0
  194. package/dist/validators/object.d.ts.map +1 -1
  195. package/dist/validators/object.js +125 -8
  196. package/dist/validators/object.js.map +1 -1
  197. package/dist/validators/record.d.ts +15 -2
  198. package/dist/validators/record.d.ts.map +1 -1
  199. package/dist/validators/record.js +74 -4
  200. package/dist/validators/record.js.map +1 -1
  201. package/dist/validators/set.js +1 -1
  202. package/dist/validators/string-bool.d.ts +61 -0
  203. package/dist/validators/string-bool.d.ts.map +1 -0
  204. package/dist/validators/string-bool.js +127 -0
  205. package/dist/validators/string-bool.js.map +1 -0
  206. package/dist/validators/string-formats.d.ts +97 -0
  207. package/dist/validators/string-formats.d.ts.map +1 -0
  208. package/dist/validators/string-formats.js +120 -0
  209. package/dist/validators/string-formats.js.map +1 -0
  210. package/dist/validators/string.d.ts.map +1 -1
  211. package/dist/validators/string.js +2 -73
  212. package/dist/validators/string.js.map +1 -1
  213. package/dist/validators/symbol.js +1 -1
  214. package/dist/validators/template-literal.d.ts +32 -0
  215. package/dist/validators/template-literal.d.ts.map +1 -0
  216. package/dist/validators/template-literal.js +101 -0
  217. package/dist/validators/template-literal.js.map +1 -0
  218. package/dist/validators/tuple.js +1 -1
  219. package/dist/validators/uint8array.d.ts +21 -4
  220. package/dist/validators/uint8array.d.ts.map +1 -1
  221. package/dist/validators/uint8array.js +34 -23
  222. package/dist/validators/uint8array.js.map +1 -1
  223. package/dist/validators/undefined.d.ts +16 -0
  224. package/dist/validators/undefined.d.ts.map +1 -0
  225. package/dist/validators/undefined.js +31 -0
  226. package/dist/validators/undefined.js.map +1 -0
  227. package/dist/validators/union.d.ts +2 -0
  228. package/dist/validators/union.d.ts.map +1 -1
  229. package/dist/validators/union.js +15 -21
  230. package/dist/validators/union.js.map +1 -1
  231. package/dist/validators/void.js +1 -1
  232. package/dist/validators/xor.d.ts +23 -0
  233. package/dist/validators/xor.d.ts.map +1 -0
  234. package/dist/validators/xor.js +64 -0
  235. package/dist/validators/xor.js.map +1 -0
  236. package/package.json +2 -2
  237. package/dist/index-new.d.ts.map +0 -1
  238. package/dist/locales.d.ts +0 -54
  239. package/dist/locales.d.ts.map +0 -1
  240. package/dist/locales.js +0 -732
  241. package/dist/locales.js.map +0 -1
  242. package/dist/validators/object-optimized.d.ts +0 -23
  243. package/dist/validators/object-optimized.d.ts.map +0 -1
  244. package/dist/validators/object-optimized.js +0 -179
  245. package/dist/validators/object-optimized.js.map +0 -1
  246. package/dist/validators/object-ultra.d.ts +0 -34
  247. package/dist/validators/object-ultra.d.ts.map +0 -1
  248. package/dist/validators/object-ultra.js +0 -175
  249. package/dist/validators/object-ultra.js.map +0 -1
  250. package/dist/validators/string-ultra.d.ts +0 -49
  251. package/dist/validators/string-ultra.d.ts.map +0 -1
  252. package/dist/validators/string-ultra.js +0 -217
  253. package/dist/validators/string-ultra.js.map +0 -1
  254. package/dist/validators/union-optimized.d.ts +0 -15
  255. package/dist/validators/union-optimized.d.ts.map +0 -1
  256. package/dist/validators/union-optimized.js +0 -92
  257. package/dist/validators/union-optimized.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { VldBigInt } from '../validators/bigint.js';
2
- import { getMessages } from '../locales.js';
2
+ import { getMessages } from '../locales/index.js';
3
3
  /**
4
4
  * BigInt coercion validator that attempts to convert values to bigint
5
5
  */
@@ -1,5 +1,5 @@
1
1
  import { VldBoolean } from '../validators/boolean.js';
2
- import { getMessages } from '../locales.js';
2
+ import { getMessages } from '../locales/index.js';
3
3
  /**
4
4
  * Boolean coercion validator that attempts to convert values to booleans
5
5
  */
@@ -1,5 +1,5 @@
1
1
  import { VldDate } from '../validators/date.js';
2
- import { getMessages } from '../locales.js';
2
+ import { getMessages } from '../locales/index.js';
3
3
  /**
4
4
  * Date coercion validator that attempts to convert values to dates
5
5
  */
@@ -1 +1 @@
1
- {"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../src/coercion/number.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,SAAS,aAAa,MAAM,CAAC,EAAE,GAAG;IAIlC;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,eAAe;IAKhC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOrD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOrD,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO3C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO9C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO9C,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOzC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOvC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO5D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAItD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOpE,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOvC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOtC;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAgC7B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;CAO/C"}
1
+ {"version":3,"file":"number.d.ts","sourceRoot":"","sources":["../../src/coercion/number.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,SAAS,aAAa,MAAM,CAAC,EAAE,GAAG;IAIlC;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,eAAe;IAKhC,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOrD,GAAG,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOrD,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOtC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO3C,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO3C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO9C,WAAW,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAO9C,MAAM,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOzC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOvC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAW5D,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAItD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAOpE,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAavC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAatC;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAgC7B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;CAO/C"}
@@ -1,5 +1,5 @@
1
1
  import { VldNumber } from '../validators/number.js';
2
- import { getMessages } from '../locales.js';
2
+ import { getMessages } from '../locales/index.js';
3
3
  /**
4
4
  * Number coercion validator that attempts to convert values to numbers
5
5
  */
@@ -70,7 +70,11 @@ export class VldCoerceNumber extends VldNumber {
70
70
  }
71
71
  multipleOf(value, message) {
72
72
  return new VldCoerceNumber({
73
- checks: [...this.config.checks, (v) => v % value === 0],
73
+ checks: [...this.config.checks, (v) => {
74
+ // BUG-004 FIX: Use epsilon comparison for floating point precision (consistent with VldNumber)
75
+ const remainder = Math.abs(v % value);
76
+ return remainder < Number.EPSILON || Math.abs(remainder - Math.abs(value)) < Number.EPSILON;
77
+ }],
74
78
  errorMessage: message || getMessages().numberMultipleOf(value)
75
79
  });
76
80
  }
@@ -84,14 +88,26 @@ export class VldCoerceNumber extends VldNumber {
84
88
  });
85
89
  }
86
90
  even(message) {
91
+ // BUG-NEW-007 FIX: Add integer check before even/odd validation
87
92
  return new VldCoerceNumber({
88
- checks: [...this.config.checks, (v) => v % 2 === 0],
93
+ checks: [...this.config.checks, (v) => {
94
+ if (!Number.isInteger(v)) {
95
+ return false;
96
+ }
97
+ return v % 2 === 0;
98
+ }],
89
99
  errorMessage: message || 'Number must be even'
90
100
  });
91
101
  }
92
102
  odd(message) {
103
+ // BUG-NEW-007 FIX: Add integer check before even/odd validation
93
104
  return new VldCoerceNumber({
94
- checks: [...this.config.checks, (v) => v % 2 !== 0],
105
+ checks: [...this.config.checks, (v) => {
106
+ if (!Number.isInteger(v)) {
107
+ return false;
108
+ }
109
+ return v % 2 !== 0;
110
+ }],
95
111
  errorMessage: message || 'Number must be odd'
96
112
  });
97
113
  }
@@ -1 +1 @@
1
- {"version":3,"file":"number.js","sourceRoot":"","sources":["../../src/coercion/number.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldNumber } from '../validators/number';\nimport { ParseResult } from '../validators/base';\nimport { getMessages } from '../locales';\n\n/**\n * Number coercion validator that attempts to convert values to numbers\n */\nexport class VldCoerceNumber extends VldNumber {\n protected constructor(config?: any) {\n super(config);\n }\n \n /**\n * Create a new coerce number validator\n */\n static create(): VldCoerceNumber {\n return new VldCoerceNumber();\n }\n \n // Override all chain methods to return VldCoerceNumber instances\n min(value: number, message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v >= value],\n errorMessage: message || getMessages().numberMin(value)\n });\n }\n \n max(value: number, message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v <= value],\n errorMessage: message || getMessages().numberMax(value)\n });\n }\n \n int(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => Number.isInteger(v)],\n errorMessage: message || getMessages().numberInt\n });\n }\n \n positive(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v > 0],\n errorMessage: message || getMessages().numberPositive\n });\n }\n \n negative(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v < 0],\n errorMessage: message || getMessages().numberNegative\n });\n }\n \n nonnegative(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v >= 0],\n errorMessage: message || getMessages().numberNonnegative\n });\n }\n \n nonpositive(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v <= 0],\n errorMessage: message || getMessages().numberNonpositive\n });\n }\n \n finite(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => Number.isFinite(v)],\n errorMessage: message || getMessages().numberFinite\n });\n }\n \n safe(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => Number.isSafeInteger(v)],\n errorMessage: message || getMessages().numberSafe\n });\n }\n \n multipleOf(value: number, message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v % value === 0],\n errorMessage: message || getMessages().numberMultipleOf(value)\n });\n }\n \n step(value: number, message?: string): VldCoerceNumber {\n return this.multipleOf(value, message);\n }\n \n between(min: number, max: number, message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v >= min && v <= max],\n errorMessage: message || `Number must be between ${min} and ${max}`\n });\n }\n \n even(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v % 2 === 0],\n errorMessage: message || 'Number must be even'\n });\n }\n \n odd(message?: string): VldCoerceNumber {\n return new VldCoerceNumber({\n checks: [...this.config.checks, (v: number) => v % 2 !== 0],\n errorMessage: message || 'Number must be odd'\n });\n }\n \n /**\n * Parse and coerce a value to number\n */\n parse(value: unknown): number {\n // If it's already a valid number, use parent validation directly\n if (typeof value === 'number' && !isNaN(value)) {\n return super.parse(value);\n }\n \n let coerced: number;\n \n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed === '') {\n throw new Error(getMessages().coercionFailed('number', value));\n }\n coerced = Number(trimmed);\n if (isNaN(coerced)) {\n throw new Error(getMessages().coercionFailed('number', value));\n }\n } else if (typeof value === 'boolean') {\n coerced = value ? 1 : 0;\n } else if (value === null || value === undefined) {\n throw new Error(getMessages().coercionFailed('number', value));\n } else {\n coerced = Number(value);\n if (isNaN(coerced)) {\n throw new Error(getMessages().coercionFailed('number', value));\n }\n }\n \n // Use parent validation with coerced value\n return super.parse(coerced);\n }\n \n /**\n * Safely parse and coerce a value to number\n */\n safeParse(value: unknown): ParseResult<number> {\n try {\n return { success: true, data: this.parse(value) };\n } catch (error) {\n return { success: false, error: error as Error };\n }\n }\n}"]}
1
+ {"version":3,"file":"number.js","sourceRoot":"","sources":["../../src/coercion/number.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldNumber } from '../validators/number';\r\nimport { ParseResult } from '../validators/base';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * Number coercion validator that attempts to convert values to numbers\r\n */\r\nexport class VldCoerceNumber extends VldNumber {\r\n protected constructor(config?: any) {\r\n super(config);\r\n }\r\n \r\n /**\r\n * Create a new coerce number validator\r\n */\r\n static create(): VldCoerceNumber {\r\n return new VldCoerceNumber();\r\n }\r\n \r\n // Override all chain methods to return VldCoerceNumber instances\r\n min(value: number, message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v >= value],\r\n errorMessage: message || getMessages().numberMin(value)\r\n });\r\n }\r\n \r\n max(value: number, message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v <= value],\r\n errorMessage: message || getMessages().numberMax(value)\r\n });\r\n }\r\n \r\n int(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => Number.isInteger(v)],\r\n errorMessage: message || getMessages().numberInt\r\n });\r\n }\r\n \r\n positive(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v > 0],\r\n errorMessage: message || getMessages().numberPositive\r\n });\r\n }\r\n \r\n negative(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v < 0],\r\n errorMessage: message || getMessages().numberNegative\r\n });\r\n }\r\n \r\n nonnegative(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v >= 0],\r\n errorMessage: message || getMessages().numberNonnegative\r\n });\r\n }\r\n \r\n nonpositive(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v <= 0],\r\n errorMessage: message || getMessages().numberNonpositive\r\n });\r\n }\r\n \r\n finite(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => Number.isFinite(v)],\r\n errorMessage: message || getMessages().numberFinite\r\n });\r\n }\r\n \r\n safe(message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => Number.isSafeInteger(v)],\r\n errorMessage: message || getMessages().numberSafe\r\n });\r\n }\r\n \r\n multipleOf(value: number, message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => {\r\n // BUG-004 FIX: Use epsilon comparison for floating point precision (consistent with VldNumber)\r\n const remainder = Math.abs(v % value);\r\n return remainder < Number.EPSILON || Math.abs(remainder - Math.abs(value)) < Number.EPSILON;\r\n }],\r\n errorMessage: message || getMessages().numberMultipleOf(value)\r\n });\r\n }\r\n \r\n step(value: number, message?: string): VldCoerceNumber {\r\n return this.multipleOf(value, message);\r\n }\r\n \r\n between(min: number, max: number, message?: string): VldCoerceNumber {\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => v >= min && v <= max],\r\n errorMessage: message || `Number must be between ${min} and ${max}`\r\n });\r\n }\r\n \r\n even(message?: string): VldCoerceNumber {\r\n // BUG-NEW-007 FIX: Add integer check before even/odd validation\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => {\r\n if (!Number.isInteger(v)) {\r\n return false;\r\n }\r\n return v % 2 === 0;\r\n }],\r\n errorMessage: message || 'Number must be even'\r\n });\r\n }\r\n \r\n odd(message?: string): VldCoerceNumber {\r\n // BUG-NEW-007 FIX: Add integer check before even/odd validation\r\n return new VldCoerceNumber({\r\n checks: [...this.config.checks, (v: number) => {\r\n if (!Number.isInteger(v)) {\r\n return false;\r\n }\r\n return v % 2 !== 0;\r\n }],\r\n errorMessage: message || 'Number must be odd'\r\n });\r\n }\r\n \r\n /**\r\n * Parse and coerce a value to number\r\n */\r\n parse(value: unknown): number {\r\n // If it's already a valid number, use parent validation directly\r\n if (typeof value === 'number' && !isNaN(value)) {\r\n return super.parse(value);\r\n }\r\n \r\n let coerced: number;\r\n \r\n if (typeof value === 'string') {\r\n const trimmed = value.trim();\r\n if (trimmed === '') {\r\n throw new Error(getMessages().coercionFailed('number', value));\r\n }\r\n coerced = Number(trimmed);\r\n if (isNaN(coerced)) {\r\n throw new Error(getMessages().coercionFailed('number', value));\r\n }\r\n } else if (typeof value === 'boolean') {\r\n coerced = value ? 1 : 0;\r\n } else if (value === null || value === undefined) {\r\n throw new Error(getMessages().coercionFailed('number', value));\r\n } else {\r\n coerced = Number(value);\r\n if (isNaN(coerced)) {\r\n throw new Error(getMessages().coercionFailed('number', value));\r\n }\r\n }\r\n \r\n // Use parent validation with coerced value\r\n return super.parse(coerced);\r\n }\r\n \r\n /**\r\n * Safely parse and coerce a value to number\r\n */\r\n safeParse(value: unknown): ParseResult<number> {\r\n try {\r\n return { success: true, data: this.parse(value) };\r\n } catch (error) {\r\n return { success: false, error: error as Error };\r\n }\r\n }\r\n}"]}
@@ -1 +1 @@
1
- {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/coercion/string.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAuFjD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,SAAS,aAAa,MAAM,CAAC,EAAE,GAAG;IAIlC;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,eAAe;IAKhC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQtD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQtD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQzD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQxC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQtC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQvC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQzD,IAAI,IAAI,eAAe;IAQvB,WAAW,IAAI,eAAe;IAQ9B,WAAW,IAAI,eAAe;IAQ9B,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQ1D,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQxD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQxD,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAarC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQvC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAWvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQ3C;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IAyE7B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;CAO/C"}
1
+ {"version":3,"file":"string.d.ts","sourceRoot":"","sources":["../../src/coercion/string.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAOjD;;GAEG;AACH,qBAAa,eAAgB,SAAQ,SAAS;IAC5C,SAAS,aAAa,MAAM,CAAC,EAAE,GAAG;IAIlC;;OAEG;IACH,MAAM,CAAC,MAAM,IAAI,eAAe;IAKhC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQtD,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQtD,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQzD,KAAK,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAUxC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQtC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQvC,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQzD,IAAI,IAAI,eAAe;IAQvB,WAAW,IAAI,eAAe;IAQ9B,WAAW,IAAI,eAAe;IAQ9B,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQ1D,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQxD,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQxD,EAAE,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAarC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQvC,IAAI,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAWvC,QAAQ,CAAC,OAAO,CAAC,EAAE,MAAM,GAAG,eAAe;IAQ3C;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM;IA2E7B;;OAEG;IACH,SAAS,CAAC,KAAK,EAAE,OAAO,GAAG,WAAW,CAAC,MAAM,CAAC;CAO/C"}
@@ -1,76 +1,8 @@
1
1
  import { VldString } from '../validators/string.js';
2
- import { getMessages } from '../locales.js';
3
- /**
4
- * Safe IPv6 validation function (re-implemented to avoid circular dependencies)
5
- */
6
- function isValidIPv6(ip) {
7
- // Length check - IPv6 addresses should be reasonable length
8
- if (ip.length === 0 || ip.length > 64) {
9
- return false;
10
- }
11
- // Allow zone IDs (interface identifiers) by splitting them out
12
- const [ipPart, zoneId] = ip.split('%');
13
- const ipToValidate = zoneId ? ipPart : ip;
14
- // Special handling for IPv4-mapped IPv6 addresses
15
- if (ipToValidate.includes('.')) {
16
- // Check if it's a valid IPv4-mapped IPv6 address pattern
17
- // Pattern should end with a valid IPv4 address after :
18
- const lastColonIndex = ipToValidate.lastIndexOf(':');
19
- if (lastColonIndex === -1)
20
- return false;
21
- const ipv4Part = ipToValidate.substring(lastColonIndex + 1);
22
- const ipv6Part = ipToValidate.substring(0, lastColonIndex);
23
- // Validate IPv4 part
24
- const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;
25
- if (!ipv4Regex.test(ipv4Part))
26
- return false;
27
- // Validate IPv6 part (should end with ::)
28
- if (!ipv6Part.includes('::'))
29
- return false;
30
- return true;
31
- }
32
- // Basic character check - only allow valid IPv6 characters for regular IPv6
33
- if (!/^[0-9a-fA-F:]+$/.test(ipToValidate)) {
34
- return false;
35
- }
36
- // ReDoS prevention: reject extremely long inputs early
37
- if (ipToValidate.length > 45) {
38
- return false;
39
- }
40
- // Check for definitely invalid patterns that could cause issues
41
- if (ipToValidate.includes(':::')) {
42
- return false;
43
- }
44
- // Allow test patterns first - these are guaranteed to be valid IPv6 addresses
45
- const testPatterns = [
46
- '2001:0db8:85a3:0000:0000:8a2e:0370:7334', // Full IPv6
47
- '2001:db8:85a3::8a2e:370:7334', // Compressed
48
- '::1', // Loopback
49
- 'fe80::1ff:fe23:4567:890a', // Link-local
50
- '2001:db8::', // Truncated
51
- '::ffff:192.0.2.1' // IPv4-mapped
52
- ];
53
- if (testPatterns.includes(ipToValidate)) {
54
- return true;
55
- }
56
- // Reject known bad patterns explicitly
57
- const knownBadPatterns = [
58
- 'invalid-ipv6',
59
- '2001:db8:::1', // too many colons
60
- '2001:db8:85a3:0:0:8a2e:370:7334:1234', // too long
61
- 'g01::', // invalid hex characters
62
- '2001:db8::g01' // invalid hex characters
63
- ];
64
- if (knownBadPatterns.includes(ipToValidate)) {
65
- return false;
66
- }
67
- // For any other input that looks like IPv6, be very permissive
68
- // Just check basic structure for security
69
- if (ipToValidate.includes(':') && ipToValidate.length <= 45) {
70
- return true;
71
- }
72
- return false;
73
- }
2
+ import { getMessages } from '../locales/index.js';
3
+ import { isValidIPv6 } from '../utils/ip-validation.js';
4
+ // BUG-NEW-001 FIX: IPv6 validation moved to shared utility (src/utils/ip-validation.ts)
5
+ // to eliminate code duplication between string.ts and coercion/string.ts
74
6
  /**
75
7
  * String coercion validator that attempts to convert values to strings
76
8
  */
@@ -107,8 +39,10 @@ export class VldCoerceString extends VldString {
107
39
  });
108
40
  }
109
41
  email(message) {
42
+ // BUG-007 FIX: Use simpler, ReDoS-safe regex (consistent with VldString)
43
+ const FAST_EMAIL_REGEX = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
110
44
  return new VldCoerceString({
111
- checks: [...this.config.checks, (v) => /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/.test(v)],
45
+ checks: [...this.config.checks, (v) => FAST_EMAIL_REGEX.test(v)],
112
46
  transforms: this.config.transforms,
113
47
  errorMessage: message || getMessages().stringEmail
114
48
  });
@@ -225,6 +159,7 @@ export class VldCoerceString extends VldString {
225
159
  }
226
160
  // Sanitize control characters for security
227
161
  // Remove characters that could cause issues in logs, databases, or UI
162
+ // eslint-disable-next-line no-control-regex -- Intentional removal of control characters for security
228
163
  const sanitized = value.replace(/[\x00-\x1F\x7F]/g, '');
229
164
  // Use parent validation with sanitized string
230
165
  return super.parse(sanitized);
@@ -285,6 +220,7 @@ export class VldCoerceString extends VldString {
285
220
  }
286
221
  // Sanitize control characters for security
287
222
  // Remove characters that could cause issues in logs, databases, or UI
223
+ // eslint-disable-next-line no-control-regex -- Intentional removal of control characters for security
288
224
  const sanitized = coerced.replace(/[\x00-\x1F\x7F]/g, '');
289
225
  // Use parent validation with sanitized value
290
226
  return super.parse(sanitized);
@@ -1 +1 @@
1
- {"version":3,"file":"string.js","sourceRoot":"","sources":["../../src/coercion/string.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldString } from '../validators/string';\r\nimport { ParseResult } from '../validators/base';\r\nimport { getMessages } from '../locales';\r\n\r\n/**\r\n * Safe IPv6 validation function (re-implemented to avoid circular dependencies)\r\n */\r\nfunction isValidIPv6(ip: string): boolean {\r\n // Length check - IPv6 addresses should be reasonable length\r\n if (ip.length === 0 || ip.length > 64) {\r\n return false;\r\n }\r\n\r\n // Allow zone IDs (interface identifiers) by splitting them out\r\n const [ipPart, zoneId] = ip.split('%');\r\n const ipToValidate = zoneId ? ipPart : ip;\r\n\r\n // Special handling for IPv4-mapped IPv6 addresses\r\n if (ipToValidate.includes('.')) {\r\n // Check if it's a valid IPv4-mapped IPv6 address pattern\r\n // Pattern should end with a valid IPv4 address after :\r\n const lastColonIndex = ipToValidate.lastIndexOf(':');\r\n if (lastColonIndex === -1) return false;\r\n\r\n const ipv4Part = ipToValidate.substring(lastColonIndex + 1);\r\n const ipv6Part = ipToValidate.substring(0, lastColonIndex);\r\n\r\n // Validate IPv4 part\r\n const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\r\n if (!ipv4Regex.test(ipv4Part)) return false;\r\n\r\n // Validate IPv6 part (should end with ::)\r\n if (!ipv6Part.includes('::')) return false;\r\n\r\n return true;\r\n }\r\n\r\n // Basic character check - only allow valid IPv6 characters for regular IPv6\r\n if (!/^[0-9a-fA-F:]+$/.test(ipToValidate)) {\r\n return false;\r\n }\r\n\r\n // ReDoS prevention: reject extremely long inputs early\r\n if (ipToValidate.length > 45) {\r\n return false;\r\n }\r\n\r\n // Check for definitely invalid patterns that could cause issues\r\n if (ipToValidate.includes(':::')) {\r\n return false;\r\n }\r\n\r\n // Allow test patterns first - these are guaranteed to be valid IPv6 addresses\r\n const testPatterns = [\r\n '2001:0db8:85a3:0000:0000:8a2e:0370:7334', // Full IPv6\r\n '2001:db8:85a3::8a2e:370:7334', // Compressed\r\n '::1', // Loopback\r\n 'fe80::1ff:fe23:4567:890a', // Link-local\r\n '2001:db8::', // Truncated\r\n '::ffff:192.0.2.1' // IPv4-mapped\r\n ];\r\n\r\n if (testPatterns.includes(ipToValidate)) {\r\n return true;\r\n }\r\n\r\n // Reject known bad patterns explicitly\r\n const knownBadPatterns = [\r\n 'invalid-ipv6',\r\n '2001:db8:::1', // too many colons\r\n '2001:db8:85a3:0:0:8a2e:370:7334:1234', // too long\r\n 'g01::', // invalid hex characters\r\n '2001:db8::g01' // invalid hex characters\r\n ];\r\n\r\n if (knownBadPatterns.includes(ipToValidate)) {\r\n return false;\r\n }\r\n\r\n // For any other input that looks like IPv6, be very permissive\r\n // Just check basic structure for security\r\n if (ipToValidate.includes(':') && ipToValidate.length <= 45) {\r\n return true;\r\n }\r\n\r\n return false;\r\n}\r\n\r\n/**\r\n * String coercion validator that attempts to convert values to strings\r\n */\r\nexport class VldCoerceString extends VldString {\r\n protected constructor(config?: any) {\r\n super(config);\r\n }\r\n \r\n /**\r\n * Create a new coerce string validator\r\n */\r\n static create(): VldCoerceString {\r\n return new VldCoerceString();\r\n }\r\n \r\n // Override all chain methods to return VldCoerceString instances\r\n min(length: number, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length >= length],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringMin(length)\r\n });\r\n }\r\n \r\n max(length: number, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length <= length],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringMax(length)\r\n });\r\n }\r\n \r\n length(length: number, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length === length],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringLength(length)\r\n });\r\n }\r\n \r\n email(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+$/.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringEmail\r\n });\r\n }\r\n \r\n url(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringUrl\r\n });\r\n }\r\n \r\n uuid(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringUuid\r\n });\r\n }\r\n \r\n regex(pattern: RegExp, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => pattern.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringRegex\r\n });\r\n }\r\n \r\n trim(): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: this.config.checks,\r\n transforms: [...this.config.transforms, (v: string) => v.trim()],\r\n errorMessage: this.config.errorMessage\r\n });\r\n }\r\n \r\n toLowerCase(): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: this.config.checks,\r\n transforms: [...this.config.transforms, (v: string) => v.toLowerCase()],\r\n errorMessage: this.config.errorMessage\r\n });\r\n }\r\n \r\n toUpperCase(): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: this.config.checks,\r\n transforms: [...this.config.transforms, (v: string) => v.toUpperCase()],\r\n errorMessage: this.config.errorMessage\r\n });\r\n }\r\n \r\n startsWith(str: string, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.startsWith(str)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringStartsWith(str)\r\n });\r\n }\r\n \r\n endsWith(str: string, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.endsWith(str)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringEndsWith(str)\r\n });\r\n }\r\n \r\n includes(str: string, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.includes(str)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIncludes(str)\r\n });\r\n }\r\n \r\n ip(message?: string): VldCoerceString {\r\n const ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => {\r\n // Prevent ReDoS: Check length before validation\r\n if (v.length > 100) return false;\r\n return ipv4.test(v) || isValidIPv6(v);\r\n }],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIp\r\n });\r\n }\r\n \r\n ipv4(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIpv4\r\n });\r\n }\r\n \r\n ipv6(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => {\r\n // Use safe IPv6 validation to prevent ReDoS attacks\r\n return isValidIPv6(v);\r\n }],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIpv6\r\n });\r\n }\r\n \r\n nonempty(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length > 0],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringEmpty\r\n });\r\n }\r\n \r\n /**\r\n * Parse and coerce a value to string\r\n */\r\n parse(value: unknown): string {\r\n // If it's already a string, apply security controls first\r\n if (typeof value === 'string') {\r\n // Enforce length limits to prevent DoS\r\n if (value.length > 1000000) {\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n }\r\n\r\n // Sanitize control characters for security\r\n // Remove characters that could cause issues in logs, databases, or UI\r\n const sanitized = value.replace(/[\\x00-\\x1F\\x7F]/g, '');\r\n\r\n // Use parent validation with sanitized string\r\n return super.parse(sanitized);\r\n }\r\n\r\n // Handle null and undefined explicitly\r\n if (value === null || value === undefined) {\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n }\r\n\r\n // Safe type coercion with security measures\r\n let coerced: string;\r\n\r\n if (typeof value === 'number') {\r\n // Numbers: safe conversion\r\n coerced = String(value);\r\n } else if (typeof value === 'boolean') {\r\n // Booleans: safe conversion\r\n coerced = value ? 'true' : 'false';\r\n } else if (typeof value === 'bigint') {\r\n // BigInt: safe conversion\r\n coerced = value.toString();\r\n } else if (typeof value === 'symbol') {\r\n // Symbols: explicit error to prevent potential issues\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n } else if (typeof value === 'object') {\r\n // Objects: only allow specific safe object types\r\n if (value instanceof Date) {\r\n // Dates: convert to ISO string\r\n coerced = value.toISOString();\r\n } else if (Array.isArray(value)) {\r\n // Arrays: convert to comma-separated string (original behavior)\r\n coerced = value.join(',');\r\n } else if (value instanceof RegExp) {\r\n // RegExp: convert to string representation\r\n coerced = value.toString();\r\n } else if (value instanceof Error) {\r\n // Errors: use message property (safe)\r\n coerced = value.message || value.toString();\r\n } else {\r\n // For plain objects, use the original String() behavior for backwards compatibility\r\n coerced = String(value);\r\n }\r\n } else {\r\n // Fallback for other types\r\n coerced = String(value);\r\n }\r\n\r\n // Apply security controls\r\n // Enforce length limits to prevent DoS\r\n if (coerced.length > 1000000) {\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n }\r\n\r\n // Sanitize control characters for security\r\n // Remove characters that could cause issues in logs, databases, or UI\r\n const sanitized = coerced.replace(/[\\x00-\\x1F\\x7F]/g, '');\r\n\r\n // Use parent validation with sanitized value\r\n return super.parse(sanitized);\r\n }\r\n \r\n /**\r\n * Safely parse and coerce a value to string\r\n */\r\n safeParse(value: unknown): ParseResult<string> {\r\n try {\r\n return { success: true, data: this.parse(value) };\r\n } catch (error) {\r\n return { success: false, error: error as Error };\r\n }\r\n }\r\n}"]}
1
+ {"version":3,"file":"string.js","sourceRoot":"","sources":["../../src/coercion/string.ts"],"names":[],"mappings":"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","sourcesContent":["import { VldString } from '../validators/string';\r\nimport { ParseResult } from '../validators/base';\r\nimport { getMessages } from '../locales';\r\nimport { isValidIPv6 } from '../utils/ip-validation';\r\n\r\n// BUG-NEW-001 FIX: IPv6 validation moved to shared utility (src/utils/ip-validation.ts)\r\n// to eliminate code duplication between string.ts and coercion/string.ts\r\n\r\n/**\r\n * String coercion validator that attempts to convert values to strings\r\n */\r\nexport class VldCoerceString extends VldString {\r\n protected constructor(config?: any) {\r\n super(config);\r\n }\r\n \r\n /**\r\n * Create a new coerce string validator\r\n */\r\n static create(): VldCoerceString {\r\n return new VldCoerceString();\r\n }\r\n \r\n // Override all chain methods to return VldCoerceString instances\r\n min(length: number, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length >= length],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringMin(length)\r\n });\r\n }\r\n \r\n max(length: number, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length <= length],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringMax(length)\r\n });\r\n }\r\n \r\n length(length: number, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length === length],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringLength(length)\r\n });\r\n }\r\n \r\n email(message?: string): VldCoerceString {\r\n // BUG-007 FIX: Use simpler, ReDoS-safe regex (consistent with VldString)\r\n const FAST_EMAIL_REGEX = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => FAST_EMAIL_REGEX.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringEmail\r\n });\r\n }\r\n \r\n url(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^https?:\\/\\/(www\\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\\.[a-zA-Z0-9()]{1,6}\\b([-a-zA-Z0-9()@:%_+.~#?&//=]*)$/.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringUrl\r\n });\r\n }\r\n \r\n uuid(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringUuid\r\n });\r\n }\r\n \r\n regex(pattern: RegExp, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => pattern.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringRegex\r\n });\r\n }\r\n \r\n trim(): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: this.config.checks,\r\n transforms: [...this.config.transforms, (v: string) => v.trim()],\r\n errorMessage: this.config.errorMessage\r\n });\r\n }\r\n \r\n toLowerCase(): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: this.config.checks,\r\n transforms: [...this.config.transforms, (v: string) => v.toLowerCase()],\r\n errorMessage: this.config.errorMessage\r\n });\r\n }\r\n \r\n toUpperCase(): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: this.config.checks,\r\n transforms: [...this.config.transforms, (v: string) => v.toUpperCase()],\r\n errorMessage: this.config.errorMessage\r\n });\r\n }\r\n \r\n startsWith(str: string, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.startsWith(str)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringStartsWith(str)\r\n });\r\n }\r\n \r\n endsWith(str: string, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.endsWith(str)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringEndsWith(str)\r\n });\r\n }\r\n \r\n includes(str: string, message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.includes(str)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIncludes(str)\r\n });\r\n }\r\n \r\n ip(message?: string): VldCoerceString {\r\n const ipv4 = /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/;\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => {\r\n // Prevent ReDoS: Check length before validation\r\n if (v.length > 100) return false;\r\n return ipv4.test(v) || isValidIPv6(v);\r\n }],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIp\r\n });\r\n }\r\n \r\n ipv4(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => /^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(v)],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIpv4\r\n });\r\n }\r\n \r\n ipv6(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => {\r\n // Use safe IPv6 validation to prevent ReDoS attacks\r\n return isValidIPv6(v);\r\n }],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringIpv6\r\n });\r\n }\r\n \r\n nonempty(message?: string): VldCoerceString {\r\n return new VldCoerceString({\r\n checks: [...this.config.checks, (v: string) => v.length > 0],\r\n transforms: this.config.transforms,\r\n errorMessage: message || getMessages().stringEmpty\r\n });\r\n }\r\n \r\n /**\r\n * Parse and coerce a value to string\r\n */\r\n parse(value: unknown): string {\r\n // If it's already a string, apply security controls first\r\n if (typeof value === 'string') {\r\n // Enforce length limits to prevent DoS\r\n if (value.length > 1000000) {\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n }\r\n\r\n // Sanitize control characters for security\r\n // Remove characters that could cause issues in logs, databases, or UI\r\n // eslint-disable-next-line no-control-regex -- Intentional removal of control characters for security\r\n const sanitized = value.replace(/[\\x00-\\x1F\\x7F]/g, '');\r\n\r\n // Use parent validation with sanitized string\r\n return super.parse(sanitized);\r\n }\r\n\r\n // Handle null and undefined explicitly\r\n if (value === null || value === undefined) {\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n }\r\n\r\n // Safe type coercion with security measures\r\n let coerced: string;\r\n\r\n if (typeof value === 'number') {\r\n // Numbers: safe conversion\r\n coerced = String(value);\r\n } else if (typeof value === 'boolean') {\r\n // Booleans: safe conversion\r\n coerced = value ? 'true' : 'false';\r\n } else if (typeof value === 'bigint') {\r\n // BigInt: safe conversion\r\n coerced = value.toString();\r\n } else if (typeof value === 'symbol') {\r\n // Symbols: explicit error to prevent potential issues\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n } else if (typeof value === 'object') {\r\n // Objects: only allow specific safe object types\r\n if (value instanceof Date) {\r\n // Dates: convert to ISO string\r\n coerced = value.toISOString();\r\n } else if (Array.isArray(value)) {\r\n // Arrays: convert to comma-separated string (original behavior)\r\n coerced = value.join(',');\r\n } else if (value instanceof RegExp) {\r\n // RegExp: convert to string representation\r\n coerced = value.toString();\r\n } else if (value instanceof Error) {\r\n // Errors: use message property (safe)\r\n coerced = value.message || value.toString();\r\n } else {\r\n // For plain objects, use the original String() behavior for backwards compatibility\r\n coerced = String(value);\r\n }\r\n } else {\r\n // Fallback for other types\r\n coerced = String(value);\r\n }\r\n\r\n // Apply security controls\r\n // Enforce length limits to prevent DoS\r\n if (coerced.length > 1000000) {\r\n throw new Error(getMessages().coercionFailed('string', value));\r\n }\r\n\r\n // Sanitize control characters for security\r\n // Remove characters that could cause issues in logs, databases, or UI\r\n // eslint-disable-next-line no-control-regex -- Intentional removal of control characters for security\r\n const sanitized = coerced.replace(/[\\x00-\\x1F\\x7F]/g, '');\r\n\r\n // Use parent validation with sanitized value\r\n return super.parse(sanitized);\r\n }\r\n \r\n /**\r\n * Safely parse and coerce a value to string\r\n */\r\n safeParse(value: unknown): ParseResult<string> {\r\n try {\r\n return { success: true, data: this.parse(value) };\r\n } catch (error) {\r\n return { success: false, error: error as Error };\r\n }\r\n }\r\n}"]}