@oxog/vld 2.0.2 → 2.1.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 (450) hide show
  1. package/CHANGELOG.md +75 -1
  2. package/LICENSE +20 -20
  3. package/README.md +101 -37
  4. package/dist/chunks/errors-core-BeiFUtZM.js +81 -0
  5. package/dist/chunks/{index-CETyGkrv.js → index-0R2ntSud.js} +16 -402
  6. package/dist/chunks/index-BvH403Yy.js +88 -0
  7. package/dist/chunks/security-B0Pd_vSY.js +35 -0
  8. package/dist/chunks/string-BJRQod3t.js +530 -0
  9. package/dist/cjs/chunks/errors-core-DWxLFs2f.cjs +83 -0
  10. package/dist/cjs/chunks/index-BkI37108.cjs +538 -0
  11. package/dist/cjs/chunks/index-Cc3bjUMX.cjs +91 -0
  12. package/dist/cjs/chunks/security-Dc3Jh13T.cjs +37 -0
  13. package/dist/cjs/chunks/string-BKZrc4hs.cjs +533 -0
  14. package/dist/cjs/cli/bin.cjs +506 -0
  15. package/dist/cjs/cli/index.cjs +209 -0
  16. package/dist/cjs/codecs/index.cjs +45 -0
  17. package/dist/{chunks/date-ODue_rtq.js → cjs/coercion/index.cjs} +185 -103
  18. package/dist/cjs/compat/emitter.cjs +184 -0
  19. package/dist/cjs/compat/result.cjs +189 -0
  20. package/dist/cjs/errors.cjs +6 -213
  21. package/dist/cjs/index.cjs +1558 -9647
  22. package/dist/cjs/kernel.cjs +415 -0
  23. package/dist/cjs/locales/af.cjs +108 -0
  24. package/dist/cjs/locales/ar.cjs +108 -0
  25. package/dist/cjs/locales/bn.cjs +108 -0
  26. package/dist/cjs/locales/da.cjs +108 -0
  27. package/dist/cjs/locales/de.cjs +108 -0
  28. package/dist/cjs/locales/en.cjs +108 -0
  29. package/dist/cjs/locales/es-MX.cjs +107 -0
  30. package/dist/cjs/locales/es.cjs +96 -0
  31. package/dist/cjs/locales/fi.cjs +108 -0
  32. package/dist/cjs/locales/fr.cjs +96 -0
  33. package/dist/cjs/locales/hi.cjs +108 -0
  34. package/dist/cjs/locales/id.cjs +108 -0
  35. package/dist/cjs/locales/index.cjs +41 -2875
  36. package/dist/cjs/locales/it.cjs +108 -0
  37. package/dist/cjs/locales/ja.cjs +108 -0
  38. package/dist/cjs/locales/ko.cjs +108 -0
  39. package/dist/cjs/locales/lazy.cjs +42 -3023
  40. package/dist/cjs/locales/nl.cjs +108 -0
  41. package/dist/cjs/locales/no.cjs +108 -0
  42. package/dist/cjs/locales/pl.cjs +108 -0
  43. package/dist/cjs/locales/pt-BR.cjs +108 -0
  44. package/dist/cjs/locales/pt.cjs +108 -0
  45. package/dist/cjs/locales/ru.cjs +108 -0
  46. package/dist/cjs/locales/runtime.cjs +51 -0
  47. package/dist/cjs/locales/sv.cjs +108 -0
  48. package/dist/cjs/locales/sw.cjs +108 -0
  49. package/dist/cjs/locales/th.cjs +108 -0
  50. package/dist/cjs/locales/tr.cjs +108 -0
  51. package/dist/cjs/locales/vi.cjs +108 -0
  52. package/dist/cjs/locales/zh.cjs +108 -0
  53. package/dist/cjs/mini.cjs +121 -7208
  54. package/dist/cjs/pigment.cjs +207 -0
  55. package/dist/cjs/plugins/index.cjs +12 -0
  56. package/dist/cjs/registry.cjs +37 -0
  57. package/dist/cjs/v3/index.cjs +425 -0
  58. package/dist/cjs/v4/core/index.cjs +894 -0
  59. package/dist/cjs/v4/index.cjs +425 -0
  60. package/dist/cjs/v4/locales/index.cjs +130 -0
  61. package/dist/cjs/v4/mini/index.cjs +509 -0
  62. package/dist/cjs/v4-mini/index.cjs +532 -0
  63. package/dist/cjs/validators/any.cjs +40 -0
  64. package/dist/cjs/validators/array.cjs +283 -0
  65. package/dist/cjs/validators/base.cjs +887 -0
  66. package/dist/cjs/validators/base64.cjs +73 -0
  67. package/dist/cjs/validators/bigint.cjs +232 -0
  68. package/dist/cjs/validators/boolean.cjs +146 -0
  69. package/dist/cjs/validators/codec.cjs +205 -0
  70. package/dist/cjs/validators/custom.cjs +71 -0
  71. package/dist/cjs/validators/date.cjs +278 -0
  72. package/dist/cjs/validators/discriminated-union.cjs +130 -0
  73. package/dist/cjs/validators/enum.cjs +154 -0
  74. package/dist/cjs/validators/file.cjs +130 -0
  75. package/dist/cjs/validators/function.cjs +63 -0
  76. package/dist/cjs/validators/hex.cjs +70 -0
  77. package/dist/cjs/validators/index.cjs +123 -0
  78. package/dist/cjs/validators/intersection.cjs +120 -0
  79. package/dist/cjs/validators/json.cjs +70 -0
  80. package/dist/cjs/validators/lazy.cjs +53 -0
  81. package/dist/cjs/validators/literal.cjs +64 -0
  82. package/dist/cjs/validators/map.cjs +218 -0
  83. package/dist/cjs/validators/nan.cjs +41 -0
  84. package/dist/cjs/validators/never.cjs +36 -0
  85. package/dist/cjs/validators/null.cjs +43 -0
  86. package/dist/cjs/validators/number.cjs +427 -0
  87. package/dist/cjs/validators/object.cjs +868 -0
  88. package/dist/cjs/validators/promise.cjs +115 -0
  89. package/dist/cjs/validators/record.cjs +262 -0
  90. package/dist/cjs/validators/set.cjs +203 -0
  91. package/dist/cjs/validators/string-bool.cjs +124 -0
  92. package/dist/cjs/validators/string-formats.cjs +168 -0
  93. package/dist/cjs/validators/string.cjs +12 -0
  94. package/dist/cjs/validators/symbol.cjs +62 -0
  95. package/dist/cjs/validators/template-literal.cjs +108 -0
  96. package/dist/cjs/validators/tuple.cjs +187 -0
  97. package/dist/cjs/validators/uint8array.cjs +106 -0
  98. package/dist/cjs/validators/undefined.cjs +43 -0
  99. package/dist/cjs/validators/union.cjs +191 -0
  100. package/dist/cjs/validators/unknown.cjs +40 -0
  101. package/dist/cjs/validators/void.cjs +48 -0
  102. package/dist/cjs/validators/xor.cjs +69 -0
  103. package/dist/cli/bin.d.ts +0 -1
  104. package/dist/cli/bin.js +407 -0
  105. package/dist/cli/commands/benchmark.d.ts +1 -2
  106. package/dist/cli/commands/validate.d.ts +1 -2
  107. package/dist/cli/index.d.ts +0 -1
  108. package/dist/cli/index.js +205 -0
  109. package/dist/codecs/index.d.ts +21 -4
  110. package/dist/codecs/index.js +11 -4
  111. package/dist/coercion/bigint.d.ts +2 -3
  112. package/dist/coercion/boolean.d.ts +3 -3
  113. package/dist/coercion/date.d.ts +3 -3
  114. package/dist/coercion/index.d.ts +5 -6
  115. package/dist/coercion/index.js +473 -5
  116. package/dist/coercion/number.d.ts +2 -3
  117. package/dist/coercion/string.d.ts +2 -3
  118. package/dist/compat/emitter.d.ts +0 -1
  119. package/dist/compat/emitter.js +0 -1
  120. package/dist/compat/index.d.ts +4 -5
  121. package/dist/compat/result.d.ts +1 -2
  122. package/dist/compat/result.js +0 -1
  123. package/dist/errors-core.d.ts +39 -0
  124. package/dist/errors.d.ts +4 -54
  125. package/dist/errors.js +4 -68
  126. package/dist/events.d.ts +3 -4
  127. package/dist/index.d.ts +1195 -600
  128. package/dist/index.js +1262 -44
  129. package/dist/kernel.d.ts +2 -3
  130. package/dist/kernel.js +10 -6
  131. package/dist/locales/af.d.ts +1 -2
  132. package/dist/locales/af.js +0 -1
  133. package/dist/locales/ar.d.ts +1 -2
  134. package/dist/locales/ar.js +0 -1
  135. package/dist/locales/bn.d.ts +1 -2
  136. package/dist/locales/bn.js +0 -1
  137. package/dist/locales/da.d.ts +1 -2
  138. package/dist/locales/da.js +0 -1
  139. package/dist/locales/de.d.ts +1 -2
  140. package/dist/locales/de.js +0 -1
  141. package/dist/locales/en.d.ts +1 -2
  142. package/dist/locales/en.js +0 -1
  143. package/dist/locales/es-MX.d.ts +1 -2
  144. package/dist/locales/es-MX.js +0 -1
  145. package/dist/locales/es.d.ts +1 -2
  146. package/dist/locales/es.js +0 -1
  147. package/dist/locales/fi.d.ts +1 -2
  148. package/dist/locales/fi.js +0 -1
  149. package/dist/locales/fr.d.ts +1 -2
  150. package/dist/locales/fr.js +0 -1
  151. package/dist/locales/hi.d.ts +1 -2
  152. package/dist/locales/hi.js +0 -1
  153. package/dist/locales/id.d.ts +1 -2
  154. package/dist/locales/id.js +0 -1
  155. package/dist/locales/index.d.ts +10 -15
  156. package/dist/locales/index.js +28 -2
  157. package/dist/locales/it.d.ts +1 -2
  158. package/dist/locales/it.js +0 -1
  159. package/dist/locales/ja.d.ts +1 -2
  160. package/dist/locales/ja.js +0 -1
  161. package/dist/locales/ko.d.ts +1 -2
  162. package/dist/locales/ko.js +0 -1
  163. package/dist/locales/lazy.d.ts +4 -26
  164. package/dist/locales/lazy.js +12 -55
  165. package/dist/locales/nl.d.ts +1 -2
  166. package/dist/locales/nl.js +0 -1
  167. package/dist/locales/no.d.ts +1 -2
  168. package/dist/locales/no.js +0 -1
  169. package/dist/locales/pl.d.ts +1 -2
  170. package/dist/locales/pl.js +0 -1
  171. package/dist/locales/pt-BR.d.ts +1 -2
  172. package/dist/locales/pt-BR.js +0 -1
  173. package/dist/locales/pt.d.ts +1 -2
  174. package/dist/locales/pt.js +0 -1
  175. package/dist/locales/ru.d.ts +1 -2
  176. package/dist/locales/ru.js +0 -1
  177. package/dist/locales/runtime.d.ts +10 -0
  178. package/dist/locales/runtime.js +41 -0
  179. package/dist/locales/sv.d.ts +1 -2
  180. package/dist/locales/sv.js +0 -1
  181. package/dist/locales/sw.d.ts +1 -2
  182. package/dist/locales/sw.js +0 -1
  183. package/dist/locales/th.d.ts +1 -2
  184. package/dist/locales/th.js +0 -1
  185. package/dist/locales/tr.d.ts +1 -2
  186. package/dist/locales/tr.js +0 -1
  187. package/dist/locales/types.d.ts +0 -1
  188. package/dist/locales/vi.d.ts +1 -2
  189. package/dist/locales/vi.js +0 -1
  190. package/dist/locales/zh.d.ts +1 -2
  191. package/dist/locales/zh.js +0 -1
  192. package/dist/logger.d.ts +0 -1
  193. package/dist/mini.d.ts +64 -65
  194. package/dist/mini.js +31 -7
  195. package/dist/pigment.d.ts +0 -1
  196. package/dist/pigment.js +6 -4
  197. package/dist/plugins/index.d.ts +2 -3
  198. package/dist/plugins/index.js +1 -0
  199. package/dist/plugins/types.d.ts +4 -5
  200. package/dist/registry.d.ts +23 -0
  201. package/dist/registry.js +34 -0
  202. package/dist/utils/codec-utils.d.ts +0 -1
  203. package/dist/utils/deep-merge.d.ts +0 -1
  204. package/dist/utils/ip-validation.d.ts +0 -1
  205. package/dist/utils/json-schema.d.ts +77 -0
  206. package/dist/utils/security.d.ts +2 -6
  207. package/dist/v3/index.d.ts +2 -0
  208. package/dist/v3/index.js +46 -0
  209. package/dist/v4/core/index.d.ts +260 -0
  210. package/dist/v4/core/index.js +277 -0
  211. package/dist/v4/index.d.ts +4 -0
  212. package/dist/v4/index.js +50 -0
  213. package/dist/v4/locales/index.d.ts +53 -0
  214. package/dist/v4/locales/index.js +77 -0
  215. package/dist/v4/mini/index.d.ts +2 -0
  216. package/dist/v4/mini/index.js +47 -0
  217. package/dist/v4-mini/index.d.ts +22 -0
  218. package/dist/v4-mini/index.js +75 -0
  219. package/dist/validators/any.d.ts +7 -2
  220. package/dist/validators/any.js +37 -0
  221. package/dist/validators/array.d.ts +9 -2
  222. package/dist/validators/array.js +279 -0
  223. package/dist/validators/base.d.ts +228 -5
  224. package/dist/validators/base.js +868 -0
  225. package/dist/validators/base64.d.ts +1 -2
  226. package/dist/validators/base64.js +68 -0
  227. package/dist/validators/bigint.d.ts +21 -3
  228. package/dist/validators/bigint.js +228 -0
  229. package/dist/validators/boolean.d.ts +13 -4
  230. package/dist/validators/boolean.js +142 -0
  231. package/dist/validators/codec.d.ts +9 -2
  232. package/dist/validators/codec.js +200 -0
  233. package/dist/validators/custom.d.ts +15 -2
  234. package/dist/validators/custom.js +67 -0
  235. package/dist/validators/date.d.ts +19 -3
  236. package/dist/validators/date.js +274 -0
  237. package/dist/validators/discriminated-union.d.ts +4 -3
  238. package/dist/validators/discriminated-union.js +123 -0
  239. package/dist/validators/enum.d.ts +10 -7
  240. package/dist/validators/enum.js +150 -0
  241. package/dist/validators/file.d.ts +7 -2
  242. package/dist/validators/file.js +125 -0
  243. package/dist/validators/function.d.ts +11 -5
  244. package/dist/validators/function.js +58 -0
  245. package/dist/validators/hex.d.ts +1 -2
  246. package/dist/validators/hex.js +65 -0
  247. package/dist/validators/index.d.ts +38 -38
  248. package/dist/validators/index.js +35 -5
  249. package/dist/validators/intersection.d.ts +1 -2
  250. package/dist/validators/intersection.js +116 -0
  251. package/dist/validators/json.d.ts +1 -2
  252. package/dist/validators/json.js +66 -0
  253. package/dist/validators/lazy.d.ts +5 -9
  254. package/dist/validators/lazy.js +50 -0
  255. package/dist/validators/literal.d.ts +2 -2
  256. package/dist/validators/literal.js +60 -0
  257. package/dist/validators/map.d.ts +15 -2
  258. package/dist/validators/map.js +214 -0
  259. package/dist/validators/nan.d.ts +2 -3
  260. package/dist/validators/nan.js +38 -0
  261. package/dist/validators/never.d.ts +1 -2
  262. package/dist/validators/never.js +32 -0
  263. package/dist/validators/null.d.ts +3 -3
  264. package/dist/validators/null.js +40 -0
  265. package/dist/validators/number.d.ts +80 -21
  266. package/dist/validators/number.js +423 -0
  267. package/dist/validators/object.d.ts +30 -9
  268. package/dist/validators/object.js +864 -0
  269. package/dist/validators/promise.d.ts +58 -0
  270. package/dist/validators/promise.js +111 -0
  271. package/dist/validators/record.d.ts +11 -2
  272. package/dist/validators/record.js +258 -0
  273. package/dist/validators/set.d.ts +11 -2
  274. package/dist/validators/set.js +199 -0
  275. package/dist/validators/string-bool.d.ts +7 -10
  276. package/dist/validators/string-bool.js +120 -0
  277. package/dist/validators/string-formats.d.ts +13 -4
  278. package/dist/validators/string-formats.js +135 -0
  279. package/dist/validators/string.d.ts +39 -18
  280. package/dist/validators/string.js +4 -0
  281. package/dist/validators/symbol.d.ts +8 -3
  282. package/dist/validators/symbol.js +58 -0
  283. package/dist/validators/template-literal.d.ts +1 -2
  284. package/dist/validators/template-literal.js +103 -0
  285. package/dist/validators/tuple.d.ts +15 -2
  286. package/dist/validators/tuple.js +183 -0
  287. package/dist/validators/uint8array.d.ts +3 -4
  288. package/dist/validators/uint8array.js +101 -0
  289. package/dist/validators/undefined.d.ts +3 -3
  290. package/dist/validators/undefined.js +40 -0
  291. package/dist/validators/union.d.ts +7 -4
  292. package/dist/validators/union.js +187 -0
  293. package/dist/validators/unknown.d.ts +7 -2
  294. package/dist/{chunks/unknown-SLIH1VCf.js → validators/unknown.js} +12 -3
  295. package/dist/validators/void.d.ts +3 -2
  296. package/dist/validators/void.js +44 -0
  297. package/dist/validators/xor.d.ts +2 -3
  298. package/dist/validators/xor.js +66 -0
  299. package/package.json +116 -31
  300. package/dist/chunks/bigint-DgsCr2dC.js +0 -1709
  301. package/dist/chunks/bigint-DgsCr2dC.js.map +0 -1
  302. package/dist/chunks/date-ODue_rtq.js.map +0 -1
  303. package/dist/chunks/index-BZqWZvVe.js +0 -426
  304. package/dist/chunks/index-BZqWZvVe.js.map +0 -1
  305. package/dist/chunks/index-CETyGkrv.js.map +0 -1
  306. package/dist/chunks/json-o20GFhTh.js +0 -2021
  307. package/dist/chunks/json-o20GFhTh.js.map +0 -1
  308. package/dist/chunks/unknown-SLIH1VCf.js.map +0 -1
  309. package/dist/cjs/errors.cjs.map +0 -1
  310. package/dist/cjs/index.cjs.map +0 -1
  311. package/dist/cjs/locales/index.cjs.map +0 -1
  312. package/dist/cjs/locales/lazy.cjs.map +0 -1
  313. package/dist/cjs/mini.cjs.map +0 -1
  314. package/dist/cli/bin.d.ts.map +0 -1
  315. package/dist/cli/commands/benchmark.d.ts.map +0 -1
  316. package/dist/cli/commands/validate.d.ts.map +0 -1
  317. package/dist/cli/index.d.ts.map +0 -1
  318. package/dist/codecs/index.d.ts.map +0 -1
  319. package/dist/codecs/index.js.map +0 -1
  320. package/dist/coercion/bigint.d.ts.map +0 -1
  321. package/dist/coercion/boolean.d.ts.map +0 -1
  322. package/dist/coercion/date.d.ts.map +0 -1
  323. package/dist/coercion/index.d.ts.map +0 -1
  324. package/dist/coercion/index.js.map +0 -1
  325. package/dist/coercion/number.d.ts.map +0 -1
  326. package/dist/coercion/string.d.ts.map +0 -1
  327. package/dist/compat/emitter.d.ts.map +0 -1
  328. package/dist/compat/emitter.js.map +0 -1
  329. package/dist/compat/index.d.ts.map +0 -1
  330. package/dist/compat/result.d.ts.map +0 -1
  331. package/dist/compat/result.js.map +0 -1
  332. package/dist/errors.d.ts.map +0 -1
  333. package/dist/errors.js.map +0 -1
  334. package/dist/events.d.ts.map +0 -1
  335. package/dist/index.d.ts.map +0 -1
  336. package/dist/index.js.map +0 -1
  337. package/dist/kernel.d.ts.map +0 -1
  338. package/dist/kernel.js.map +0 -1
  339. package/dist/locales/af.d.ts.map +0 -1
  340. package/dist/locales/af.js.map +0 -1
  341. package/dist/locales/ar.d.ts.map +0 -1
  342. package/dist/locales/ar.js.map +0 -1
  343. package/dist/locales/backup-en.d.ts +0 -3
  344. package/dist/locales/backup-en.d.ts.map +0 -1
  345. package/dist/locales/bn.d.ts.map +0 -1
  346. package/dist/locales/bn.js.map +0 -1
  347. package/dist/locales/da.d.ts.map +0 -1
  348. package/dist/locales/da.js.map +0 -1
  349. package/dist/locales/de.d.ts.map +0 -1
  350. package/dist/locales/de.js.map +0 -1
  351. package/dist/locales/en.d.ts.map +0 -1
  352. package/dist/locales/en.js.map +0 -1
  353. package/dist/locales/es-MX.d.ts.map +0 -1
  354. package/dist/locales/es-MX.js.map +0 -1
  355. package/dist/locales/es.d.ts.map +0 -1
  356. package/dist/locales/es.js.map +0 -1
  357. package/dist/locales/fi.d.ts.map +0 -1
  358. package/dist/locales/fi.js.map +0 -1
  359. package/dist/locales/fr.d.ts.map +0 -1
  360. package/dist/locales/fr.js.map +0 -1
  361. package/dist/locales/hi.d.ts.map +0 -1
  362. package/dist/locales/hi.js.map +0 -1
  363. package/dist/locales/id.d.ts.map +0 -1
  364. package/dist/locales/id.js.map +0 -1
  365. package/dist/locales/index.d.ts.map +0 -1
  366. package/dist/locales/index.js.map +0 -1
  367. package/dist/locales/it.d.ts.map +0 -1
  368. package/dist/locales/it.js.map +0 -1
  369. package/dist/locales/ja.d.ts.map +0 -1
  370. package/dist/locales/ja.js.map +0 -1
  371. package/dist/locales/ko.d.ts.map +0 -1
  372. package/dist/locales/ko.js.map +0 -1
  373. package/dist/locales/lazy.d.ts.map +0 -1
  374. package/dist/locales/lazy.js.map +0 -1
  375. package/dist/locales/nl.d.ts.map +0 -1
  376. package/dist/locales/nl.js.map +0 -1
  377. package/dist/locales/no.d.ts.map +0 -1
  378. package/dist/locales/no.js.map +0 -1
  379. package/dist/locales/pl.d.ts.map +0 -1
  380. package/dist/locales/pl.js.map +0 -1
  381. package/dist/locales/pt-BR.d.ts.map +0 -1
  382. package/dist/locales/pt-BR.js.map +0 -1
  383. package/dist/locales/pt.d.ts.map +0 -1
  384. package/dist/locales/pt.js.map +0 -1
  385. package/dist/locales/ru.d.ts.map +0 -1
  386. package/dist/locales/ru.js.map +0 -1
  387. package/dist/locales/sv.d.ts.map +0 -1
  388. package/dist/locales/sv.js.map +0 -1
  389. package/dist/locales/sw.d.ts.map +0 -1
  390. package/dist/locales/sw.js.map +0 -1
  391. package/dist/locales/th.d.ts.map +0 -1
  392. package/dist/locales/th.js.map +0 -1
  393. package/dist/locales/tr.d.ts.map +0 -1
  394. package/dist/locales/tr.js.map +0 -1
  395. package/dist/locales/types.d.ts.map +0 -1
  396. package/dist/locales/vi.d.ts.map +0 -1
  397. package/dist/locales/vi.js.map +0 -1
  398. package/dist/locales/zh.d.ts.map +0 -1
  399. package/dist/locales/zh.js.map +0 -1
  400. package/dist/logger.d.ts.map +0 -1
  401. package/dist/mini.d.ts.map +0 -1
  402. package/dist/mini.js.map +0 -1
  403. package/dist/pigment.d.ts.map +0 -1
  404. package/dist/pigment.js.map +0 -1
  405. package/dist/plugins/index.d.ts.map +0 -1
  406. package/dist/plugins/types.d.ts.map +0 -1
  407. package/dist/utils/codec-utils.d.ts.map +0 -1
  408. package/dist/utils/deep-merge.d.ts.map +0 -1
  409. package/dist/utils/ip-validation.d.ts.map +0 -1
  410. package/dist/utils/security.d.ts.map +0 -1
  411. package/dist/validators/any.d.ts.map +0 -1
  412. package/dist/validators/array.d.ts.map +0 -1
  413. package/dist/validators/base.d.ts.map +0 -1
  414. package/dist/validators/base64.d.ts.map +0 -1
  415. package/dist/validators/bigint.d.ts.map +0 -1
  416. package/dist/validators/boolean.d.ts.map +0 -1
  417. package/dist/validators/codec.d.ts.map +0 -1
  418. package/dist/validators/custom.d.ts.map +0 -1
  419. package/dist/validators/date.d.ts.map +0 -1
  420. package/dist/validators/discriminated-union.d.ts.map +0 -1
  421. package/dist/validators/enum.d.ts.map +0 -1
  422. package/dist/validators/file.d.ts.map +0 -1
  423. package/dist/validators/function.d.ts.map +0 -1
  424. package/dist/validators/hex.d.ts.map +0 -1
  425. package/dist/validators/index.d.ts.map +0 -1
  426. package/dist/validators/index.js.map +0 -1
  427. package/dist/validators/intersection.d.ts.map +0 -1
  428. package/dist/validators/json.d.ts.map +0 -1
  429. package/dist/validators/lazy.d.ts.map +0 -1
  430. package/dist/validators/literal.d.ts.map +0 -1
  431. package/dist/validators/map.d.ts.map +0 -1
  432. package/dist/validators/nan.d.ts.map +0 -1
  433. package/dist/validators/never.d.ts.map +0 -1
  434. package/dist/validators/null.d.ts.map +0 -1
  435. package/dist/validators/number.d.ts.map +0 -1
  436. package/dist/validators/object.d.ts.map +0 -1
  437. package/dist/validators/record.d.ts.map +0 -1
  438. package/dist/validators/set.d.ts.map +0 -1
  439. package/dist/validators/string-bool.d.ts.map +0 -1
  440. package/dist/validators/string-formats.d.ts.map +0 -1
  441. package/dist/validators/string.d.ts.map +0 -1
  442. package/dist/validators/symbol.d.ts.map +0 -1
  443. package/dist/validators/template-literal.d.ts.map +0 -1
  444. package/dist/validators/tuple.d.ts.map +0 -1
  445. package/dist/validators/uint8array.d.ts.map +0 -1
  446. package/dist/validators/undefined.d.ts.map +0 -1
  447. package/dist/validators/union.d.ts.map +0 -1
  448. package/dist/validators/unknown.d.ts.map +0 -1
  449. package/dist/validators/void.d.ts.map +0 -1
  450. package/dist/validators/xor.d.ts.map +0 -1
@@ -1,2021 +0,0 @@
1
- import { i as VldBase, t as getMessages, V as VldString, a as VldNumber, b as VldBoolean, c as VldDate, e as VldOptional } from './bigint-DgsCr2dC.js';
2
- import { c as VldCoerceString, b as VldCoerceNumber, a as VldCoerceBoolean, V as VldCoerceDate } from './date-ODue_rtq.js';
3
-
4
- /**
5
- * Default truthy and falsy value sets
6
- */
7
- const DEFAULT_TRUTHY = ['true', '1', 'yes', 'on', 'y', 'enabled'];
8
- const DEFAULT_FALSY = ['false', '0', 'no', 'off', 'n', 'disabled'];
9
- /**
10
- * Immutable string boolean validator for flexible boolean parsing
11
- * Supports string representations like "true", "yes", "on", "1", etc.
12
- */
13
- class VldStringBool extends VldBase {
14
- constructor(options) {
15
- super();
16
- this.options = options;
17
- }
18
- /**
19
- * Create a new string boolean validator
20
- */
21
- static create(options = {}) {
22
- return new VldStringBool(options);
23
- }
24
- /**
25
- * Normalize a string value based on case sensitivity setting
26
- */
27
- normalizeValue(value) {
28
- return this.options.caseSensitive ? value : value.toLowerCase();
29
- }
30
- /**
31
- * Get the effective truthy values (custom or default)
32
- */
33
- getTruthyValues() {
34
- return this.options.truthy ?? DEFAULT_TRUTHY;
35
- }
36
- /**
37
- * Get the effective falsy values (custom or default)
38
- */
39
- getFalsyValues() {
40
- return this.options.falsy ?? DEFAULT_FALSY;
41
- }
42
- /**
43
- * Parse and validate a string boolean value
44
- */
45
- parse(value) {
46
- // First, ensure we have a string
47
- if (typeof value !== 'string') {
48
- // Also accept actual boolean values for convenience
49
- if (typeof value === 'boolean') {
50
- return value;
51
- }
52
- throw new Error(getMessages().stringExpected(typeof value, 'string'));
53
- }
54
- const normalized = this.normalizeValue(value);
55
- const truthyValues = this.getTruthyValues();
56
- const falsyValues = this.getFalsyValues();
57
- // Normalize the value sets for comparison
58
- const normalizedTruthy = this.options.caseSensitive
59
- ? truthyValues
60
- : truthyValues.map(v => v.toLowerCase());
61
- const normalizedFalsy = this.options.caseSensitive
62
- ? falsyValues
63
- : falsyValues.map(v => v.toLowerCase());
64
- // Check if value is in truthy set
65
- if (normalizedTruthy.includes(normalized)) {
66
- return true;
67
- }
68
- // Check if value is in falsy set
69
- if (normalizedFalsy.includes(normalized)) {
70
- return false;
71
- }
72
- // Value is not recognized
73
- const allValidValues = [...normalizedTruthy, ...normalizedFalsy];
74
- throw new Error(getMessages().stringBoolExpected(this.options.caseSensitive ? allValidValues.join(', ') : allValidValues.join(', '), value));
75
- }
76
- /**
77
- * Safely parse and validate a string boolean value
78
- */
79
- safeParse(value) {
80
- try {
81
- const result = this.parse(value);
82
- return { success: true, data: result };
83
- }
84
- catch (error) {
85
- return {
86
- success: false,
87
- error: error
88
- };
89
- }
90
- }
91
- /**
92
- * Create a new validator with custom truthy values
93
- */
94
- withTruthy(values) {
95
- return new VldStringBool({
96
- ...this.options,
97
- truthy: values
98
- });
99
- }
100
- /**
101
- * Create a new validator with custom falsy values
102
- */
103
- withFalsy(values) {
104
- return new VldStringBool({
105
- ...this.options,
106
- falsy: values
107
- });
108
- }
109
- /**
110
- * Create a new validator with case-sensitive matching
111
- */
112
- caseSensitive() {
113
- return new VldStringBool({
114
- ...this.options,
115
- caseSensitive: true
116
- });
117
- }
118
- /**
119
- * Create a new validator with case-insensitive matching (default)
120
- */
121
- caseInsensitive() {
122
- return new VldStringBool({
123
- ...this.options,
124
- caseSensitive: false
125
- });
126
- }
127
- }
128
-
129
- /**
130
- * Immutable array validator with chainable methods
131
- */
132
- class VldArray extends VldBase {
133
- /**
134
- * Private constructor to enforce immutability
135
- */
136
- constructor(config) {
137
- super();
138
- this.config = config;
139
- }
140
- /**
141
- * Create a new array validator
142
- */
143
- static create(itemValidator) {
144
- return new VldArray({ itemValidator });
145
- }
146
- /**
147
- * Parse and validate an array value
148
- */
149
- parse(value) {
150
- if (!Array.isArray(value)) {
151
- throw new Error(this.config.errorMessage || getMessages().invalidArray);
152
- }
153
- // Validate length constraints
154
- if (this.config.exactLength !== undefined && value.length !== this.config.exactLength) {
155
- throw new Error(this.config.errorMessage || getMessages().arrayLength(this.config.exactLength));
156
- }
157
- if (this.config.minLength !== undefined && value.length < this.config.minLength) {
158
- throw new Error(this.config.errorMessage || getMessages().arrayMin(this.config.minLength));
159
- }
160
- if (this.config.maxLength !== undefined && value.length > this.config.maxLength) {
161
- throw new Error(this.config.errorMessage || getMessages().arrayMax(this.config.maxLength));
162
- }
163
- // Validate each item with optimized loop and safeParse
164
- const result = [];
165
- const length = value.length;
166
- for (let i = 0; i < length; i++) {
167
- const parseResult = this.config.itemValidator.safeParse(value[i]);
168
- if (!parseResult.success) {
169
- throw new Error(getMessages().arrayItem(i, parseResult.error.message));
170
- }
171
- result[i] = parseResult.data; // Direct assignment is faster than push
172
- }
173
- // Check uniqueness if required - optimized with Map-based approach
174
- if (this.config.unique) {
175
- this.checkUnique(result);
176
- }
177
- return result;
178
- }
179
- /**
180
- * Safely parse and validate an array value
181
- */
182
- safeParse(value) {
183
- try {
184
- return { success: true, data: this.parse(value) };
185
- }
186
- catch (error) {
187
- return { success: false, error: error };
188
- }
189
- }
190
- /**
191
- * Optimized uniqueness check using Map-based approach
192
- * Avoids repeated stableStringify calls by caching serialized values
193
- */
194
- checkUnique(items) {
195
- const seen = new Set(); // Set of seen keys
196
- const objectKeys = new WeakMap(); // Cache for object->string mappings
197
- for (const item of items) {
198
- let key;
199
- if (typeof item === 'object' && item !== null) {
200
- // Check if we've already serialized this object reference
201
- const cached = objectKeys.get(item);
202
- if (cached !== undefined) {
203
- key = cached;
204
- }
205
- else {
206
- // Serialize and cache
207
- const serialized = this.stableStringify(item);
208
- key = serialized;
209
- objectKeys.set(item, serialized);
210
- }
211
- }
212
- else {
213
- // Primitives can be used directly as keys
214
- key = item;
215
- }
216
- if (seen.has(key)) {
217
- throw new Error('Array must contain unique items');
218
- }
219
- seen.add(key);
220
- }
221
- }
222
- /**
223
- * Create a stable string representation of an object for hashing
224
- * Handles circular references and deep nesting gracefully
225
- * BUG-006 FIX: Added depth limit to prevent stack overflow
226
- * BUG-NEW-003 FIX: Fixed depth tracking to properly track recursion depth
227
- */
228
- stableStringify(obj) {
229
- const seen = new WeakSet();
230
- const MAX_DEPTH = 100; // Reasonable depth limit to prevent stack overflow
231
- // Helper function to sort keys and create stable representation
232
- const sortedStringify = (value, depth = 0) => {
233
- // Check depth limit
234
- if (depth > MAX_DEPTH) {
235
- return '"[Max Depth Exceeded]"';
236
- }
237
- // Handle primitives
238
- if (value === null)
239
- return 'null';
240
- if (value === undefined)
241
- return 'undefined';
242
- if (typeof value !== 'object')
243
- return JSON.stringify(value);
244
- // Handle circular references
245
- if (seen.has(value)) {
246
- return '"[Circular]"';
247
- }
248
- seen.add(value);
249
- try {
250
- // Handle arrays
251
- if (Array.isArray(value)) {
252
- const items = value.map(item => sortedStringify(item, depth + 1));
253
- return `[${items.join(',')}]`;
254
- }
255
- // Handle objects - sort keys for stability
256
- const keys = Object.keys(value).sort();
257
- const pairs = keys.map(key => {
258
- const serializedKey = JSON.stringify(key);
259
- const serializedValue = sortedStringify(value[key], depth + 1);
260
- return `${serializedKey}:${serializedValue}`;
261
- });
262
- return `{${pairs.join(',')}}`;
263
- }
264
- finally {
265
- // Clean up seen set for this branch
266
- seen.delete(value);
267
- }
268
- };
269
- try {
270
- return sortedStringify(obj);
271
- }
272
- catch (error) {
273
- // Fallback to safe representation if stringify fails
274
- return String(obj);
275
- }
276
- }
277
- /**
278
- * Create a new validator with minimum length constraint
279
- */
280
- min(length, message) {
281
- return new VldArray({
282
- ...this.config,
283
- minLength: length,
284
- errorMessage: message || getMessages().arrayMin(length)
285
- });
286
- }
287
- /**
288
- * Create a new validator with maximum length constraint
289
- */
290
- max(length, message) {
291
- return new VldArray({
292
- ...this.config,
293
- maxLength: length,
294
- errorMessage: message || getMessages().arrayMax(length)
295
- });
296
- }
297
- /**
298
- * Create a new validator with exact length constraint
299
- */
300
- length(length, message) {
301
- return new VldArray({
302
- ...this.config,
303
- exactLength: length,
304
- minLength: undefined,
305
- maxLength: undefined,
306
- errorMessage: message || getMessages().arrayLength(length)
307
- });
308
- }
309
- /**
310
- * Create a new validator that ensures array is not empty
311
- */
312
- nonempty(message) {
313
- return new VldArray({
314
- ...this.config,
315
- minLength: 1,
316
- errorMessage: message || getMessages().arrayEmpty
317
- });
318
- }
319
- /**
320
- * Create a new validator that ensures array contains unique items
321
- */
322
- unique(message) {
323
- return new VldArray({
324
- ...this.config,
325
- unique: true,
326
- errorMessage: message || 'Array must contain unique items'
327
- });
328
- }
329
- /**
330
- * Create a new validator with a range constraint for length
331
- */
332
- between(min, max, message) {
333
- return new VldArray({
334
- ...this.config,
335
- minLength: min,
336
- maxLength: max,
337
- errorMessage: message || `Array length must be between ${min} and ${max}`
338
- });
339
- }
340
- }
341
-
342
- /**
343
- * Immutable enum validator for string enum values
344
- */
345
- class VldEnum extends VldBase {
346
- /**
347
- * Private constructor to enforce immutability
348
- */
349
- constructor(_values, errorMessage) {
350
- super();
351
- this._values = _values;
352
- this.errorMessage = errorMessage;
353
- }
354
- /**
355
- * Get the enum values
356
- */
357
- get values() {
358
- return this._values;
359
- }
360
- /**
361
- * Create a new enum validator
362
- */
363
- static create(values) {
364
- return new VldEnum(values);
365
- }
366
- /**
367
- * Parse and validate an enum value
368
- */
369
- parse(value) {
370
- // BUG-002 FIX: Add type check before includes() to prevent type confusion
371
- if (typeof value !== 'string') {
372
- throw new Error(this.errorMessage ||
373
- getMessages().enumExpected([...this._values], JSON.stringify(value)));
374
- }
375
- if (!this._values.includes(value)) {
376
- throw new Error(this.errorMessage ||
377
- getMessages().enumExpected([...this._values], JSON.stringify(value)));
378
- }
379
- return value;
380
- }
381
- /**
382
- * Safely parse and validate an enum value
383
- */
384
- safeParse(value) {
385
- // BUG-002 FIX: Add type check before includes() to prevent type confusion
386
- if (typeof value !== 'string') {
387
- return {
388
- success: false,
389
- error: new Error(this.errorMessage ||
390
- getMessages().enumExpected([...this._values], JSON.stringify(value)))
391
- };
392
- }
393
- if (this._values.includes(value)) {
394
- return { success: true, data: value };
395
- }
396
- return {
397
- success: false,
398
- error: new Error(this.errorMessage ||
399
- getMessages().enumExpected([...this._values], JSON.stringify(value)))
400
- };
401
- }
402
- /**
403
- * Exclude specific values from the enum
404
- * Creates a new enum validator without the specified values
405
- */
406
- exclude(...excludeValues) {
407
- const filtered = this._values.filter(v => !excludeValues.includes(v));
408
- if (filtered.length === 0) {
409
- throw new Error('Cannot exclude all enum values');
410
- }
411
- // Type assertion needed because TypeScript can't guarantee the filtered array maintains the required type
412
- return new VldEnum(filtered, this.errorMessage);
413
- }
414
- /**
415
- * Extract specific values from the enum
416
- * Creates a new enum validator with only the specified values
417
- */
418
- extract(...extractValues) {
419
- const extracted = this._values.filter(v => extractValues.includes(v));
420
- if (extracted.length === 0) {
421
- throw new Error('Cannot extract non-existent enum values');
422
- }
423
- // Type assertion needed because TypeScript can't guarantee the extracted array has the required type
424
- return new VldEnum(extracted, this.errorMessage);
425
- }
426
- }
427
-
428
- /**
429
- * Optimized immutable object validator with chainable methods
430
- * Features pre-computed keys and Set-based lookups for better performance
431
- */
432
- class VldObject extends VldBase {
433
- /**
434
- * Private constructor to enforce immutability
435
- */
436
- constructor(config) {
437
- super();
438
- this._config = config;
439
- // Pre-compute shape keys for faster access
440
- this._shapeKeys = Object.keys(config.shape);
441
- this._shapeKeysSet = new Set(this._shapeKeys);
442
- }
443
- /**
444
- * Get the validator configuration
445
- * @internal Used by discriminated union validator
446
- */
447
- get config() {
448
- return this._config;
449
- }
450
- /**
451
- * Get the shape keys array
452
- */
453
- get shapeKeys() {
454
- return this._shapeKeys;
455
- }
456
- /**
457
- * Get the shape keys set for O(1) lookups
458
- * @internal Used by discriminated union validator
459
- */
460
- get shapeKeysSet() {
461
- return this._shapeKeysSet;
462
- }
463
- /**
464
- * Create a new object validator
465
- */
466
- static create(shape) {
467
- return new VldObject({ shape });
468
- }
469
- /**
470
- * Parse and validate an object value
471
- * Ultra-optimized with inline type checks and minimal overhead
472
- */
473
- parse(value) {
474
- // Fast type check
475
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
476
- throw new Error(this._config.errorMessage || getMessages().invalidObject);
477
- }
478
- const obj = value;
479
- const result = {};
480
- // Ultra-optimized field validation with inline fast paths
481
- for (let i = 0; i < this._shapeKeys.length; i++) {
482
- const key = this._shapeKeys[i];
483
- const validator = this._config.shape[key];
484
- const fieldValue = obj[key];
485
- // BUG-NEW-002 FIX: Use instanceof instead of constructor.name
486
- // constructor.name breaks in minified builds where class names become 'a', 'b', etc.
487
- // instanceof checks are reliable regardless of minification
488
- //
489
- // Note: Coercion validators extend their base validators, so we need to check for
490
- // coercion types first (more specific) before checking base types
491
- // Check for coercion validators first - they need full safeParse for type conversion
492
- if (validator instanceof VldCoerceString ||
493
- validator instanceof VldCoerceNumber ||
494
- validator instanceof VldCoerceBoolean ||
495
- validator instanceof VldCoerceDate) {
496
- // Coercion validators need safeParse to handle type conversion
497
- const parseResult = validator.safeParse(fieldValue);
498
- if (!parseResult.success) {
499
- throw new Error(getMessages().objectField(key, parseResult.error.message));
500
- }
501
- result[key] = parseResult.data;
502
- }
503
- else if (validator instanceof VldString) {
504
- // For string with validations, use safeParse to handle email, regex etc.
505
- const parseResult = validator.safeParse(fieldValue);
506
- if (!parseResult.success) {
507
- throw new Error(getMessages().objectField(key, parseResult.error.message));
508
- }
509
- result[key] = parseResult.data;
510
- }
511
- else if (validator instanceof VldNumber) {
512
- if (typeof fieldValue !== 'number' || isNaN(fieldValue)) {
513
- throw new Error(getMessages().objectField(key, getMessages().invalidNumber));
514
- }
515
- result[key] = fieldValue;
516
- }
517
- else if (validator instanceof VldBoolean) {
518
- if (typeof fieldValue !== 'boolean') {
519
- throw new Error(getMessages().objectField(key, getMessages().invalidBoolean));
520
- }
521
- result[key] = fieldValue;
522
- }
523
- else if (validator instanceof VldDate) {
524
- // Use the actual validator for Date parsing (handles string conversion)
525
- const parseResult = validator.safeParse(fieldValue);
526
- if (!parseResult.success) {
527
- throw new Error(getMessages().objectField(key, parseResult.error.message));
528
- }
529
- result[key] = parseResult.data;
530
- }
531
- else {
532
- // Fallback to safeParse for complex validators
533
- const parseResult = validator.safeParse(fieldValue);
534
- if (!parseResult.success) {
535
- throw new Error(getMessages().objectField(key, parseResult.error.message));
536
- }
537
- result[key] = parseResult.data;
538
- }
539
- }
540
- // Handle strict/passthrough/catchall modes - optimized single Object.keys() call
541
- if (this._config.strict || this._config.passthrough || this._config.catchall) {
542
- const objKeys = Object.keys(obj);
543
- // Handle strict mode - optimized with Set
544
- if (this._config.strict) {
545
- const extraKeys = [];
546
- for (let i = 0; i < objKeys.length; i++) {
547
- if (!this._shapeKeysSet.has(objKeys[i])) {
548
- extraKeys.push(objKeys[i]);
549
- }
550
- }
551
- if (extraKeys.length > 0) {
552
- throw new Error(getMessages().unexpectedKeys(extraKeys));
553
- }
554
- }
555
- // Handle passthrough mode - optimized with comprehensive prototype pollution protection
556
- if (this._config.passthrough) {
557
- for (let i = 0; i < objKeys.length; i++) {
558
- const key = objKeys[i];
559
- // Skip dangerous keys to prevent prototype pollution
560
- if (!this._shapeKeysSet.has(key) && !this.isDangerousKey(key)) {
561
- result[key] = obj[key];
562
- }
563
- }
564
- }
565
- // Handle catchall - validate extra keys with catchall validator
566
- if (this._config.catchall) {
567
- for (let i = 0; i < objKeys.length; i++) {
568
- const key = objKeys[i];
569
- // Skip keys already in shape and dangerous keys
570
- if (!this._shapeKeysSet.has(key) && !this.isDangerousKey(key)) {
571
- result[key] = this._config.catchall.parse(obj[key]);
572
- }
573
- }
574
- }
575
- }
576
- return result;
577
- }
578
- /**
579
- * Safely parse and validate an object value
580
- * Optimized version using pre-computed keys
581
- */
582
- safeParse(value) {
583
- // Fast type check
584
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
585
- return {
586
- success: false,
587
- error: new Error(this._config.errorMessage || getMessages().invalidObject)
588
- };
589
- }
590
- const obj = value;
591
- const result = {};
592
- // Validate all fields
593
- for (let i = 0; i < this._shapeKeys.length; i++) {
594
- const key = this._shapeKeys[i];
595
- const validator = this._config.shape[key];
596
- const fieldValue = obj[key];
597
- const parseResult = validator.safeParse(fieldValue);
598
- if (parseResult.success) {
599
- result[key] = parseResult.data;
600
- }
601
- else {
602
- return {
603
- success: false,
604
- error: new Error(getMessages().objectField(key, parseResult.error.message))
605
- };
606
- }
607
- }
608
- // Handle strict/passthrough/catchall modes - optimized single Object.keys() call
609
- if (this._config.strict || this._config.passthrough || this._config.catchall) {
610
- const objKeys = Object.keys(obj);
611
- // Handle strict mode
612
- if (this._config.strict) {
613
- const extraKeys = [];
614
- for (let i = 0; i < objKeys.length; i++) {
615
- if (!this._shapeKeysSet.has(objKeys[i])) {
616
- extraKeys.push(objKeys[i]);
617
- }
618
- }
619
- if (extraKeys.length > 0) {
620
- return {
621
- success: false,
622
- error: new Error(getMessages().unexpectedKeys(extraKeys))
623
- };
624
- }
625
- }
626
- // Handle passthrough mode with comprehensive prototype pollution protection
627
- if (this._config.passthrough) {
628
- for (let i = 0; i < objKeys.length; i++) {
629
- const key = objKeys[i];
630
- // Skip dangerous keys to prevent prototype pollution
631
- if (!this._shapeKeysSet.has(key) && !this.isDangerousKey(key)) {
632
- result[key] = obj[key];
633
- }
634
- }
635
- }
636
- // Handle catchall - validate extra keys with catchall validator
637
- if (this._config.catchall) {
638
- for (let i = 0; i < objKeys.length; i++) {
639
- const key = objKeys[i];
640
- // Skip keys already in shape and dangerous keys
641
- if (!this._shapeKeysSet.has(key) && !this.isDangerousKey(key)) {
642
- const catchallResult = this._config.catchall.safeParse(obj[key]);
643
- if (!catchallResult.success) {
644
- return {
645
- success: false,
646
- error: new Error(getMessages().objectField(key, catchallResult.error.message))
647
- };
648
- }
649
- result[key] = catchallResult.data;
650
- }
651
- }
652
- }
653
- }
654
- return { success: true, data: result };
655
- }
656
- /**
657
- * Comprehensive prototype pollution protection
658
- * Checks for dangerous keys that could modify Object.prototype
659
- */
660
- isDangerousKey(key) {
661
- // Direct dangerous keys
662
- const directDangerousKeys = ['__proto__', 'constructor', 'prototype'];
663
- if (directDangerousKeys.includes(key)) {
664
- return true;
665
- }
666
- // Nested prototype manipulation vectors
667
- // These patterns could allow prototype pollution through nested access
668
- const nestedPatterns = [
669
- 'constructor.prototype',
670
- '__proto__.toString',
671
- 'prototype.constructor',
672
- '__defineGetter__',
673
- '__defineSetter__',
674
- '__lookupGetter__',
675
- '__lookupSetter__'
676
- ];
677
- // Check for nested patterns
678
- for (const pattern of nestedPatterns) {
679
- if (key.includes(pattern)) {
680
- return true;
681
- }
682
- }
683
- // Check for property access chains that could lead to prototype pollution
684
- // This covers patterns like "x.constructor.prototype.polluted"
685
- const dangerousChains = [
686
- 'constructor.',
687
- '__proto__.',
688
- 'prototype.'
689
- ];
690
- for (const chain of dangerousChains) {
691
- if (key.includes(chain)) {
692
- return true;
693
- }
694
- }
695
- // Additional protection: reject keys that could be used for property shadowing
696
- const shadowingPatterns = [
697
- 'hasOwnProperty',
698
- 'toString',
699
- 'valueOf',
700
- 'isPrototypeOf',
701
- 'propertyIsEnumerable'
702
- ];
703
- for (const pattern of shadowingPatterns) {
704
- if (key === pattern || key.includes(`.${pattern}`)) {
705
- return true;
706
- }
707
- }
708
- return false;
709
- }
710
- /**
711
- * Create a new validator in strict mode (no extra keys allowed)
712
- */
713
- strict(message) {
714
- return new VldObject({
715
- ...this._config,
716
- strict: true,
717
- passthrough: false,
718
- errorMessage: message
719
- });
720
- }
721
- /**
722
- * Create a new validator in passthrough mode (extra keys are preserved)
723
- */
724
- passthrough() {
725
- return new VldObject({
726
- ...this._config,
727
- strict: false,
728
- passthrough: true
729
- });
730
- }
731
- /**
732
- * Create a new validator with all fields optional
733
- */
734
- partial() {
735
- const partialShape = {};
736
- for (const key in this._config.shape) {
737
- partialShape[key] = new VldOptional(this._config.shape[key]);
738
- }
739
- return new VldObject({
740
- ...this._config,
741
- shape: partialShape
742
- });
743
- }
744
- /**
745
- * Create a new validator with deep partial (nested objects also partial)
746
- */
747
- deepPartial() {
748
- const deepPartialShape = {};
749
- for (const key in this._config.shape) {
750
- const validator = this._config.shape[key];
751
- if (validator instanceof VldObject) {
752
- deepPartialShape[key] = new VldOptional(validator.deepPartial());
753
- }
754
- else {
755
- deepPartialShape[key] = new VldOptional(validator);
756
- }
757
- }
758
- return new VldObject({
759
- ...this._config,
760
- shape: deepPartialShape
761
- });
762
- }
763
- /**
764
- * Create a new validator with only specified keys
765
- */
766
- pick(...keys) {
767
- const pickedShape = {};
768
- for (const key of keys) {
769
- if (key in this._config.shape) {
770
- pickedShape[key] = this._config.shape[key];
771
- }
772
- }
773
- return new VldObject({
774
- ...this._config,
775
- shape: pickedShape
776
- });
777
- }
778
- /**
779
- * Create a new validator without specified keys
780
- */
781
- omit(...keys) {
782
- const omittedShape = {};
783
- const keysToOmit = new Set(keys);
784
- for (const key in this._config.shape) {
785
- if (!keysToOmit.has(key)) {
786
- omittedShape[key] = this._config.shape[key];
787
- }
788
- }
789
- return new VldObject({
790
- ...this._config,
791
- shape: omittedShape
792
- });
793
- }
794
- /**
795
- * Create a new validator with additional fields
796
- */
797
- extend(extension) {
798
- return new VldObject({
799
- ...this._config,
800
- shape: { ...this._config.shape, ...extension }
801
- });
802
- }
803
- /**
804
- * Create a new validator by merging with another object validator
805
- */
806
- merge(other) {
807
- return new VldObject({
808
- ...this._config,
809
- shape: { ...this._config.shape, ...other.config.shape }
810
- });
811
- }
812
- /**
813
- * Create a new validator with all fields required (removes optional)
814
- */
815
- required() {
816
- const requiredShape = {};
817
- for (const key in this._config.shape) {
818
- const validator = this._config.shape[key];
819
- // If it's optional, unwrap it
820
- if (validator instanceof VldOptional) {
821
- // BUG-001 FIX: Add defensive check for baseValidator property
822
- const unwrapped = validator.baseValidator;
823
- if (!unwrapped || typeof unwrapped.parse !== 'function') {
824
- throw new Error(`Invalid VldOptional structure for field "${key}": missing or invalid baseValidator`);
825
- }
826
- requiredShape[key] = unwrapped;
827
- }
828
- else {
829
- requiredShape[key] = validator;
830
- }
831
- }
832
- return new VldObject({
833
- ...this._config,
834
- shape: requiredShape
835
- });
836
- }
837
- /**
838
- * Create a new validator with a catchall validator for extra keys
839
- * Zod 4 API parity - validates unknown keys with provided schema
840
- */
841
- catchall(schema) {
842
- return new VldObject({
843
- ...this._config,
844
- catchall: schema,
845
- passthrough: false // catchall overrides passthrough
846
- });
847
- }
848
- /**
849
- * Access the inner shape schemas
850
- * Zod 4 API parity - returns the shape object
851
- */
852
- get shape() {
853
- return this._config.shape;
854
- }
855
- /**
856
- * Create an enum validator from object keys
857
- * Zod 4 API parity - creates literal union of keys
858
- */
859
- keyof() {
860
- const keys = Object.keys(this._config.shape);
861
- if (keys.length === 0) {
862
- throw new Error('Cannot create keyof enum from empty object');
863
- }
864
- return VldEnum.create(keys);
865
- }
866
- /**
867
- * Type-safe extend that throws an error if any key already exists
868
- * Zod 4 API parity - prevents accidental field override
869
- * @param extension The extension shape to add
870
- * @returns A new validator with extended shape
871
- * @throws {Error} If any extension key already exists in the shape
872
- * @example
873
- * const base = v.object({ name: v.string() });
874
- * const extended = base.safeExtend({ age: v.number() }); // OK
875
- * const invalid = base.safeExtend({ name: v.number() }); // Throws error
876
- */
877
- safeExtend(extension) {
878
- // Check for overlapping keys
879
- const existingKeys = new Set(Object.keys(this._config.shape));
880
- const extensionKeys = Object.keys(extension);
881
- const overlappingKeys = [];
882
- for (const key of extensionKeys) {
883
- if (existingKeys.has(key)) {
884
- overlappingKeys.push(key);
885
- }
886
- }
887
- if (overlappingKeys.length > 0) {
888
- throw new Error(`safeExtend: ${getMessages().safeExtendOverlap(overlappingKeys)}`);
889
- }
890
- return new VldObject({
891
- ...this._config,
892
- shape: { ...this._config.shape, ...extension }
893
- });
894
- }
895
- }
896
-
897
- /**
898
- * Optimized immutable union validator for multiple type options
899
- * Features type-checking shortcuts for 110x performance improvement
900
- */
901
- class VldUnion extends VldBase {
902
- /**
903
- * Private constructor to enforce immutability
904
- */
905
- constructor(validators, errorMessage) {
906
- super();
907
- this.validators = validators;
908
- this.errorMessage = errorMessage;
909
- this.typeCheckers = new Map();
910
- // Pre-compile type checkers for common types
911
- for (const validator of validators) {
912
- this.typeCheckers.set(validator, this.createTypeChecker(validator));
913
- }
914
- }
915
- /**
916
- * Create type checker based on validator type for fast path optimization
917
- * Uses a safer approach that's less prone to spoofing
918
- */
919
- createTypeChecker(validator) {
920
- // More conservative approach that prioritizes security and stability
921
- // Only use fast path checks for very common, unambiguous types
922
- try {
923
- // Test basic types with safe parsing to validate the validator
924
- const stringTest = validator.safeParse('test');
925
- if (stringTest.success) {
926
- return (v) => typeof v === 'string';
927
- }
928
- const numberTest = validator.safeParse(123);
929
- if (numberTest.success) {
930
- return (v) => typeof v === 'number' && !isNaN(v);
931
- }
932
- const booleanTest = validator.safeParse(true);
933
- if (booleanTest.success) {
934
- return (v) => typeof v === 'boolean';
935
- }
936
- const arrayTest = validator.safeParse([]);
937
- if (arrayTest.success) {
938
- return (v) => Array.isArray(v);
939
- }
940
- const objectTest = validator.safeParse({});
941
- if (objectTest.success) {
942
- return (v) => typeof v === 'object' && v !== null && !Array.isArray(v);
943
- }
944
- const nullTest = validator.safeParse(null);
945
- if (nullTest.success) {
946
- return (v) => v === null;
947
- }
948
- const undefinedTest = validator.safeParse(undefined);
949
- if (undefinedTest.success) {
950
- return (v) => v === undefined;
951
- }
952
- }
953
- catch {
954
- // If safe testing fails, fall back to safe validation
955
- }
956
- // Fallback: no quick check available - use safe validation
957
- return () => true;
958
- }
959
- /**
960
- * Create a new union validator
961
- */
962
- static create(...validators) {
963
- return new VldUnion(validators);
964
- }
965
- /**
966
- * Parse and validate a value against union options
967
- * Optimized with type checking and safeParse to avoid try-catch overhead
968
- * BUG-NEW-013 FIX: Single-pass error collection to avoid double parsing
969
- */
970
- parse(value) {
971
- // Single pass: collect errors during validation
972
- const errors = [];
973
- for (const validator of this.validators) {
974
- const typeChecker = this.typeCheckers.get(validator);
975
- // Skip validators that definitely won't match based on type
976
- if (typeChecker && !typeChecker(value)) {
977
- continue;
978
- }
979
- // Use safeParse to avoid try-catch overhead
980
- const result = validator.safeParse(value);
981
- if (result.success) {
982
- return result.data;
983
- }
984
- // Collect error for final message if all validators fail
985
- errors.push(result.error.message);
986
- }
987
- // All validators failed - throw with collected errors
988
- throw new Error(this.errorMessage ||
989
- getMessages().unionNoMatch(errors));
990
- }
991
- /**
992
- * Safely parse and validate a value against union options
993
- * Optimized version using type checking shortcuts
994
- * BUG-NEW-013 FIX: Single-pass error collection to avoid double parsing
995
- */
996
- safeParse(value) {
997
- // Single pass: collect errors during validation
998
- const errors = [];
999
- for (const validator of this.validators) {
1000
- const typeChecker = this.typeCheckers.get(validator);
1001
- // Skip validators that definitely won't match based on type
1002
- if (typeChecker && !typeChecker(value)) {
1003
- continue;
1004
- }
1005
- const result = validator.safeParse(value);
1006
- if (result.success) {
1007
- return result;
1008
- }
1009
- // Collect error for final message if all validators fail
1010
- errors.push(result.error.message);
1011
- }
1012
- // All validators failed - return error with collected messages
1013
- return {
1014
- success: false,
1015
- error: new Error(this.errorMessage ||
1016
- getMessages().unionNoMatch(errors))
1017
- };
1018
- }
1019
- }
1020
-
1021
- /**
1022
- * Immutable literal validator for exact value matching
1023
- */
1024
- class VldLiteral extends VldBase {
1025
- /**
1026
- * Private constructor to enforce immutability
1027
- */
1028
- constructor(_literal, errorMessage) {
1029
- super();
1030
- this._literal = _literal;
1031
- this.errorMessage = errorMessage;
1032
- }
1033
- /**
1034
- * Get the literal value
1035
- */
1036
- get literal() {
1037
- return this._literal;
1038
- }
1039
- /**
1040
- * Create a new literal validator
1041
- */
1042
- static create(literal) {
1043
- return new VldLiteral(literal);
1044
- }
1045
- /**
1046
- * Parse and validate a literal value
1047
- */
1048
- parse(value) {
1049
- if (value !== this._literal) {
1050
- throw new Error(this.errorMessage ||
1051
- getMessages().literalExpected(JSON.stringify(this._literal), JSON.stringify(value)));
1052
- }
1053
- return this._literal;
1054
- }
1055
- /**
1056
- * Safely parse and validate a literal value
1057
- */
1058
- safeParse(value) {
1059
- if (value === this._literal) {
1060
- return { success: true, data: this._literal };
1061
- }
1062
- return {
1063
- success: false,
1064
- error: new Error(this.errorMessage ||
1065
- getMessages().literalExpected(JSON.stringify(this._literal), JSON.stringify(value)))
1066
- };
1067
- }
1068
- }
1069
-
1070
- /**
1071
- * Immutable symbol validator
1072
- */
1073
- class VldSymbol extends VldBase {
1074
- /**
1075
- * Private constructor to enforce immutability
1076
- */
1077
- constructor(errorMessage) {
1078
- super();
1079
- this.errorMessage = errorMessage;
1080
- }
1081
- /**
1082
- * Create a new symbol validator
1083
- */
1084
- static create() {
1085
- return new VldSymbol();
1086
- }
1087
- /**
1088
- * Parse and validate a symbol value
1089
- */
1090
- parse(value) {
1091
- if (typeof value !== 'symbol') {
1092
- throw new Error(this.errorMessage || getMessages().invalidSymbol);
1093
- }
1094
- return value;
1095
- }
1096
- /**
1097
- * Safely parse and validate a symbol value
1098
- */
1099
- safeParse(value) {
1100
- if (typeof value === 'symbol') {
1101
- return { success: true, data: value };
1102
- }
1103
- return {
1104
- success: false,
1105
- error: new Error(this.errorMessage || getMessages().invalidSymbol)
1106
- };
1107
- }
1108
- }
1109
-
1110
- /**
1111
- * Immutable tuple validator for fixed-length arrays
1112
- */
1113
- class VldTuple extends VldBase {
1114
- /**
1115
- * Private constructor to enforce immutability
1116
- */
1117
- constructor(validators, errorMessage) {
1118
- super();
1119
- this.validators = validators;
1120
- this.errorMessage = errorMessage;
1121
- }
1122
- /**
1123
- * Create a new tuple validator
1124
- */
1125
- static create(...validators) {
1126
- return new VldTuple(validators);
1127
- }
1128
- /**
1129
- * Parse and validate a tuple value
1130
- */
1131
- parse(value) {
1132
- if (!Array.isArray(value)) {
1133
- throw new Error(this.errorMessage || getMessages().invalidTuple);
1134
- }
1135
- if (value.length !== this.validators.length) {
1136
- throw new Error(this.errorMessage ||
1137
- getMessages().tupleLength(this.validators.length, value.length));
1138
- }
1139
- const result = [];
1140
- for (let i = 0; i < this.validators.length; i++) {
1141
- try {
1142
- result[i] = this.validators[i].parse(value[i]);
1143
- }
1144
- catch (error) {
1145
- throw new Error(getMessages().arrayItem(i, error.message));
1146
- }
1147
- }
1148
- return result;
1149
- }
1150
- /**
1151
- * Safely parse and validate a tuple value
1152
- */
1153
- safeParse(value) {
1154
- try {
1155
- return { success: true, data: this.parse(value) };
1156
- }
1157
- catch (error) {
1158
- return { success: false, error: error };
1159
- }
1160
- }
1161
- }
1162
-
1163
- /**
1164
- * Security utilities for prototype pollution protection
1165
- * BUG-NEW-018 & BUG-NEW-020 FIX: Centralized comprehensive dangerous key detection
1166
- */
1167
- /**
1168
- * Comprehensive prototype pollution protection
1169
- * Checks for dangerous keys that could modify Object.prototype or built-in prototypes
1170
- * @param key The property key to check
1171
- * @returns true if the key is dangerous, false otherwise
1172
- */
1173
- function isDangerousKey(key) {
1174
- // Direct dangerous keys
1175
- const directDangerousKeys = ['__proto__', 'constructor', 'prototype'];
1176
- if (directDangerousKeys.includes(key)) {
1177
- return true;
1178
- }
1179
- // Nested prototype manipulation vectors
1180
- // These patterns could allow prototype pollution through nested access
1181
- const nestedPatterns = [
1182
- 'constructor.prototype',
1183
- '__proto__.toString',
1184
- 'prototype.constructor',
1185
- '__defineGetter__',
1186
- '__defineSetter__',
1187
- '__lookupGetter__',
1188
- '__lookupSetter__'
1189
- ];
1190
- // Check for nested patterns
1191
- for (const pattern of nestedPatterns) {
1192
- if (key.includes(pattern)) {
1193
- return true;
1194
- }
1195
- }
1196
- // Check for property access chains that could lead to prototype pollution
1197
- // This covers patterns like "x.constructor.prototype.polluted"
1198
- const dangerousChains = [
1199
- 'constructor.',
1200
- '__proto__.',
1201
- 'prototype.'
1202
- ];
1203
- for (const chain of dangerousChains) {
1204
- if (key.includes(chain)) {
1205
- return true;
1206
- }
1207
- }
1208
- // Additional protection: reject keys that could be used for property shadowing
1209
- const shadowingPatterns = [
1210
- 'hasOwnProperty',
1211
- 'toString',
1212
- 'valueOf',
1213
- 'isPrototypeOf',
1214
- 'propertyIsEnumerable'
1215
- ];
1216
- for (const pattern of shadowingPatterns) {
1217
- if (key === pattern || key.includes(`.${pattern}`)) {
1218
- return true;
1219
- }
1220
- }
1221
- return false;
1222
- }
1223
-
1224
- /**
1225
- * Immutable record validator for key-value pairs
1226
- * BUG-NEW-018 FIX: Uses comprehensive dangerous key protection
1227
- */
1228
- class VldRecord extends VldBase {
1229
- /**
1230
- * Private constructor to enforce immutability
1231
- */
1232
- constructor(valueValidator, errorMessage) {
1233
- super();
1234
- this.valueValidator = valueValidator;
1235
- this.errorMessage = errorMessage;
1236
- }
1237
- /**
1238
- * Create a new record validator
1239
- */
1240
- static create(valueValidator) {
1241
- return new VldRecord(valueValidator);
1242
- }
1243
- /**
1244
- * Parse and validate a record value
1245
- * BUG-NEW-018 FIX: Use comprehensive dangerous key protection
1246
- */
1247
- parse(value) {
1248
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
1249
- throw new Error(this.errorMessage || getMessages().invalidRecord);
1250
- }
1251
- const result = {};
1252
- const obj = value;
1253
- for (const [key, val] of Object.entries(obj)) {
1254
- // Skip dangerous keys to prevent prototype pollution
1255
- // Now using comprehensive protection from shared utility
1256
- if (isDangerousKey(key)) {
1257
- continue;
1258
- }
1259
- try {
1260
- result[key] = this.valueValidator.parse(val);
1261
- }
1262
- catch (error) {
1263
- throw new Error(getMessages().objectField(key, error.message));
1264
- }
1265
- }
1266
- return result;
1267
- }
1268
- /**
1269
- * Safely parse and validate a record value
1270
- */
1271
- safeParse(value) {
1272
- try {
1273
- return { success: true, data: this.parse(value) };
1274
- }
1275
- catch (error) {
1276
- return { success: false, error: error };
1277
- }
1278
- }
1279
- /**
1280
- * Create a partial record variant (all keys optional)
1281
- * Similar to v.object().partial() but for records
1282
- */
1283
- partial() {
1284
- const optionalValidator = this.valueValidator.optional();
1285
- return new VldRecord(optionalValidator);
1286
- }
1287
- /**
1288
- * Create a loose record variant (allows extra keys)
1289
- * Similar to v.object().passthrough() but for records
1290
- * Note: Records already allow any keys, so this mainly affects error handling
1291
- */
1292
- loose() {
1293
- // For records, "loose" means we don't throw errors for validation failures
1294
- // We return a modified version that catches validation errors
1295
- return new VldLooseRecord(this.valueValidator);
1296
- }
1297
- }
1298
- /**
1299
- * Loose record variant that allows validation failures
1300
- * Used internally by .loose() method
1301
- */
1302
- class VldLooseRecord extends VldBase {
1303
- constructor(valueValidator) {
1304
- super();
1305
- this.valueValidator = valueValidator;
1306
- }
1307
- parse(value) {
1308
- if (typeof value !== 'object' || value === null || Array.isArray(value)) {
1309
- throw new Error(getMessages().invalidRecord);
1310
- }
1311
- const result = {};
1312
- const obj = value;
1313
- for (const [key, val] of Object.entries(obj)) {
1314
- // Skip dangerous keys
1315
- if (isDangerousKey(key)) {
1316
- continue;
1317
- }
1318
- // For loose records, skip invalid values instead of throwing
1319
- const parseResult = this.valueValidator.safeParse(val);
1320
- if (parseResult.success) {
1321
- result[key] = parseResult.data;
1322
- }
1323
- }
1324
- return result;
1325
- }
1326
- safeParse(value) {
1327
- try {
1328
- return { success: true, data: this.parse(value) };
1329
- }
1330
- catch (error) {
1331
- return { success: false, error: error };
1332
- }
1333
- }
1334
- /**
1335
- * Create a partial variant (all keys optional)
1336
- */
1337
- partial() {
1338
- const optionalValidator = this.valueValidator.optional();
1339
- return new VldLooseRecord(optionalValidator);
1340
- }
1341
- /**
1342
- * Return self (already loose)
1343
- */
1344
- loose() {
1345
- return this;
1346
- }
1347
- }
1348
-
1349
- /**
1350
- * Immutable Set validator
1351
- */
1352
- class VldSet extends VldBase {
1353
- /**
1354
- * Private constructor to enforce immutability
1355
- */
1356
- constructor(itemValidator, errorMessage) {
1357
- super();
1358
- this.itemValidator = itemValidator;
1359
- this.errorMessage = errorMessage;
1360
- }
1361
- /**
1362
- * Create a new Set validator
1363
- */
1364
- static create(itemValidator) {
1365
- return new VldSet(itemValidator);
1366
- }
1367
- /**
1368
- * Parse and validate a Set value
1369
- */
1370
- parse(value) {
1371
- if (!(value instanceof Set)) {
1372
- throw new Error(this.errorMessage || getMessages().invalidSet);
1373
- }
1374
- const result = new Set();
1375
- for (const item of value) {
1376
- try {
1377
- result.add(this.itemValidator.parse(item));
1378
- }
1379
- catch (error) {
1380
- throw new Error(error.message);
1381
- }
1382
- }
1383
- return result;
1384
- }
1385
- /**
1386
- * Safely parse and validate a Set value
1387
- */
1388
- safeParse(value) {
1389
- try {
1390
- return { success: true, data: this.parse(value) };
1391
- }
1392
- catch (error) {
1393
- return { success: false, error: error };
1394
- }
1395
- }
1396
- }
1397
-
1398
- /**
1399
- * Immutable Map validator
1400
- */
1401
- class VldMap extends VldBase {
1402
- /**
1403
- * Private constructor to enforce immutability
1404
- */
1405
- constructor(keyValidator, valueValidator, errorMessage) {
1406
- super();
1407
- this.keyValidator = keyValidator;
1408
- this.valueValidator = valueValidator;
1409
- this.errorMessage = errorMessage;
1410
- }
1411
- /**
1412
- * Create a new Map validator
1413
- */
1414
- static create(keyValidator, valueValidator) {
1415
- return new VldMap(keyValidator, valueValidator);
1416
- }
1417
- /**
1418
- * Parse and validate a Map value
1419
- */
1420
- parse(value) {
1421
- if (!(value instanceof Map)) {
1422
- throw new Error(this.errorMessage || getMessages().invalidMap);
1423
- }
1424
- const result = new Map();
1425
- for (const [key, val] of value) {
1426
- try {
1427
- const validKey = this.keyValidator.parse(key);
1428
- const validValue = this.valueValidator.parse(val);
1429
- result.set(validKey, validValue);
1430
- }
1431
- catch (error) {
1432
- throw new Error(error.message);
1433
- }
1434
- }
1435
- return result;
1436
- }
1437
- /**
1438
- * Safely parse and validate a Map value
1439
- */
1440
- safeParse(value) {
1441
- try {
1442
- return { success: true, data: this.parse(value) };
1443
- }
1444
- catch (error) {
1445
- return { success: false, error: error };
1446
- }
1447
- }
1448
- }
1449
-
1450
- /**
1451
- * Type guard to check if a value is a plain object
1452
- */
1453
- function isPlainObject(obj) {
1454
- return (obj !== null &&
1455
- typeof obj === 'object' &&
1456
- obj.constructor === Object &&
1457
- Object.prototype.toString.call(obj) === '[object Object]');
1458
- }
1459
- /**
1460
- * Safely deep merge two objects without prototype pollution vulnerability
1461
- * Optimized for performance with minimal object allocations
1462
- * BUG-NEW-020 FIX: Use comprehensive dangerous key protection from shared utility
1463
- * @param target The target object
1464
- * @param source The source object to merge from
1465
- * @returns A new merged object
1466
- */
1467
- function deepMerge(target, source) {
1468
- // Create a new object to avoid mutations (only once)
1469
- const result = { ...target };
1470
- // Get source keys directly for better performance
1471
- const sourceKeys = Object.keys(source);
1472
- for (let i = 0; i < sourceKeys.length; i++) {
1473
- const key = sourceKeys[i];
1474
- // Skip dangerous keys that could lead to prototype pollution
1475
- if (isDangerousKey(key)) {
1476
- continue;
1477
- }
1478
- // Only process own properties (redundant with Object.keys but safe)
1479
- if (!Object.prototype.hasOwnProperty.call(source, key)) {
1480
- continue;
1481
- }
1482
- const sourceValue = source[key];
1483
- const targetValue = target[key];
1484
- // If both values are plain objects, merge them recursively
1485
- if (isPlainObject(sourceValue) && isPlainObject(targetValue)) {
1486
- result[key] = deepMerge(targetValue, sourceValue);
1487
- }
1488
- else {
1489
- // Otherwise, use the source value (including undefined)
1490
- result[key] = sourceValue;
1491
- }
1492
- }
1493
- return result;
1494
- }
1495
-
1496
- /**
1497
- * Immutable intersection validator for combining validators
1498
- */
1499
- class VldIntersection extends VldBase {
1500
- /**
1501
- * Private constructor to enforce immutability
1502
- */
1503
- constructor(validatorA, validatorB) {
1504
- super();
1505
- this.validatorA = validatorA;
1506
- this.validatorB = validatorB;
1507
- }
1508
- /**
1509
- * Create a new intersection validator
1510
- */
1511
- static create(validatorA, validatorB) {
1512
- return new VldIntersection(validatorA, validatorB);
1513
- }
1514
- /**
1515
- * Parse and validate a value against both validators
1516
- */
1517
- parse(value) {
1518
- try {
1519
- // Both validators must pass
1520
- const resultA = this.validatorA.parse(value);
1521
- const resultB = this.validatorB.parse(value);
1522
- // BUG-NEW-015 FIX: Check type consistency before merging
1523
- const aIsObject = isPlainObject(resultA);
1524
- const bIsObject = isPlainObject(resultB);
1525
- // Both are objects - safe to merge
1526
- if (aIsObject && bIsObject) {
1527
- return deepMerge(resultA, resultB);
1528
- }
1529
- // Neither are objects - must be identical primitives
1530
- if (!aIsObject && !bIsObject) {
1531
- if (resultA === resultB) {
1532
- return resultA;
1533
- }
1534
- throw new Error('Values must be identical for intersection of primitive types');
1535
- }
1536
- // One is object, one is primitive - invalid intersection
1537
- throw new Error('Cannot create intersection of object and primitive types. ' +
1538
- 'Both validators must produce the same type category.');
1539
- }
1540
- catch (error) {
1541
- throw new Error(getMessages().intersectionError(error.message));
1542
- }
1543
- }
1544
- /**
1545
- * Safely parse and validate a value against both validators
1546
- */
1547
- safeParse(value) {
1548
- try {
1549
- return { success: true, data: this.parse(value) };
1550
- }
1551
- catch (error) {
1552
- return { success: false, error: error };
1553
- }
1554
- }
1555
- }
1556
-
1557
- /**
1558
- * Validator that accepts any value
1559
- */
1560
- class VldAny extends VldBase {
1561
- /**
1562
- * Create a new any validator
1563
- */
1564
- static create() {
1565
- return new VldAny();
1566
- }
1567
- /**
1568
- * Parse any value (always succeeds)
1569
- */
1570
- parse(value) {
1571
- return value;
1572
- }
1573
- /**
1574
- * Safely parse any value (always succeeds)
1575
- */
1576
- safeParse(value) {
1577
- return { success: true, data: value };
1578
- }
1579
- }
1580
-
1581
- /**
1582
- * Validator that only accepts undefined
1583
- */
1584
- class VldVoid extends VldBase {
1585
- /**
1586
- * Create a new void validator
1587
- */
1588
- static create() {
1589
- return new VldVoid();
1590
- }
1591
- /**
1592
- * Parse void value (must be undefined)
1593
- */
1594
- parse(value) {
1595
- if (value !== undefined) {
1596
- throw new Error(getMessages().expectedUndefined);
1597
- }
1598
- return undefined;
1599
- }
1600
- /**
1601
- * Safely parse void value
1602
- */
1603
- safeParse(value) {
1604
- if (value === undefined) {
1605
- return { success: true, data: undefined };
1606
- }
1607
- return {
1608
- success: false,
1609
- error: new Error(getMessages().expectedUndefined)
1610
- };
1611
- }
1612
- }
1613
-
1614
- /**
1615
- * Validator that never succeeds
1616
- */
1617
- class VldNever extends VldBase {
1618
- /**
1619
- * Create a new never validator
1620
- */
1621
- static create() {
1622
- return new VldNever();
1623
- }
1624
- /**
1625
- * Parse never value (always fails)
1626
- */
1627
- parse(_value) {
1628
- throw new Error(getMessages().neverType);
1629
- }
1630
- /**
1631
- * Safely parse never value (always fails)
1632
- */
1633
- safeParse(_value) {
1634
- return {
1635
- success: false,
1636
- error: new Error(getMessages().neverType)
1637
- };
1638
- }
1639
- }
1640
-
1641
- /**
1642
- * VldNull - Validates that a value is exactly null
1643
- * Part of Zod 4 API parity implementation
1644
- */
1645
- /**
1646
- * Null validator - validates that a value is exactly null
1647
- */
1648
- class VldNull extends VldBase {
1649
- constructor() {
1650
- super();
1651
- }
1652
- static create() {
1653
- return new VldNull();
1654
- }
1655
- parse(value) {
1656
- if (value !== null) {
1657
- throw new Error(`Expected null, received ${typeof value}`);
1658
- }
1659
- return null;
1660
- }
1661
- safeParse(value) {
1662
- try {
1663
- return { success: true, data: this.parse(value) };
1664
- }
1665
- catch (error) {
1666
- return { success: false, error: error };
1667
- }
1668
- }
1669
- }
1670
-
1671
- /**
1672
- * VldUndefined - Validates that a value is exactly undefined
1673
- * Part of Zod 4 API parity implementation
1674
- */
1675
- /**
1676
- * Undefined validator - validates that a value is exactly undefined
1677
- */
1678
- class VldUndefined extends VldBase {
1679
- constructor() {
1680
- super();
1681
- }
1682
- static create() {
1683
- return new VldUndefined();
1684
- }
1685
- parse(value) {
1686
- if (value !== undefined) {
1687
- throw new Error(`Expected undefined, received ${typeof value}`);
1688
- }
1689
- return undefined;
1690
- }
1691
- safeParse(value) {
1692
- try {
1693
- return { success: true, data: this.parse(value) };
1694
- }
1695
- catch (error) {
1696
- return { success: false, error: error };
1697
- }
1698
- }
1699
- }
1700
-
1701
- /**
1702
- * VldNan - Validates that a value is NaN (Not a Number)
1703
- * Part of Zod 4 API parity implementation
1704
- */
1705
- /**
1706
- * NaN validator - validates that a value is NaN
1707
- * Note: Uses Number.isNaN() which is more strict than global isNaN()
1708
- */
1709
- class VldNan extends VldBase {
1710
- constructor() {
1711
- super();
1712
- }
1713
- static create() {
1714
- return new VldNan();
1715
- }
1716
- parse(value) {
1717
- if (typeof value !== 'number' || !Number.isNaN(value)) {
1718
- throw new Error(`Expected NaN, received ${typeof value === 'number' ? 'a valid number' : typeof value}`);
1719
- }
1720
- return value;
1721
- }
1722
- safeParse(value) {
1723
- try {
1724
- return { success: true, data: this.parse(value) };
1725
- }
1726
- catch (error) {
1727
- return { success: false, error: error };
1728
- }
1729
- }
1730
- }
1731
-
1732
- /**
1733
- * VldLazy - Lazy evaluation for recursive schemas
1734
- * Part of Zod 4 API parity implementation
1735
- * Allows schemas that reference themselves (e.g., tree structures, nested categories)
1736
- */
1737
- /**
1738
- * Lazy validator - defers schema evaluation until runtime
1739
- * Essential for recursive and self-referencing types
1740
- *
1741
- * MEMORY OPTIMIZATION: Uses WeakRef for the cached schema to allow garbage collection
1742
- * when the validator is no longer in use. This prevents memory leaks in long-running
1743
- * applications with dynamically created schemas.
1744
- */
1745
- class VldLazy extends VldBase {
1746
- constructor(_schemaGetter) {
1747
- super();
1748
- this._schemaGetter = _schemaGetter;
1749
- // Use WeakRef to allow garbage collection of the cached schema
1750
- this._cachedSchemaRef = null;
1751
- // Keep a strong reference flag to prevent GC during active use
1752
- this._strongRef = null;
1753
- }
1754
- static create(schemaGetter) {
1755
- return new VldLazy(schemaGetter);
1756
- }
1757
- /**
1758
- * Get the actual schema, caching it after first retrieval
1759
- * Uses WeakRef to allow garbage collection when validator is not in use
1760
- */
1761
- _getSchema() {
1762
- // Check if we have a strong reference first (active use)
1763
- if (this._strongRef) {
1764
- return this._strongRef;
1765
- }
1766
- // Try to get from WeakRef
1767
- if (this._cachedSchemaRef) {
1768
- const cached = this._cachedSchemaRef.deref();
1769
- if (cached) {
1770
- // Restore strong reference for active use
1771
- this._strongRef = cached;
1772
- return cached;
1773
- }
1774
- }
1775
- // Create new schema
1776
- const schema = this._schemaGetter();
1777
- this._cachedSchemaRef = new WeakRef(schema);
1778
- this._strongRef = schema;
1779
- // Clear strong reference after a tick to allow GC
1780
- // This keeps the schema alive during synchronous operations
1781
- // but allows it to be collected if the validator is discarded
1782
- Promise.resolve().then(() => {
1783
- this._strongRef = null;
1784
- });
1785
- return schema;
1786
- }
1787
- /**
1788
- * Get the inner schema (unwrap)
1789
- * Returns a strong reference that will keep the schema alive
1790
- */
1791
- unwrap() {
1792
- return this._getSchema();
1793
- }
1794
- parse(value) {
1795
- return this._getSchema().parse(value);
1796
- }
1797
- safeParse(value) {
1798
- return this._getSchema().safeParse(value);
1799
- }
1800
- }
1801
-
1802
- /**
1803
- * VldDiscriminatedUnion - Fast union validation using discriminator field
1804
- * Part of Zod 4 API parity implementation
1805
- * Provides O(1) lookup performance by using a discriminator key
1806
- */
1807
- /**
1808
- * Extract literal values from a schema
1809
- */
1810
- function extractLiteralValues(schema) {
1811
- if (schema instanceof VldLiteral) {
1812
- return [schema.literal];
1813
- }
1814
- if (schema instanceof VldEnum) {
1815
- return [...schema.values];
1816
- }
1817
- throw new Error('Discriminator must be a literal or enum schema');
1818
- }
1819
- /**
1820
- * Discriminated union validator - validates union based on discriminator key
1821
- * Much faster than regular union when you have a discriminator field
1822
- */
1823
- class VldDiscriminatedUnion extends VldBase {
1824
- constructor(_discriminator, _options) {
1825
- super();
1826
- this._discriminator = _discriminator;
1827
- this._options = _options;
1828
- // Build discriminator map for O(1) lookup
1829
- this._discriminatorMap = new Map();
1830
- for (const option of _options) {
1831
- if (!(option instanceof VldObject)) {
1832
- throw new Error('All options in a discriminated union must be objects');
1833
- }
1834
- const discriminatorSchema = option.config?.shape?.[this._discriminator];
1835
- if (!discriminatorSchema) {
1836
- throw new Error(`Missing discriminator key "${this._discriminator}" in one of the options`);
1837
- }
1838
- const values = extractLiteralValues(discriminatorSchema);
1839
- for (const value of values) {
1840
- if (this._discriminatorMap.has(value)) {
1841
- throw new Error(`Duplicate discriminator value "${String(value)}" found in discriminated union`);
1842
- }
1843
- this._discriminatorMap.set(value, option);
1844
- }
1845
- }
1846
- }
1847
- static create(discriminator, options) {
1848
- return new VldDiscriminatedUnion(discriminator, options);
1849
- }
1850
- parse(value) {
1851
- const result = this.safeParse(value);
1852
- if (!result.success) {
1853
- throw result.error;
1854
- }
1855
- return result.data;
1856
- }
1857
- safeParse(value) {
1858
- // Check if input is an object
1859
- if (typeof value !== 'object' || value === null) {
1860
- return {
1861
- success: false,
1862
- error: new Error(`Expected object, received ${value === null ? 'null' : typeof value}`)
1863
- };
1864
- }
1865
- // Get discriminator value
1866
- const discriminatorValue = value[this._discriminator];
1867
- // Look up matching schema
1868
- const matchedSchema = this._discriminatorMap.get(discriminatorValue);
1869
- if (!matchedSchema) {
1870
- const validValues = Array.from(this._discriminatorMap.keys());
1871
- return {
1872
- success: false,
1873
- error: new Error(`Invalid discriminator value for "${this._discriminator}". ` +
1874
- `Expected one of: ${JSON.stringify(validValues)}, ` +
1875
- `received: ${JSON.stringify(discriminatorValue)}`)
1876
- };
1877
- }
1878
- // Validate against matched schema
1879
- return matchedSchema.safeParse(value);
1880
- }
1881
- /**
1882
- * Get the discriminator key
1883
- */
1884
- getDiscriminator() {
1885
- return this._discriminator;
1886
- }
1887
- /**
1888
- * Get all options
1889
- */
1890
- getOptions() {
1891
- return this._options;
1892
- }
1893
- }
1894
-
1895
- /**
1896
- * VldXor - Exclusive union validator
1897
- * Part of Zod 4 API parity implementation
1898
- * Ensures exactly one schema in the union matches
1899
- */
1900
- /**
1901
- * XOR validator - ensures exactly one option matches
1902
- * Unlike regular union which allows multiple matches, XOR requires exactly one
1903
- */
1904
- class VldXor extends VldBase {
1905
- constructor(_options) {
1906
- super();
1907
- this._options = _options;
1908
- }
1909
- static create(options) {
1910
- if (options.length < 2) {
1911
- throw new Error('XOR requires at least 2 options');
1912
- }
1913
- return new VldXor(options);
1914
- }
1915
- parse(value) {
1916
- const result = this.safeParse(value);
1917
- if (!result.success) {
1918
- throw result.error;
1919
- }
1920
- return result.data;
1921
- }
1922
- safeParse(value) {
1923
- let matchCount = 0;
1924
- let lastSuccess = null;
1925
- for (const option of this._options) {
1926
- const result = option.safeParse(value);
1927
- if (result.success) {
1928
- matchCount++;
1929
- lastSuccess = result;
1930
- if (matchCount > 1) {
1931
- // Early exit if more than one match
1932
- break;
1933
- }
1934
- }
1935
- }
1936
- if (matchCount === 0) {
1937
- return {
1938
- success: false,
1939
- error: new Error('No schema matched in XOR union')
1940
- };
1941
- }
1942
- if (matchCount > 1) {
1943
- return {
1944
- success: false,
1945
- error: new Error(`Input matches ${matchCount} schemas in XOR union, but exactly one is required`)
1946
- };
1947
- }
1948
- return lastSuccess;
1949
- }
1950
- /**
1951
- * Get all options
1952
- */
1953
- getOptions() {
1954
- return this._options;
1955
- }
1956
- }
1957
-
1958
- /**
1959
- * Immutable JSON validator that validates and parses JSON strings
1960
- * Accepts both strings (which are parsed) and already-parsed objects
1961
- */
1962
- class VldJson extends VldBase {
1963
- constructor(schema) {
1964
- super();
1965
- this.schema = schema;
1966
- }
1967
- /**
1968
- * Create a new JSON validator
1969
- */
1970
- static create(schema) {
1971
- return new VldJson(schema);
1972
- }
1973
- /**
1974
- * Parse and validate a JSON value
1975
- */
1976
- parse(value) {
1977
- let parsed;
1978
- // If it's a string, try to parse it as JSON first
1979
- if (typeof value === 'string') {
1980
- try {
1981
- parsed = JSON.parse(value);
1982
- }
1983
- catch (e) {
1984
- throw new Error(getMessages().invalidJson);
1985
- }
1986
- }
1987
- else {
1988
- // Not a string - assume it's already parsed
1989
- parsed = value;
1990
- }
1991
- // If we have a schema, validate against it
1992
- if (this.schema) {
1993
- return this.schema.parse(parsed);
1994
- }
1995
- // No schema - just return the parsed value
1996
- return parsed;
1997
- }
1998
- /**
1999
- * Safely parse and validate a JSON value
2000
- */
2001
- safeParse(value) {
2002
- try {
2003
- return { success: true, data: this.parse(value) };
2004
- }
2005
- catch (error) {
2006
- return {
2007
- success: false,
2008
- error: error
2009
- };
2010
- }
2011
- }
2012
- /**
2013
- * Create a new JSON validator with a schema for validation
2014
- */
2015
- withSchema(schema) {
2016
- return new VldJson(schema);
2017
- }
2018
- }
2019
-
2020
- export { VldSymbol as V, VldStringBool as a, VldArray as b, VldObject as c, VldTuple as d, VldRecord as e, VldSet as f, VldMap as g, VldUnion as h, VldIntersection as i, VldDiscriminatedUnion as j, VldXor as k, VldLiteral as l, VldEnum as m, VldAny as n, VldVoid as o, VldNever as p, VldNull as q, VldUndefined as r, VldNan as s, VldLazy as t, VldJson as u };
2021
- //# sourceMappingURL=json-o20GFhTh.js.map